Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
LIBSA(3)		    Library Functions Manual		      LIBSA(3)

NAME
       libsa --	support	library	for standalone executables

SYNOPSIS
       #include	<stand.h>

DESCRIPTION
       The libsa library provides a set	of supporting functions	for standalone
       applications, mimicking where possible the standard BSD programming en-
       vironment.   The	following sections group these functions by kind.  Un-
       less specifically described here, see the corresponding section 3  man-
       pages for the given functions.

STRING FUNCTIONS
       String	functions   are	 available  as	documented  in	string(3)  and
       bstring(3).

MEMORY ALLOCATION
       void * malloc(size_t size)

		   Allocate size bytes of memory from the heap using  a	 best-
		   fit algorithm.

       void free(void *ptr)

		   Free	the allocated object at	ptr.

       void setheap(void *start, void *limit)

		   Initialise  the  heap.  This	function must be called	before
		   calling alloc() for the first  time.	  The  region  between
		   start  and  limit  will be used for the heap; attempting to
		   allocate beyond this	will result in a panic.

       char * sbrk(int junk)

		   Provides the	behaviour of sbrk(0), i.e., returns the	 high-
		   est	point  that  the  heap has reached.  This value	can be
		   used	during testing to determine  the  actual  heap	usage.
		   The junk argument is	ignored.

ENVIRONMENT
       A  set of functions are provided	for manipulating a flat	variable space
       similar to the traditional shell-supported environment.	Major enhance-
       ments are support for set/unset hook functions.

       char * getenv(const char	*name)

       int setenv(const	char *name, const char *value, int overwrite)

       int putenv(char *string)

       int unsetenv(const char *name)

		   These functions behave similarly to their standard  library
		   counterparts.

       struct env_var *	env_getenv(const char *name)

		   Looks  up a variable	in the environment and returns its en-
		   tire	data structure.

       int  env_setenv(const  char  *name,  int	 flags,	 const	void   *value,
		   ev_sethook_t	sethook, ev_unsethook_t	unsethook)

		   Creates  a  new  or	sets  an existing environment variable
		   called name.	 If creating a new variable, the  sethook  and
		   unsethook arguments may be specified.

		   The	set hook is invoked whenever an	attempt	is made	to set
		   the variable, unless	the EV_NOHOOK flag is set.   Typically
		   a  set hook will validate the value argument, and then call
		   env_setenv()	again with EV_NOHOOK set to actually save  the
		   value.   The	 predefined function env_noset() may be	speci-
		   fied	to refuse all attempts to set a	variable.

		   The unset hook is invoked when an attempt is	made to	 unset
		   a  variable.	  If it	returns	zero, the variable will	be un-
		   set.	 The predefined	function env_nounset may  be  used  to
		   prevent a variable being unset.

STANDARD LIBRARY SUPPORT
       int abs(int i)

       int getopt(int argc, char * const *argv,	const char *optstring)

       long strtol(const char *nptr, char **endptr, int	base)

       long long strtoll(const char *nptr, char	**endptr, int base)

       long strtoul(const char *nptr, char **endptr, int base)

       long long strtoull(const	char *nptr, char **endptr, int base)

       void srandom(unsigned int seed)

       long random(void)

       char * strerror(int error)

		   Returns  error messages for the subset of errno values sup-
		   ported by libsa.

       assert(expression)

		   Requires <assert.h>.

       int setjmp(jmp_buf env)

       void longjmp(jmp_buf env, int val)

		   Defined as _setjmp()	and _longjmp() respectively  as	 there
		   is no signal	state to manipulate.  Requires <setjmp.h>.

CHARACTER I/O
       void gets(char *buf)

		   Read	 characters  from  the	console	 into buf.  All	of the
		   standard cautions apply to this function.

       void ngets(char *buf, int size)

		   Read	at most	size - 1 characters from the console into buf.
		   If size is less than	1, the function's behaviour is as  for
		   gets().

       int fgetstr(char	*buf, int size,	int fd)

		   Read	a line of at most size characters into buf.  Line ter-
		   minating  characters	are stripped, and the buffer is	always
		   NUL terminated.  Returns the	number of characters in	buf if
		   successful, or -1 if	a read error occurs.

       int printf(const	char *fmt, ...)

       void vprintf(const char *fmt, va_list ap)

       int sprintf(char	*buf, const char *fmt, ...)

       void vsprintf(char *buf,	const char *fmt, va_list ap)

		   The *printf functions implement a subset  of	 the  standard
		   printf()  family  functionality  and	 some extensions.  The
		   following	standard    conversions	    are	    supported:
		   c,d,n,o,p,s,u,x.   The  following  modifiers	are supported:
		   +,-,#,*,0,field width,precision,l.

		   The b conversion is provided	 to  decode  error  registers.
		   Its usage is:

			 printf( "reg=%b\n", regval, "<base><arg>*" );

		   where  <base>  is the output	expressed as a control charac-
		   ter,	e.g. \10 gives octal, \20 gives	hex.  Each <arg> is  a
		   sequence  of	 characters,  the first	of which gives the bit
		   number to be	inspected (origin 1) and the  next  characters
		   (up	to  a character	less than 32) give the text to be dis-
		   played if the bit is	set.  Thus

			 printf( "reg=%b\n", 3,	"\10\2BITTWO\1BITONE" );

		   would give the output

			 reg=3<BITTWO,BITONE>

		   The D conversion provides a hexdump facility, e.g.

			 printf( "%6D",	ptr, ":" ); gives "XX:XX:XX:XX:XX:XX"

			 printf( "%*D",	len, ptr, " " ); gives "XX XX XX ..."

CHARACTER TESTS	AND CONVERSIONS
       int isupper(int c)

       int islower(int c)

       int isspace(int c)

       int isdigit(int c)

       int isxdigit(int	c)

       int isascii(int c)

       int isalpha(int c)

       int isalnum(int c)

       int iscntrl(int c)

       int isgraph(int c)

       int ispunct(int c)

       int toupper(int c)

       int tolower(int c)

FILE I/O
       int open(const char *path, int flags)

		   Similar to the behaviour as specified  in  open(2),	except
		   that	 file creation is not supported, so the	mode parameter
		   is  not  required.	The  flags  argument  may  be  one  of
		   O_RDONLY, O_WRONLY and O_RDWR.  Only	UFS currently supports
		   writing.

       int close(int fd)

       void closeall(void)

		   Close all open files.

       ssize_t read(int	fd, void *buf, size_t len)

       ssize_t write(int fd, void *buf,	size_t len)

		   (No file systems currently support writing.)

       off_t lseek(int fd, off_t offset, int whence)

		   Files  being	automatically uncompressed during reading can-
		   not seek backwards from the current point.

       int stat(const char *path, struct stat *sb)

       int fstat(int fd, struct	stat *sb)

		   The stat() and fstat() functions only fill out the  follow-
		   ing	     fields	  in	   the	    sb	    structure:
		   st_mode,st_nlink,st_uid,st_gid,st_size.  The	tftp file sys-
		   tem cannot provide meaningful values	for this call, and the
		   cd9660 file system always reports files having  uid/gid  of
		   zero.

PAGER
       The  libsa library supplies a simple internal pager to ease reading the
       output of large commands.

       void pager_open()

		   Initialises the pager and tells it that the next line  out-
		   put	will be	the top	of the display.	 The environment vari-
		   able	LINES is consulted to determine	the number of lines to
		   be displayed	before pausing.

       void pager_close(void)

		   Closes the pager.

       int pager_output(const char *lines)

		   Sends the lines in the NUL-terminated buffer	 at  lines  to
		   the	pager.	Newline	characters are counted in order	to de-
		   termine the number of lines being output (wrapped lines are
		   not accounted for).	The pager_output() function  will  re-
		   turn	 zero  when  all  of  the  lines  have been output, or
		   nonzero if the display was paused and the user  elected  to
		   quit.

       int pager_file(const char *fname)

		   Attempts to open and	display	the file fname.	 Returns -1 on
		   error,  0  at  EOF,	or  1 if the user elects to quit while
		   reading.

FEATURE	SUPPORT
       A set of	functions are provided to communicate support of features from
       the loader binary to the	interpreter.  These are	used to	 do  something
       sensible	 if  we	 are still operating with a loader binary that behaves
       differently than	expected.

       void feature_enable(uint32_t mask)

		   Enable the referenced mask feature, which should be one  of
		   the FEATURE_* macros	defined	in <stand.h>.

       bool feature_name_is_enabled(const char *name)

		   Check  if the referenced name feature is enabled.  The name
		   is usually the same name as the FEATURE_* macro,  but  with
		   the FEATURE_	prefix stripped	off.  The authoritative	source
		   of  feature	names  is  the	mapping	 table near the	top in
		   stand/libsa/features.c.

       void (feature_iter_fn)(void  *cookie,  const  char  *name,  const  char
		   *desc, bool enabled)

		   The	cookie	argument  is passed as-is from the argument of
		   the same name to feature_iter().  The name and  desc	 argu-
		   ments    are	   defined    in    the	  mapping   table   in
		   stand/libsa/features.c.  The	enabled	argument indicates the
		   current status of the feature, though one  could  theoreti-
		   cally turn a	feature	off in later execution.	 As such, this
		   should  likely not be trusted if it is needed after the it-
		   eration has finished.

       void feature_iter(feature_iter_fn *iter_fn, void	*cookie)

		   Iterate over	the current set	of features.

MISC
       char * devformat(struct devdesc *)

		   Format the specified	device as a string.

       int devparse(struct devdesc **dev,  const  char	*devdesc,  const  char
		   **path)

		   Parse     the     devdesc	 string	    of	   the	  form
		   `device:[/path/to/file]'.  The devsw	table is used to match
		   the	start  of  the	`device'  string  with	dv_name.    If
		   dv_parsedev	is  non-NULL,  then it will be called to parse
		   the rest of the string and allocate the struct devdesc  for
		   this	 path.	If NULL, then a	default	routine	will be	called
		   that	will allocate a	simple struct devdesc,	parse  a  unit
		   number  and ensure there's no trailing characters.  If path
		   is non-NULL,	then a pointer to the remainder	of the devdesc
		   string after	the device specification is written.

       int devinit(void)

		   Calls all the dv_init routines in the devsw array,  return-
		   ing the number of routines that returned an error.

       void twiddle(void)

		   Successive  calls  emit  the	 characters  in	 the  sequence
		   |,/,-,\ followed by a backspace in order to	provide	 reas-
		   surance to the user.

REQUIRED LOW-LEVEL SUPPORT
       The  following  resources  are consumed by libsa	- stack, heap, console
       and devices.

       The stack must be established before libsa functions  can  be  invoked.
       Stack  requirements  vary  depending  on	the functions and file systems
       used by the consumer and	the support layer functions detailed below.

       The heap	must be	established before calling alloc() or open() by	 call-
       ing  setheap().	Heap usage will	vary depending on the number of	simul-
       taneously open files, as	well as	client	behaviour.   Automatic	decom-
       pression	will allocate more than	64K of data per	open file.

       Console	access	is performed via the getchar(),	putchar() and ischar()
       functions detailed below.

       Device access is	initiated via devopen()	and is performed  through  the
       dv_strategy(), dv_ioctl() and dv_close()	functions in the device	switch
       structure that devopen()	returns.

       The consumer must provide the following support functions:

       int getchar(void)

		   Return  a  character	 from  the  console,  used  by gets(),
		   ngets() and pager functions.

       int ischar(void)

		   Returns nonzero if a	character is waiting from the console.

       void putchar(int)

		   Write a character to	the console, used by gets(),  ngets(),
		   *printf(),  panic()	and  twiddle()	and thus by many other
		   functions for debugging and informational output.

       int devopen(struct open_file *of, const char *name, const char **file)

		   Open	the appropriate	device for the file named in name, re-
		   turning in file a pointer to	the  remaining	body  of  name
		   which  does not refer to the	device.	 The f_dev field in of
		   will	be set to point	to the devsw structure for the	opened
		   device  if successful.  Device identifiers must always pre-
		   cede	the path component, but	may otherwise  be  arbitrarily
		   formatted.	Used by	open() and thus	for all	device-related
		   I/O.

       int devclose(struct open_file *of)

		   Close the device allocated for of.  The device  driver  it-
		   self	will already have been called for the close; this call
		   should clean	up any allocation made by devopen only.

       void __abort()

		   Calls panic() with a	fixed string.

       void panic(const	char *msg, ...)

		   Signal  a fatal and unrecoverable error condition.  The msg
		   ... arguments are as	for printf().

INTERNAL FILE SYSTEMS
       Internal	file systems are enabled by the	consumer exporting  the	 array
       struct fs_ops *file_system[], which should be initialised with pointers
       to  struct  fs_ops  structures.	The following file system handlers are
       supplied	by libsa, the consumer may supply other	file systems of	 their
       own:

       ufs_fsops     The BSD UFS.

       ext2fs_fsops  Linux ext2fs file system.

       tftp_fsops    File access via TFTP.

       nfs_fsops     File access via NFS.

       cd9660_fsops  ISO 9660 (CD-ROM) file system.

       gzipfs_fsops  Stacked  file system supporting gzipped files.  When try-
		     ing the gzipfs file system, libsa appends .gz to the  end
		     of	 the filename, and then	tries to locate	the file using
		     the other file systems.  Placement	of this	file system in
		     the file_system[] array determines	whether	gzipped	 files
		     will be opened in preference to non-gzipped files.	 It is
		     only possible to seek a gzipped file forwards, and	stat()
		     and  fstat()  on  gzipped	files  will  report an invalid
		     length.

       bzipfs_fsops  The same as  gzipfs_fsops,	 but  for  bzip2(1)-compressed
		     files.

       The array of struct fs_ops pointers should be terminated	with a NULL.

DEVICES
       Devices	are exported by	the supporting code via	the array struct devsw
       *devsw[]	which is a NULL	terminated array of pointers to	device	switch
       structures.

DRIVER INTERFACE
       The  driver needs to provide a common set of entry points that are used
       by libsa	to interface with the device.

       struct devsw {
	   const char  dv_name[DEV_NAMLEN];
	   int	       dv_type;
	   int	       (*dv_init)(void);
	   int	       (*dv_strategy)(void *devdata, int rw, daddr_t blk,
			       size_t size, char *buf, size_t *rsize);
	   int	       (*dv_open)(struct open_file *f, ...);
	   int	       (*dv_close)(struct open_file *f);
	   int	       (*dv_ioctl)(struct open_file *f,	u_long cmd, void *data);
	   int	       (*dv_print)(int verbose);
	   void	       (*dv_cleanup)(void);
	   char	*      (*dv_fmtdev)(struct devdesc *);
	   int	       (*dv_parsedev)(struct devdesc **dev, const char *devpart,
		       const char **path);
	   bool	       (*dv_match)(struct devsw	*dv, const char	*devspec);
       };

       dv_name()      The device's name.

       dv_type()      Type of device.  The supported types are:

		      DEVT_NONE

		      DEVT_DISK

		      DEVT_NET

		      DEVT_CD

		      DEVT_ZFS

		      DEVT_FD
		      Each type	may have its own associated  (struct  type_de-
		      vdesc),  which  has  the generic (struct devdesc)	as its
		      first member.

       dv_init()      Driver  initialization  routine.	 This  routine	should
		      probe  for available units.  Drivers are responsible for
		      maintaining lists	of units for  later  enumeration.   No
		      other driver routines may	be called before dv_init() re-
		      turns.

       dv_open()      The driver open routine.

       dv_close()     The driver close routine.

       dv_ioctl()     The driver ioctl routine.

       dv_print()     Prints  information about	the available devices.	Infor-
		      mation should be presented with pager_output().

       dv_cleanup()   Cleans up	any memory used	by the device before the  next
		      stage is run.

       dv_fmtdev()    Converts	the  specified devdesc to the canonical	string
		      representation for that device.

       dv_parsedev()  Parses the device	portion	of a file path.	  The  devpart
		      will  point  to the `tail' of device name, possibly fol-
		      lowed by a colon and a  path  within  the	 device.   The
		      `tail'  is, by convention, the part of the device	speci-
		      fication that follows the	dv_name	part  of  the  string.
		      So  when	devparse is parsing the	string "disk3p5:/xxx",
		      devpart will point to the	`3' in that string.  The pars-
		      ing routine is expected to allocate a new	struct devdesc
		      or subclass and return it	in dev when successful.	  This
		      routine  should  set path	to point to the	portion	of the
		      string after device specification, or "/xxx" in the ear-
		      lier example.  Generally,	code needing to	parse  a  path
		      will  use	 devparse  instead of calling this routine di-
		      rectly.

       dv_match()     NULL to specify that  all	 device	 paths	starting  with
		      dv_name match.  Otherwise, this function returns 0 for a
		      match  and  a  non-zero  errno to	indicate why it	didn't
		      match.  This is helpful when you claim the  device  path
		      after  using it to query properties on systems that have
		      uniform naming for different types of devices.

HISTORY
       The libsa library contains contributions	from many sources, including:
          libsa from NetBSD
          libc	and libkern from FreeBSD 3.0.
          zalloc from Matthew Dillon <dillon@backplane.com>

       The reorganisation and port to FreeBSD 3.0, the	environment  functions
       and this	manpage	were written by	Mike Smith <msmith@FreeBSD.org>.

BUGS
       The lack	of detailed memory usage data is unhelpful.

FreeBSD	14.3		       September 9, 2022		      LIBSA(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=libsa&sektion=3&manpath=FreeBSD+14.3-RELEASE+and+Ports>

home | help