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