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 void 512.Fn twiddle void 513.Xc 514.Pp 515Successive calls emit the characters in the sequence |,/,-,\\ followed by a 516backspace in order to provide reassurance to the user. 517.El 518.Sh REQUIRED LOW-LEVEL SUPPORT 519The following resources are consumed by 520.Nm 521- stack, heap, console and devices. 522.Pp 523The stack must be established before 524.Nm 525functions can be invoked. 526Stack requirements vary depending on the functions 527and file systems used by the consumer and the support layer functions detailed 528below. 529.Pp 530The heap must be established before calling 531.Fn alloc 532or 533.Fn open 534by calling 535.Fn setheap . 536Heap usage will vary depending on the number of simultaneously open files, 537as well as client behaviour. 538Automatic decompression will allocate more 539than 64K of data per open file. 540.Pp 541Console access is performed via the 542.Fn getchar , 543.Fn putchar 544and 545.Fn ischar 546functions detailed below. 547.Pp 548Device access is initiated via 549.Fn devopen 550and is performed through the 551.Fn dv_strategy , 552.Fn dv_ioctl 553and 554.Fn dv_close 555functions in the device switch structure that 556.Fn devopen 557returns. 558.Pp 559The consumer must provide the following support functions: 560.Bl -hang -width 10n 561.It Xo 562.Ft int 563.Fn getchar void 564.Xc 565.Pp 566Return a character from the console, used by 567.Fn gets , 568.Fn ngets 569and pager functions. 570.It Xo 571.Ft int 572.Fn ischar void 573.Xc 574.Pp 575Returns nonzero if a character is waiting from the console. 576.It Xo 577.Ft void 578.Fn putchar int 579.Xc 580.Pp 581Write a character to the console, used by 582.Fn gets , 583.Fn ngets , 584.Fn *printf , 585.Fn panic 586and 587.Fn twiddle 588and thus by many other functions for debugging and informational output. 589.It Xo 590.Ft int 591.Fn devopen "struct open_file *of" "const char *name" "const char **file" 592.Xc 593.Pp 594Open the appropriate device for the file named in 595.Fa name , 596returning in 597.Fa file 598a pointer to the remaining body of 599.Fa name 600which does not refer to the device. 601The 602.Va f_dev 603field in 604.Fa of 605will be set to point to the 606.Vt devsw 607structure for the opened device if successful. 608Device identifiers must 609always precede the path component, but may otherwise be arbitrarily formatted. 610Used by 611.Fn open 612and thus for all device-related I/O. 613.It Xo 614.Ft int 615.Fn devclose "struct open_file *of" 616.Xc 617.Pp 618Close the device allocated for 619.Fa of . 620The device driver itself will already have been called for the close; this call 621should clean up any allocation made by devopen only. 622.It Xo 623.Ft void 624.Fn __abort 625.Xc 626.Pp 627Calls 628.Fn panic 629with a fixed string. 630.It Xo 631.Ft void 632.Fn panic "const char *msg" "..." 633.Xc 634.Pp 635Signal a fatal and unrecoverable error condition. 636The 637.Fa msg ... 638arguments are as for 639.Fn printf . 640.El 641.Sh INTERNAL FILE SYSTEMS 642Internal file systems are enabled by the consumer exporting the array 643.Vt struct fs_ops *file_system[] , 644which should be initialised with pointers 645to 646.Vt struct fs_ops 647structures. 648The following file system handlers are supplied by 649.Nm , 650the consumer may supply other file systems of their own: 651.Bl -hang -width ".Va cd9660_fsops" 652.It Va ufs_fsops 653The 654.Bx 655UFS. 656.It Va ext2fs_fsops 657Linux ext2fs file system. 658.It Va tftp_fsops 659File access via TFTP. 660.It Va nfs_fsops 661File access via NFS. 662.It Va cd9660_fsops 663ISO 9660 (CD-ROM) file system. 664.It Va gzipfs_fsops 665Stacked file system supporting gzipped files. 666When trying the gzipfs file system, 667.Nm 668appends 669.Li .gz 670to the end of the filename, and then tries to locate the file using the other 671file systems. 672Placement of this file system in the 673.Va file_system[] 674array determines whether gzipped files will be opened in preference to non-gzipped 675files. 676It is only possible to seek a gzipped file forwards, and 677.Fn stat 678and 679.Fn fstat 680on gzipped files will report an invalid length. 681.It Va bzipfs_fsops 682The same as 683.Va gzipfs_fsops , 684but for 685.Xr bzip2 1 Ns -compressed 686files. 687.El 688.Pp 689The array of 690.Vt struct fs_ops 691pointers should be terminated with a NULL. 692.Sh DEVICES 693Devices are exported by the supporting code via the array 694.Vt struct devsw *devsw[] 695which is a NULL terminated array of pointers to device switch structures. 696.Sh DRIVER INTERFACE 697The driver needs to provide a common set of entry points that are 698used by 699.Nm libsa 700to interface with the device. 701.Bd -literal 702struct devsw { 703 const char dv_name[DEV_NAMLEN]; 704 int dv_type; 705 int (*dv_init)(void); 706 int (*dv_strategy)(void *devdata, int rw, daddr_t blk, 707 size_t size, char *buf, size_t *rsize); 708 int (*dv_open)(struct open_file *f, ...); 709 int (*dv_close)(struct open_file *f); 710 int (*dv_ioctl)(struct open_file *f, u_long cmd, void *data); 711 int (*dv_print)(int verbose); 712 void (*dv_cleanup)(void); 713 void (*dv_fmtdev)(struct devdesc *); 714}; 715.Ed 716.Bl -tag -width ".Fn dv_strategy" 717.It Fn dv_name 718The device's name. 719.It Fn dv_type 720Type of device. 721The supported types are: 722.Bl -tag -width "DEVT_NONE" 723.It DEVT_NONE 724.It DEVT_DISK 725.It DEVT_NET 726.It DEVT_CD 727.It DEVT_ZFS 728.It DEVT_FD 729.El 730Each type may have its own associated (struct type_devdesc), 731which has the generic (struct devdesc) as its first member. 732.It Fn dv_init 733Driver initialization routine. 734This routine should probe for available units. 735Drivers are responsible for maintaining lists of units for later enumeration. 736No other driver routines may be called before 737.Fn dv_init 738returns. 739.It Fn dv_open 740The driver open routine. 741.It Fn dv_close 742The driver close routine. 743.It Fn dv_ioctl 744The driver ioctl routine. 745.It Fn dv_print 746Prints information about the available devices. 747Information should be presented with 748.Fn pager_output . 749.It Fn dv_cleanup 750Cleans up any memory used by the device before the next stage is run. 751.It Fn dv_fmtdev 752Converts the specified devdesc to the canonical string representation 753for that device. 754.El 755.Sh HISTORY 756The 757.Nm 758library contains contributions from many sources, including: 759.Bl -bullet -compact 760.It 761.Nm libsa 762from 763.Nx 764.It 765.Nm libc 766and 767.Nm libkern 768from 769.Fx 3.0 . 770.It 771.Nm zalloc 772from 773.An Matthew Dillon Aq Mt dillon@backplane.com 774.El 775.Pp 776The reorganisation and port to 777.Fx 3.0 , 778the environment functions and this manpage were written by 779.An Mike Smith Aq Mt msmith@FreeBSD.org . 780.Sh BUGS 781The lack of detailed memory usage data is unhelpful. 782