SIO(3X) SIO(3X) NNAAMMEE Sread, Sgetc, Srdline, Sfetch, Swrite, Sputc, Sprint, Sprintv, Sdone, Sundo, Stie, Suntie, Sflush, Sclose, Sbuftype, Smorefds, Sgetchar, Sputchar, SIOLINELEN, SIOMAXLINELEN - fast stream I/O SSYYNNOOPPSSIISS ##iinncclluuddee ""ssiioo..hh"" iinntt SSrreeaadd(( ffdd,, bbuuff,, nnbbyytteess )) iinntt ffdd ;; cchhaarr **bbuuff ;; iinntt nnbbyytteess ;; iinntt SSggeettcc(( ffdd )) iinntt ffdd ;; cchhaarr **SSrrddlliinnee(( ffdd )) iinntt ffdd ;; cchhaarr **SSffeettcchh(( ffdd,, lleennggtthh )) iinntt ffdd ;; lloonngg **lleennggtthh ;; iinntt SSwwrriittee(( ffdd,, bbuuff,, nnbbyytteess )) iinntt ffdd ;; cchhaarr **bbuuff ;; iinntt nnbbyytteess ;; iinntt SSppuuttcc(( ffdd,, cc )) iinntt ffdd ;; cchhaarr cc ;; iinntt SSpprriinntt(( ffdd,, ffoorrmmaatt [[ ,, ...... ]] )) iinntt ffdd ;; cchhaarr **ffoorrmmaatt ;; iinntt SSpprriinnttvv(( ffdd,, ffoorrmmaatt,, aapp )) iinntt ffdd ;; cchhaarr **ffoorrmmaatt ;; vvaa__lliisstt aapp ;; iinntt SSddoonnee(( ffdd )) iinntt ffdd ;; iinntt SSuunnddoo(( ffdd,, ttyyppee )) iinntt ffdd ;; iinntt ttyyppee ;; iinntt SSttiiee(( iiffdd,, ooffdd )) iinntt iiffdd,, ooffdd ;; iinntt SSuunnttiiee(( ffdd )) iinntt ffdd ;; 29 May 1992 1 SIO(3X) SIO(3X) iinntt SSbbuuffttyyppee(( ffdd,, ttyyppee )) iinntt ffdd,, ttyyppee ;; iinntt SSmmoorreeffddss(()) iinntt SSfflluusshh(( ffdd )) iinntt ffdd ;; iinntt SScclloossee(( ffdd )) iinntt ffdd ;; iinntt SSggeettcchhaarr(( ffdd )) iinntt ffdd ;; iinntt SSppuuttcchhaarr(( ffdd,, cc )) iinntt ffdd;; cchhaarr cc ;; iinntt SSIIOOLLIINNEELLEENN(( ffdd )) iinntt ffdd ;; iinntt SSIIOOMMAAXXLLIINNEELLEENN(( ffdd )) iinntt ffdd ;; DDEESSCCRRIIPPTTIIOONN The _S_I_O library provides support for _s_t_r_e_a_m I/O on file descriptors. The first argument of every function or macro is a file descriptor. The file descriptor may be used either for input or for output, but not both. Attempting to use a descriptor for both input and output will cause the call for the latter use to fail. When you are done with using a file descriptor, you should inform _S_I_O by invoking SSddoonnee(()) (unless the program is about to call _e_x_i_t_(_3_)). You can also use SSddoonnee(()) if you want to perform a different type of operation on the same file descriptor (e.g. first you were reading data from the file descriptor and then you want to write some data). Another possibility is to do stream I/O at different file offsets by using SSddoonnee(()) before using llsseeeekk((22)) to move to a new file offset. I/O operations on different file descriptors do not inter- fere (unless the file descriptors refer to the same file, in which case the results are undefined). For disk files, I/O always starts at the current file off- set. If that offset is not a multiple of the preferred block size for file system I/O, performance will not be optimal (the preferred block size is determined from the _s_t___b_l_k_s_i_z_e field in _s_t_r_u_c_t _s_t_a_t). For optimal perfor- mance, it is recommended that no I/O operations (like _r_e_a_d_(_2_) or _w_r_i_t_e_(_2_)) are applied to the file descriptor if it is to be used by _S_I_O. 29 May 1992 2 SIO(3X) SIO(3X) Read I/O is either buffered, or is done using memory map- ping whenever that is possible and appropriate. The library functions that do stream I/O resemble system calls (for example SSrreeaadd(()) resembles _r_e_a_d_(_2_)) so that mod- ifying a program that uses the system calls to use the _S_I_O functions is easy (e.g. just replace _r_e_a_d_(_2_) with SSrreeaadd(()); the function signatures as well as the return values are exactly the same; also make sure to replace calls to _c_l_o_s_e_(_2_) with SScclloossee(())). _S_I_O uses the underlying system calls _r_e_a_d_(_2_) and _w_r_i_t_e_(_2_) to do I/O (except when reading files using memory map- ping). These calls may be interrupted (i.e. they may return -1 with _e_r_r_n_o set to EINTR). Such interruptions are ignored by _S_I_O which simply reissues the system call (this means that a _S_I_O call will never fail because the underly- ing I/O system call was interrupted). SSrreeaadd(()) reads _n_b_y_t_e_s bytes from the stream associated with file descriptor _f_d into the buffer pointed to by _b_u_f. SSggeettcc(()) reads a character from the stream associated with file descriptor _f_d. It returns SSIIOO__EEOOFF if the end of file has been reached. SSggeettcchhaarr(()) (a macro) performs exactly the same function as SSggeettcc(()) but it is much faster. SSrrddlliinnee(()) reads a line from the stream associated with file descriptor _f_d. The newline at the end of the line is replaced by a NUL byte. Lines longer than the maximum line length supported by _S_I_O will have characters deleted. SSIIOOLLIINNEELLEENN(()) (a macro) returns the length of the line returned by the last call to SSrrddlliinnee(()) (the value returned by SSIIOOLLIINNEELLEENN(()) is valid only after SSrrddlliinnee(()) and as long as no other _S_I_O calls are performed on that file descrip- tor). SSIIOOMMAAXXLLIINNEELLEENN(()) (a macro) returns the maximul line length supported by _S_I_O for the file descriptor. As a side-effect it initializes _f_d for input. SSffeettcchh(()) returns a pointer to data coming from the stream associated with file descriptor _f_d. The amount of data available is indicated by the _l_e_n_g_t_h argument. One possi- ble use for this function is to copy files. SSwwrriittee(()) writes _n_b_y_t_e_s bytes to the stream associated with file descriptor _f_d from the buffer pointed to by _b_u_f. SSppuuttcc(()) writes a single character to the stream associated with file descriptor _f_d. 29 May 1992 3 SIO(3X) SIO(3X) SSppuuttcchhaarr(()) (a macro) performs exactly the same function as SSppuuttcc(()) but it is much faster. SSpprriinntt(()) imitates the behavior of printf(3) as defined in the ANSI C Standard. There are some limitations. Check the SSpprriinntt(()) man page for more information. SSpprriinnttvv(()) is the same as SSpprriinntt(()) except that it uses a _v_a_r_a_r_g_s argument list. SSuunnddoo(()) returns the characters returned by the last call to SSrrddlliinnee(()), SSggeettcc(()) or SSggeettcchhaarr(()) to the stream so that they can be reread. The _t_y_p_e argument to SSuunnddoo(()) can be SSIIOO__UUNNDDOO__LLIINNEE or SSIIOO__UUNNDDOO__CCHHAARR depending on whether the call whose effect needs to be undone was SSrrddlliinnee(()) or SSggeettcc(())/SSggeettcchhaarr(()) respectively. There is no check on whether the last function invoked on _f_d was one of the above and the results are undefined if there is no corre- spondence between the _t_y_p_e and the last operation on _f_d. (i.e. the result is undefined if you try SSIIOO__UUNNDDOO__CCHHAARR and the last operation was not SSggeettcchhaarr(()) or SSggeettcc(())). SSttiiee(()) ties the file descriptor _i_f_d to the file descriptor _o_f_d. This means that whenever a _r_e_a_d_(_2_) is done on _i_f_d, it is preceded by a _w_r_i_t_e_(_2_) on _o_f_d. For filters it is useful to do _S_t_i_e_( _0_, _1 _) to maximize concurrency. It is also useful to do the same thing when you issue prompts to the user and you want the user reply to appear on the same line with the prompt. _i_f_d, _o_f_d will be initialized for input, output respectively (if any of them is initialized, it must be for the appropriate stream type (input or out- put)). If _i_f_d was tied to another file descriptor, the old tie is broken. SSuunnttiiee(()) undoes the effect of SSttiiee(()) for the specified input file descriptor. SSbbuuffttyyppee(()) determines the buffering type for the output stream associated with file descriptor _f_d. By default output directed to terminals is line buffered, output directed to file descriptor 2 (standard error) is unbuffered and everything else is fully buffered. Possi- ble values for the _t_y_p_e argument are SSIIOO__FFUULLLLBBUUFF for full buffering SSIIOO__LLIINNEEBBUUFF for line buffering SSIIOO__NNOOBBUUFF for no buffering SSmmoorreeffddss(()) should be used to inform SSIIOO that the number of available file descriptors has been increased. SSIIOO uses an array of internal stream descriptors which are indexed by the file descriptor number. Some operating systems (ex. 29 May 1992 4 SIO(3X) SIO(3X) SunOS 4.1[.x]) allow the number of available file descrip- tors to vary. If that number is increased beyond its ini- tial value SSIIOO needs to know in order to allocate more stream descriptors. SSddoonnee(()) flushes any buffered output for _f_d and releases the _S_I_O resources used. SSddoonnee(()) is useful in case the pro- gram needs to reprocess the data of a file descriptor (assuming the file descriptor corresponds to a file). The program can call SSddoonnee(()), _l_s_e_e_k_(_2_) to the beginning of the file and then proceed to reread the file. SSfflluusshh(()) causes any buffered stream output to be written to the file descriptor. If its argument is the special value SSIIOO__FFLLUUSSHH__AALLLL then all output streams will be flushed. SScclloossee(()) closes a file descriptor used for stream I/O, flushes any buffered output and releases the _S_I_O resources used. EEXXAAMMPPLLEESS The following code implements a (poor) substitute for the tee command (it copies standard input to a file as well as to standard output). ##iinncclluuddee ""ssiioo..hh"" mmaaiinn(( aarrggcc,, aarrggvv )) iinntt aarrggcc ;; cchhaarr **aarrggvv[[]] ;; {{ cchhaarr **ffiillee == ((aarrggcc >> 11)) ?? aarrggvv[[ 11 ]] :: ""tteeee..ffiillee"" ;; iinntt ffdd == ccrreeaatt(( ffiillee,, 00664444 )) ;; lloonngg lleennggtthh ;; cchhaarr **ss ;; wwhhiillee (( ss == SSffeettcchh(( 00,, &&lleennggtthh )) )) {{ SSwwrriittee(( 11,, ss,, lleennggtthh )) ;; SSwwrriittee(( ffdd,, ss,, lleennggtthh )) ;; }} eexxiitt(( 00 )) ;; }} RREETTUURRNN VVAALLUUEESS SSrreeaadd(()) returns the number of bytes read on success (0 means end-of-file) or SSIIOO__EERRRR on failure (_e_r_r_n_o is set to indicate the error). SSggeettcc(()) returns the character read on success, SIO_EOF when the end-of-file is reached, or SSIIOO__EERRRR on failure (_e_r_r_n_o is set to indicate the error). SSrrddlliinnee(()) returns a pointer to the next line on success. On failure or when the end-of-file is reached it returns NULL. If the end-of-file is reached _e_r_r_n_o is set to 0, 29 May 1992 5 SIO(3X) SIO(3X) otherwise it indicates the error. SSffeettcchh(()) returns a pointer to file data on success. (the _l_e_n_g_t_h argument indicates how many bytes are available). On failure or when the end-of-file is reached it returns NULL. If the end-of-file is reached _e_r_r_n_o is set to 0, otherwise it indicates the error. SSwwrriittee(()) returns the number of bytes written on success or SSIIOO__EERRRR on failure (_e_r_r_n_o is set to indicate the error). SSppuuttcc(()) returns the character it was given as an argument on success SSpprriinntt(()) returns the number of characters printed on success or SSIIOO__EERRRR on failure (_e_r_r_n_o is set to indicate the error). SSddoonnee(()) returns 00 on success or SSIIOO__EERRRR on failure (_e_r_r_n_o is set to indicate the error). SSuunnddoo(()) returns 00 on success or SSIIOO__EERRRR on failure (_e_r_r_n_o is set to indicate the error). SSttiiee(()) returns 00 on success or SSIIOO__EERRRR on failure (_e_r_r_n_o is set to indicate the error). SSuunnttiiee(()) returns 00 on success or SSIIOO__EERRRR on failure (_e_r_r_n_o is set to EEBBAADDFF if there was no tied file descriptor). SSbbuuffttyyppee(()) returns 00 on success or SSIIOO__EERRRR on failure (_e_r_r_n_o is set to EEBBAADDFF if this is not an output stream or to EEIINNVVAALL if an unknown _t_y_p_e is specified). SSmmoorreeffddss(()) returns 00 on success or SSIIOO__EERRRR on failure (because of lack of memory). SSfflluusshh(()) returns 00 on success or SSIIOO__EERRRR on failure (_e_r_r_n_o is set to indicate the error). SScclloossee(()) returns 00 on success or SSIIOO__EERRRR on failure (_e_r_r_n_o is set to indicate the error). SSggeettcchhaarr(()) returns the character read on success, SIO_EOF when the end-of-file is reached, or SSIIOO__EERRRR on failure (_e_r_r_n_o is set to indicate the error). SSppuuttcchhaarr(()) returns the character it was given as an argu- ment on success or SSIIOO__EERRRR on failure (_e_r_r_n_o is set to indicate the error). SSIIOOLLIINNEELLEENN(()) returns the length of the last line read by SSrrddlliinnee(()). SSIIOOMMAAXXLLIINNEELLEENN(()) returns the length of the longest line supported by _S_I_O on success or SSIIOO__EERRRR on failure (_e_r_r_n_o 29 May 1992 6 SIO(3X) SIO(3X) is set to indicate the error). Attempting a read operation on a descriptor opened for writing or vice versa will cause the operation to fail with _e_r_r_n_o set to EEBBAADDFF. The first _S_I_O operation on a descriptor must be a read or write operation. It cannot be a control operation (like SSfflluusshh(())). Such an operation will fail with _e_r_r_n_o set to EEBBAADDFF. NNOOTTEE 11:: SSttiiee(()) is an input/output operation for the respective file descriptors, not a control operation. SSuunnttiiee(()) is a control operation. NNOOTTEE 22:: SSIIOO__EERRRR is defined to be --11. SSEEEE AALLSSOO Sprint(3) BBUUGGSS If the operating system does not provide for invocation of a finalization function upon exit, the program will have to explicitly flush all output streams. The following operating systems provide such a facility: SunOS 4.x, Ultrix 4.x, SunOS 5.x Socket file descriptors can be used for input as well as output but SSIIOO does not support this. The current implementation will not try to use memory map- ping to read a file if the file offset is not 0 (it will use buffered I/O instead). Pointers returned by SSffeettcchh(()) point to read-only memory. Attempting to modify this memory will result in a segmen- tation violation. 29 May 1992 7