xref: /freebsd/stand/libsa/libsa.3 (revision 1d386b48)
1.\" Copyright (c) Michael Smith
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\"    notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\"    notice, this list of conditions and the following disclaimer in the
11.\"    documentation and/or other materials provided with the distribution.
12.\"
13.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23.\" SUCH DAMAGE.
24.\"
25.\" $FreeBSD$
26.\"
27.Dd September 9, 2022
28.Dt LIBSA 3
29.Os
30.Sh NAME
31.Nm libsa
32.Nd support library for standalone executables
33.Sh SYNOPSIS
34.In stand.h
35.Sh DESCRIPTION
36The
37.Nm
38library provides a set of supporting functions for standalone
39applications, mimicking where possible the standard
40.Bx
41programming
42environment.
43The following sections group these functions by kind.
44Unless specifically described here, see the corresponding section 3
45manpages for the given functions.
46.Sh STRING FUNCTIONS
47String functions are available as documented in
48.Xr string 3
49and
50.Xr bstring 3 .
51.Sh MEMORY ALLOCATION
52.Bl -hang -width 10n
53.It Xo
54.Ft "void *"
55.Fn malloc "size_t size"
56.Xc
57.Pp
58Allocate
59.Fa size
60bytes of memory from the heap using a best-fit algorithm.
61.It Xo
62.Ft void
63.Fn free "void *ptr"
64.Xc
65.Pp
66Free the allocated object at
67.Fa ptr .
68.It Xo
69.Ft void
70.Fn setheap "void *start" "void *limit"
71.Xc
72.Pp
73Initialise the heap.
74This function must be called before calling
75.Fn alloc
76for the first time.
77The region between
78.Fa start
79and
80.Fa limit
81will be used for the heap; attempting to allocate beyond this will result
82in a panic.
83.It Xo
84.Ft "char *"
85.Fn sbrk "int junk"
86.Xc
87.Pp
88Provides the behaviour of
89.Fn sbrk 0 ,
90i.e., returns the highest point that the heap has reached.
91This value can
92be used during testing to determine the actual heap usage.
93The
94.Fa junk
95argument is ignored.
96.El
97.Sh ENVIRONMENT
98A set of functions are provided for manipulating a flat variable space similar
99to the traditional shell-supported environment.
100Major enhancements are support
101for set/unset hook functions.
102.Bl -hang -width 10n
103.It Xo
104.Ft "char *"
105.Fn getenv "const char *name"
106.Xc
107.It Xo
108.Ft int
109.Fn setenv "const char *name" "const char *value" "int overwrite"
110.Xc
111.It Xo
112.Ft int
113.Fn putenv "char *string"
114.Xc
115.It Xo
116.Ft int
117.Fn unsetenv "const char *name"
118.Xc
119.Pp
120These functions behave similarly to their standard library counterparts.
121.It Xo
122.Ft "struct env_var *"
123.Fn env_getenv "const char *name"
124.Xc
125.Pp
126Looks up a variable in the environment and returns its entire
127data structure.
128.It Xo
129.Ft int
130.Fn env_setenv "const char *name" "int flags" "const void *value" "ev_sethook_t sethook" "ev_unsethook_t unsethook"
131.Xc
132.Pp
133Creates a new or sets an existing environment variable called
134.Fa name .
135If creating a new variable, the
136.Fa sethook
137and
138.Fa unsethook
139arguments may be specified.
140.Pp
141The set hook is invoked whenever an attempt
142is made to set the variable, unless the EV_NOHOOK flag is set.
143Typically
144a set hook will validate the
145.Fa value
146argument, and then call
147.Fn env_setenv
148again with EV_NOHOOK set to actually save the value.
149The predefined function
150.Fn env_noset
151may be specified to refuse all attempts to set a variable.
152.Pp
153The unset hook is invoked when an attempt is made to unset a variable.
154If it
155returns zero, the variable will be unset.
156The predefined function
157.Fa env_nounset
158may be used to prevent a variable being unset.
159.El
160.Sh STANDARD LIBRARY SUPPORT
161.Bl -hang -width 10n
162.It Xo
163.Ft int
164.Fn abs "int i"
165.Xc
166.It Xo
167.Ft int
168.Fn getopt "int argc" "char * const *argv" "const char *optstring"
169.Xc
170.It Xo
171.Ft long
172.Fn strtol "const char *nptr" "char **endptr" "int base"
173.Xc
174.It Xo
175.Ft long long
176.Fn strtoll "const char *nptr" "char **endptr" "int base"
177.Xc
178.It Xo
179.Ft long
180.Fn strtoul "const char *nptr" "char **endptr" "int base"
181.Xc
182.It Xo
183.Ft long long
184.Fn strtoull "const char *nptr" "char **endptr" "int base"
185.Xc
186.It Xo
187.Ft void
188.Fn srandom "unsigned int seed"
189.Xc
190.It Xo
191.Ft "long"
192.Fn random void
193.Xc
194.It Xo
195.Ft "char *"
196.Fn strerror "int error"
197.Xc
198.Pp
199Returns error messages for the subset of errno values supported by
200.Nm .
201.It Fn assert expression
202.Pp
203Requires
204.In assert.h .
205.It Xo
206.Ft int
207.Fn setjmp "jmp_buf env"
208.Xc
209.It Xo
210.Ft void
211.Fn longjmp "jmp_buf env" "int val"
212.Xc
213.Pp
214Defined as
215.Fn _setjmp
216and
217.Fn _longjmp
218respectively as there is no signal state to manipulate.
219Requires
220.In setjmp.h .
221.El
222.Sh CHARACTER I/O
223.Bl -hang -width 10n
224.It Xo
225.Ft void
226.Fn gets "char *buf"
227.Xc
228.Pp
229Read characters from the console into
230.Fa buf .
231All of the standard cautions apply to this function.
232.It Xo
233.Ft void
234.Fn ngets "char *buf" "int size"
235.Xc
236.Pp
237Read at most
238.Fa size
239- 1 characters from the console into
240.Fa buf .
241If
242.Fa size
243is less than 1, the function's behaviour is as for
244.Fn gets .
245.It Xo
246.Ft int
247.Fn fgetstr "char *buf" "int size" "int fd"
248.Xc
249.Pp
250Read a line of at most
251.Fa size
252characters into
253.Fa buf .
254Line terminating characters are stripped, and the buffer is always
255.Dv NUL
256terminated.
257Returns the number of characters in
258.Fa buf
259if successful, or -1 if a read error occurs.
260.It Xo
261.Ft int
262.Fn printf "const char *fmt" "..."
263.Xc
264.It Xo
265.Ft void
266.Fn vprintf "const char *fmt" "va_list ap"
267.Xc
268.It Xo
269.Ft int
270.Fn sprintf "char *buf" "const char *fmt" "..."
271.Xc
272.It Xo
273.Ft void
274.Fn vsprintf "char *buf" "const char *fmt" "va_list ap"
275.Xc
276.Pp
277The *printf functions implement a subset of the standard
278.Fn printf
279family functionality and some extensions.
280The following standard conversions
281are supported: c,d,n,o,p,s,u,x.
282The following modifiers are supported:
283+,-,#,*,0,field width,precision,l.
284.Pp
285The
286.Li b
287conversion is provided to decode error registers.
288Its usage is:
289.Bd -ragged -offset indent
290printf(
291.Qq reg=%b\en ,
292regval,
293.Qq <base><arg>*
294);
295.Ed
296.Pp
297where <base> is the output expressed as a control character, e.g.\& \e10 gives
298octal, \e20 gives hex.
299Each <arg> is a sequence of characters, the first of
300which gives the bit number to be inspected (origin 1) and the next characters
301(up to a character less than 32) give the text to be displayed if the bit is set.
302Thus
303.Bd -ragged -offset indent
304printf(
305.Qq reg=%b\en ,
3063,
307.Qq \e10\e2BITTWO\e1BITONE
308);
309.Ed
310.Pp
311would give the output
312.Bd -ragged -offset indent
313reg=3<BITTWO,BITONE>
314.Ed
315.Pp
316The
317.Li D
318conversion provides a hexdump facility, e.g.
319.Bd -ragged -offset indent
320printf(
321.Qq %6D ,
322ptr,
323.Qq \&:
324); gives
325.Qq XX:XX:XX:XX:XX:XX
326.Ed
327.Bd -ragged -offset indent
328printf(
329.Qq %*D ,
330len,
331ptr,
332.Qq "\ "
333); gives
334.Qq XX XX XX ...
335.Ed
336.El
337.Sh CHARACTER TESTS AND CONVERSIONS
338.Bl -hang -width 10n
339.It Xo
340.Ft int
341.Fn isupper "int c"
342.Xc
343.It Xo
344.Ft int
345.Fn islower "int c"
346.Xc
347.It Xo
348.Ft int
349.Fn isspace "int c"
350.Xc
351.It Xo
352.Ft int
353.Fn isdigit "int c"
354.Xc
355.It Xo
356.Ft int
357.Fn isxdigit "int c"
358.Xc
359.It Xo
360.Ft int
361.Fn isascii "int c"
362.Xc
363.It Xo
364.Ft int
365.Fn isalpha "int c"
366.Xc
367.It Xo
368.Ft int
369.Fn isalnum "int c"
370.Xc
371.It Xo
372.Ft int
373.Fn iscntrl "int c"
374.Xc
375.It Xo
376.Ft int
377.Fn isgraph "int c"
378.Xc
379.It Xo
380.Ft int
381.Fn ispunct "int c"
382.Xc
383.It Xo
384.Ft int
385.Fn toupper "int c"
386.Xc
387.It Xo
388.Ft int
389.Fn tolower "int c"
390.Xc
391.El
392.Sh FILE I/O
393.Bl -hang -width 10n
394.It Xo
395.Ft int
396.Fn open "const char *path" "int flags"
397.Xc
398.Pp
399Similar to the behaviour as specified in
400.Xr open 2 ,
401except that file creation is not supported, so the mode parameter is not
402required.
403The
404.Fa flags
405argument may be one of O_RDONLY, O_WRONLY and O_RDWR.
406Only UFS currently supports writing.
407.It Xo
408.Ft int
409.Fn close "int fd"
410.Xc
411.It Xo
412.Ft void
413.Fn closeall void
414.Xc
415.Pp
416Close all open files.
417.It Xo
418.Ft ssize_t
419.Fn read "int fd" "void *buf" "size_t len"
420.Xc
421.It Xo
422.Ft ssize_t
423.Fn write "int fd" "void *buf" "size_t len"
424.Xc
425.Pp
426(No file systems currently support writing.)
427.It Xo
428.Ft off_t
429.Fn lseek "int fd" "off_t offset" "int whence"
430.Xc
431.Pp
432Files being automatically uncompressed during reading cannot seek backwards
433from the current point.
434.It Xo
435.Ft int
436.Fn stat "const char *path" "struct stat *sb"
437.Xc
438.It Xo
439.Ft int
440.Fn fstat "int fd" "struct stat *sb"
441.Xc
442.Pp
443The
444.Fn stat
445and
446.Fn fstat
447functions only fill out the following fields in the
448.Fa sb
449structure: st_mode,st_nlink,st_uid,st_gid,st_size.
450The
451.Nm tftp
452file system cannot provide meaningful values for this call, and the
453.Nm cd9660
454file system always reports files having uid/gid of zero.
455.El
456.Sh PAGER
457The
458.Nm
459library supplies a simple internal pager to ease reading the output of large
460commands.
461.Bl -hang -width 10n
462.It Xo
463.Ft void
464.Fn pager_open
465.Xc
466.Pp
467Initialises the pager and tells it that the next line output will be the top of the
468display.
469The environment variable LINES is consulted to determine the number of
470lines to be displayed before pausing.
471.It Xo
472.Ft void
473.Fn pager_close void
474.Xc
475.Pp
476Closes the pager.
477.It Xo
478.Ft int
479.Fn pager_output "const char *lines"
480.Xc
481.Pp
482Sends the lines in the
483.Dv NUL Ns
484-terminated buffer at
485.Fa lines
486to the pager.
487Newline characters are counted in order to determine the number
488of lines being output (wrapped lines are not accounted for).
489The
490.Fn pager_output
491function will return zero when all of the lines have been output, or nonzero
492if the display was paused and the user elected to quit.
493.It Xo
494.Ft int
495.Fn pager_file "const char *fname"
496.Xc
497.Pp
498Attempts to open and display the file
499.Fa fname .
500Returns -1 on error, 0 at EOF, or 1 if the user elects to quit while reading.
501.El
502.Sh MISC
503.Bl -hang -width 10n
504.It Xo
505.Ft char *
506.Fn devformat "struct devdesc *"
507.Xc
508.Pp
509Format the specified device as a string.
510.It Xo
511.Ft int
512.Fn devparse "struct devdesc **dev" "const char *devdesc" "const char **path"
513.Xc
514.Pp
515Parse the
516.Dv devdesc
517string of the form
518.Sq device:[/path/to/file] .
519The
520.Dv devsw
521table is used to match the start of the
522.Sq device
523string with
524.Fa dv_name .
525If
526.Fa dv_parsedev
527is non-NULL, then it will be called to parse the rest of the string and allocate
528the
529.Dv struct devdesc
530for this path.
531If NULL, then a default routine will be called that will allocate a simple
532.Dv struct devdesc ,
533parse a unit number and ensure there's no trailing characters.
534If
535.Dv path
536is non-NULL, then a pointer to the remainder of the
537.Dv devdesc
538string after the device specification is written.
539.It Xo
540.Ft int
541.Fn devinit void
542Calls all the
543.Fa dv_init
544routines in the
545.Dv devsw
546array, returning the number of routines that returned an error.
547.It Xo
548.Ft void
549.Fn twiddle void
550.Xc
551.Pp
552Successive calls emit the characters in the sequence |,/,-,\\ followed by a
553backspace in order to provide reassurance to the user.
554.El
555.Sh REQUIRED LOW-LEVEL SUPPORT
556The following resources are consumed by
557.Nm
558- stack, heap, console and devices.
559.Pp
560The stack must be established before
561.Nm
562functions can be invoked.
563Stack requirements vary depending on the functions
564and file systems used by the consumer and the support layer functions detailed
565below.
566.Pp
567The heap must be established before calling
568.Fn alloc
569or
570.Fn open
571by calling
572.Fn setheap .
573Heap usage will vary depending on the number of simultaneously open files,
574as well as client behaviour.
575Automatic decompression will allocate more
576than 64K of data per open file.
577.Pp
578Console access is performed via the
579.Fn getchar ,
580.Fn putchar
581and
582.Fn ischar
583functions detailed below.
584.Pp
585Device access is initiated via
586.Fn devopen
587and is performed through the
588.Fn dv_strategy ,
589.Fn dv_ioctl
590and
591.Fn dv_close
592functions in the device switch structure that
593.Fn devopen
594returns.
595.Pp
596The consumer must provide the following support functions:
597.Bl -hang -width 10n
598.It Xo
599.Ft int
600.Fn getchar void
601.Xc
602.Pp
603Return a character from the console, used by
604.Fn gets ,
605.Fn ngets
606and pager functions.
607.It Xo
608.Ft int
609.Fn ischar void
610.Xc
611.Pp
612Returns nonzero if a character is waiting from the console.
613.It Xo
614.Ft void
615.Fn putchar int
616.Xc
617.Pp
618Write a character to the console, used by
619.Fn gets ,
620.Fn ngets ,
621.Fn *printf ,
622.Fn panic
623and
624.Fn twiddle
625and thus by many other functions for debugging and informational output.
626.It Xo
627.Ft int
628.Fn devopen "struct open_file *of" "const char *name" "const char **file"
629.Xc
630.Pp
631Open the appropriate device for the file named in
632.Fa name ,
633returning in
634.Fa file
635a pointer to the remaining body of
636.Fa name
637which does not refer to the device.
638The
639.Va f_dev
640field in
641.Fa of
642will be set to point to the
643.Vt devsw
644structure for the opened device if successful.
645Device identifiers must
646always precede the path component, but may otherwise be arbitrarily formatted.
647Used by
648.Fn open
649and thus for all device-related I/O.
650.It Xo
651.Ft int
652.Fn devclose "struct open_file *of"
653.Xc
654.Pp
655Close the device allocated for
656.Fa of .
657The device driver itself will already have been called for the close; this call
658should clean up any allocation made by devopen only.
659.It Xo
660.Ft void
661.Fn __abort
662.Xc
663.Pp
664Calls
665.Fn panic
666with a fixed string.
667.It Xo
668.Ft void
669.Fn panic "const char *msg" "..."
670.Xc
671.Pp
672Signal a fatal and unrecoverable error condition.
673The
674.Fa msg ...
675arguments are as for
676.Fn printf .
677.El
678.Sh INTERNAL FILE SYSTEMS
679Internal file systems are enabled by the consumer exporting the array
680.Vt struct fs_ops *file_system[] ,
681which should be initialised with pointers
682to
683.Vt struct fs_ops
684structures.
685The following file system handlers are supplied by
686.Nm ,
687the consumer may supply other file systems of their own:
688.Bl -hang -width ".Va cd9660_fsops"
689.It Va ufs_fsops
690The
691.Bx
692UFS.
693.It Va ext2fs_fsops
694Linux ext2fs file system.
695.It Va tftp_fsops
696File access via TFTP.
697.It Va nfs_fsops
698File access via NFS.
699.It Va cd9660_fsops
700ISO 9660 (CD-ROM) file system.
701.It Va gzipfs_fsops
702Stacked file system supporting gzipped files.
703When trying the gzipfs file system,
704.Nm
705appends
706.Li .gz
707to the end of the filename, and then tries to locate the file using the other
708file systems.
709Placement of this file system in the
710.Va file_system[]
711array determines whether gzipped files will be opened in preference to non-gzipped
712files.
713It is only possible to seek a gzipped file forwards, and
714.Fn stat
715and
716.Fn fstat
717on gzipped files will report an invalid length.
718.It Va bzipfs_fsops
719The same as
720.Va gzipfs_fsops ,
721but for
722.Xr bzip2 1 Ns -compressed
723files.
724.El
725.Pp
726The array of
727.Vt struct fs_ops
728pointers should be terminated with a NULL.
729.Sh DEVICES
730Devices are exported by the supporting code via the array
731.Vt struct devsw *devsw[]
732which is a NULL terminated array of pointers to device switch structures.
733.Sh DRIVER INTERFACE
734The driver needs to provide a common set of entry points that are
735used by
736.Nm libsa
737to interface with the device.
738.Bd -literal
739struct devsw {
740    const char	dv_name[DEV_NAMLEN];
741    int		dv_type;
742    int		(*dv_init)(void);
743    int		(*dv_strategy)(void *devdata, int rw, daddr_t blk,
744			size_t size, char *buf, size_t *rsize);
745    int		(*dv_open)(struct open_file *f, ...);
746    int		(*dv_close)(struct open_file *f);
747    int		(*dv_ioctl)(struct open_file *f, u_long cmd, void *data);
748    int		(*dv_print)(int verbose);
749    void	(*dv_cleanup)(void);
750    char *	(*dv_fmtdev)(struct devdesc *);
751    int		(*dv_parsedev)(struct devdesc **dev, const char *devpart,
752    		const char **path);
753    bool	(*dv_match)(struct devsw *dv, const char *devspec);
754};
755.Ed
756.Bl -tag -width ".Fn dv_strategy"
757.It Fn dv_name
758The device's name.
759.It Fn dv_type
760Type of device.
761The supported types are:
762.Bl -tag -width "DEVT_NONE"
763.It DEVT_NONE
764.It DEVT_DISK
765.It DEVT_NET
766.It DEVT_CD
767.It DEVT_ZFS
768.It DEVT_FD
769.El
770Each type may have its own associated (struct type_devdesc),
771which has the generic (struct devdesc) as its first member.
772.It Fn dv_init
773Driver initialization routine.
774This routine should probe for available units.
775Drivers are responsible for maintaining lists of units for later enumeration.
776No other driver routines may be called before
777.Fn dv_init
778returns.
779.It Fn dv_open
780The driver open routine.
781.It Fn dv_close
782The driver close routine.
783.It Fn dv_ioctl
784The driver ioctl routine.
785.It Fn dv_print
786Prints information about the available devices.
787Information should be presented with
788.Fn pager_output .
789.It Fn dv_cleanup
790Cleans up any memory used by the device before the next stage is run.
791.It Fn dv_fmtdev
792Converts the specified devdesc to the canonical string representation
793for that device.
794.It Fn dv_parsedev
795Parses the device portion of a file path.
796The
797.Dv devpart
798will point to the
799.Sq tail
800of device name, possibly followed by a colon and a path within the device.
801The
802.Sq tail
803is, by convention, the part of the device specification that follows the
804.Fa dv_name
805part of the string.
806So when
807.Fa devparse
808is parsing the string
809.Dq disk3p5:/xxx ,
810.Dv devpart
811will point to the
812.Sq 3
813in that string.
814The parsing routine is expected to allocate a new
815.Dv struct devdesc
816or subclass and return it in
817.Dv dev
818when successful.
819This routine should set
820.Dv path
821to point to the portion of the string after device specification, or
822.Dq /xxx
823in the earlier example.
824Generally, code needing to parse a path will use
825.Fa devparse
826instead of calling this routine directly.
827.It Fn dv_match
828.Dv NULL
829to specify that all device paths starting with
830.Fa dv_name
831match.
832Otherwise, this function returns 0 for a match and a non-zero
833.Dv errno
834to indicate why it didn't match.
835This is helpful when you claim the device path after using it to query
836properties on systems that have uniform naming for different types of
837devices.
838.El
839.Sh HISTORY
840The
841.Nm
842library contains contributions from many sources, including:
843.Bl -bullet -compact
844.It
845.Nm libsa
846from
847.Nx
848.It
849.Nm libc
850and
851.Nm libkern
852from
853.Fx 3.0 .
854.It
855.Nm zalloc
856from
857.An Matthew Dillon Aq Mt dillon@backplane.com
858.El
859.Pp
860The reorganisation and port to
861.Fx 3.0 ,
862the environment functions and this manpage were written by
863.An Mike Smith Aq Mt msmith@FreeBSD.org .
864.Sh BUGS
865The lack of detailed memory usage data is unhelpful.
866