io.html revision 266692
190792Sgshapiro<html> 290792Sgshapiro<head> 390792Sgshapiro<title>libsm sm_io general overview</title> 490792Sgshapiro</head> 590792Sgshapiro<body> 690792Sgshapiro<a href="index.html">Back to libsm overview</a> 790792Sgshapiro<center> 890792Sgshapiro<h1>libsm sm_io general overview</h1> 9266692Sgshapiro<br> $Id: io.html,v 1.3 2001-03-17 03:22:50 gshapiro Exp $ 1090792Sgshapiro</center> 1190792Sgshapiro<h2> Introduction </h2> 1290792Sgshapiro<p> 1390792SgshapiroThe <i>sm_io</i> portion of the <i>libsm</i> library is similar to 1490792Sgshapirothe <i>stdio</i> library. It is derived from the Chris Torek version 1590792Sgshapiroof the <i>stdio</i> library (BSD). There are some key differences 1690792Sgshapirodescribed below between <i>sm_io</i> and <i>stdio</i> but many 1790792Sgshapirosimilarities will be noticed. 1890792Sgshapiro</p> 1990792Sgshapiro<p> 2090792SgshapiroA key difference between <i>stdio</i> and <i>sm_io</i> is that the 2190792Sgshapirofunctional code that does the open, close, read, write, etc. on a file 2290792Sgshapirocan be different for different files. For example, with <i>stdio</i> 2390792Sgshapirothe functional code (read, write) is either the default supplied in the 2490792Sgshapirolibrary or a "programmer specified" set of functions set via 2590792Sgshapiro<i>sm_io_open()</i>. Whichever set of functions are specified <b>all</b> 2690792Sgshapiroopen's, read's, write's, etc use the same set of functions. In contrast, with 2790792Sgshapiro<i>sm_io</i> a different set of functions can be specified with each 2890792Sgshapiroactive file for read's, write's, etc. These different function sets 2990792Sgshapiroare identified as <b>file types</b> (see <tt>sm_io_open()</tt>). Each function 3090792Sgshapiroset can handle the actions directly, pass the action request to 3190792Sgshapiroanother function set or do some work before passing it on to another function 3290792Sgshapiroset. The setting of a function set for a file type can be done for 3390792Sgshapiroa file type at any time (even after the type is open). 3490792Sgshapiro</p> 3590792Sgshapiro<p> 3690792SgshapiroA second difference is the use of <a href="rpool.html"><b>rpools</b></a>. 3790792SgshapiroAn <b>rpool</b> is specified with the opening of a file 3890792Sgshapiro(<tt>sm_io_open()</tt>). 3990792SgshapiroThis allows of a file to be associated with an rpool so that when the 4090792Sgshapirorpool is released the open file will be closed; the <tt>sm_io_open()</tt> 4190792Sgshapiroregisters that <tt>sm_io_close()</tt> should be called when the rpool is 4290792Sgshapiroreleased. 4390792Sgshapiro</p> 4490792Sgshapiro<p> 4590792SgshapiroA third difference is that the I/O functions take a <i>timeout</i> 4690792Sgshapiroargument. This allows the setting of a maximum amount of time allowable 4790792Sgshapirofor the I/O to be completed. This means the calling program does not need 4890792Sgshapiroto setup it's own timeout mechanism. NOTE: SIGALRM's should not be 4990792Sgshapiroactive in the calling program when an I/O function with a <i>timeout</i> 5090792Sgshapirois used. 5190792Sgshapiro</p> 5290792Sgshapiro<p> 5390792SgshapiroWhen converting source code from <i>stdio</i> to <i>sm_io</i> be 5490792Sgshapirovery careful to NOTE: the arguments to functions have been rationalized. 5590792SgshapiroThat is, unlike <i>stdio</i>, all <i>sm_io</i> functions that 5690792Sgshapirotake a file pointer (SM_FILE_T *) argument have the file pointer 5790792Sgshapiroas the first argument. Also not all functions with <i>stdio</i> have 5890792Sgshapiroan identical matching <i>sm_io</i> API: the API list has been thinned 5990792Sgshapirosince a number of <i>stdio</i> API's overlapped in functionality. 6090792SgshapiroRemember many functions also have a <i>timeout</i> argument added. 6190792Sgshapiro</p> 6290792Sgshapiro<p> 6390792SgshapiroWhen a file is going to be opened, the file type is included with 6490792Sgshapiro<tt>sm_io_open()</tt>. 6590792SgshapiroA file type is either one automatically included with the <i>sm_io</i> 6690792Sgshapirolibrary or one created by the program at runtime. 6790792SgshapiroFile types can be either buffered or unbuffered. When buffered the buffering 6890792Sgshapirois either the builtin <i>sm_io</i> buffering or as done by the file type. 6990792SgshapiroFile types can be disk files, strings, TCP/IP connections or whatever 7090792Sgshapiroyour imagination can come up with that can be read and/or written to. 7190792Sgshapiro</p> 7290792Sgshapiro<p> 7390792SgshapiroInformation about a particular file type or pointer can be obtained or set with 7490792Sgshapirothe <i>sm_io</i> "info" functions. 7590792SgshapiroThe <tt>sm_io_setinfo()</tt> and <tt>sm_io_getinfo()</tt> functions work on 7690792Sgshapiroan active file pointer. 7790792Sgshapiro</p> 7890792Sgshapiro<h2>Include files</h2> 7990792Sgshapiro<p> 8090792SgshapiroThere is one main include file for use with sm_io: <i>io.h</i>. Since the 8190792Sgshapirouse of <b>rpools</b> is specified with <tt>sm_io_open()</tt> an 8290792Sgshapiro<b>rpool</b> may 8390792Sgshapirobe created and thus <i>rpool.h</i> may need to be included as well 8490792Sgshapiro(before io.h). 8590792Sgshapiro</p> 8690792Sgshapiro<pre> 8790792Sgshapiro#include <rpool.h> 8890792Sgshapiro#include <io.h> 8990792Sgshapiro</pre> 9090792Sgshapiro 9190792Sgshapiro<h2>Functions/API's</h2> 9290792Sgshapiro<p> 9390792SgshapiroBelow is a list of the functions for <i>sm_io</i> listed in 9490792Sgshapiroalphabetical order. Currently these functions return error codes 9590792Sgshapiroand set errno when appropriate. These (may?/will?) change to 9690792Sgshapiroraising exceptions later. 9790792Sgshapiro</p> 9890792Sgshapiro<pre> 9990792Sgshapiro<a href="#sm_io_autoflush">SM_FILE_T *sm_io_autoflush(SM_FILE_T *fp, SM_FILE_T *)</a> 10090792Sgshapiro 10190792Sgshapiro<a href="#sm_io_automode">void sm_io_automode(SM_FILE_T *fp, SM_FILE_T *)</a> 10290792Sgshapiro 10390792Sgshapiro<a href="#defaultapi">void sm_io_clearerr(SM_FILE_T *fp)</a> 10490792Sgshapiro 10590792Sgshapiro<a href="#sm_io_close">int sm_io_close(SM_FILE_T *fp, int timeout)</a> 10690792Sgshapiro 10790792Sgshapiro<a href="#defaultapi">int sm_io_dup(SM_FILE_T *fp)</a> 10890792Sgshapiro 10990792Sgshapiro<a href="#defaultapi">int sm_io_eof(SM_FILE_T *fp)</a> 11090792Sgshapiro 11190792Sgshapiro<a href="#defaultapi">int sm_io_error(SM_FILE_T *fp)</a> 11290792Sgshapiro 11390792Sgshapiro<a href="#defaultapi">char * sm_io_fgets(SM_FILE_T *fp, int timeout, char *buf, int n)</a> 11490792Sgshapiro 11590792Sgshapiro<a href="#defaultapi">int sm_io_flush(SM_FILE_T *fp, int timeout)</a> 11690792Sgshapiro 11790792Sgshapiro<a href="#sm_io_fopen">int sm_io_fopen(char *pathname, int flags [, MODE_T mode])</a> 11890792Sgshapiro 11990792Sgshapiro<a href="#defaultapi">int sm_io_fprintf(SM_FILE_T *fp, int timeout, const char *fmt, ...)</a> 12090792Sgshapiro 12190792Sgshapiro<a href="#defaultapi">int sm_io_fputs(s, int, SM_FILE_T *fp)</a> 12290792Sgshapiro 12390792Sgshapiro<a href="#defaultapi">int sm_io_fscanf(SM_FILE_T *fp, int timeout, char const *fmt, ...) </a> 12490792Sgshapiro 12590792Sgshapiro<a href="#defaultapi">int sm_io_getc(SM_FILE_T *fp, int timeout)</a> 12690792Sgshapiro 12790792Sgshapiro<a href="#sm_io_getinfo">void sm_io_getinfo(SM_FILE_T *sfp, int what, void *valp)</a> 12890792Sgshapiro 12990792Sgshapiro<a href="#sm_io_open">SM_FILE_T * sm_io_open(SM_FILE_T type, int timeout, void *info, int flags, void *rpool)</a> 13090792Sgshapiro 13190792Sgshapiro<a href="#defaultapi">int sm_io_purge(SM_FILE_T *fp)</a> 13290792Sgshapiro 13390792Sgshapiro<a href="#defaultapi">int sm_io_putc(SM_FILE_T *fp, int timeout, int c)</a> 13490792Sgshapiro 13590792Sgshapiro<a href="#defaultapi">size_t sm_io_read(SM_FILE_T *fp, int timeout, char *buf, size_t size)</a> 13690792Sgshapiro 13790792Sgshapiro<a href="#sm_io_reopen">SM_FILE_T * sm_io_open(SM_FILE_T type, int timeout, void *info, int flags, void *rpool)</a> 13890792Sgshapiro 13990792Sgshapiro<a href="#defaultapi">void sm_io_rewind(SM_FILE_T *fp, int timeout)</a> 14090792Sgshapiro 14190792Sgshapiro<a href="#defaultapi">int sm_io_seek(SM_FILE_T *fp, off_t offset, int timeout, int whence)</a> 14290792Sgshapiro 14390792Sgshapiro<a href="#sm_io_setinfo">void sm_io_setinfo(SM_FILE_T *sfp, int what, void *valp)</a> 14490792Sgshapiro 14590792Sgshapiro<a href="#defaultapi">int sm_io_setvbuf(SM_FILE_T *fp, int timeout, char *buf, int mode, size_t size)</a> 14690792Sgshapiro 14790792Sgshapiro<a href="#defaultapi">int sm_io_sscanf(const char *str, char const *fmt, ...)</a> 14890792Sgshapiro 14990792Sgshapiro<a href="#defaultapi">long sm_io_tell(SM_FILE_T *fp, int timeout)</a> 15090792Sgshapiro 15190792Sgshapiro<a href="#defaultapi">int sm_io_ungetc(SM_FILE_T *fp, int timeout, int c)</a> 15290792Sgshapiro 15390792Sgshapiro<a href="#defaultapi">size_t sm_io_write(SM_FILE_T *fp, int timeout, char *buf, size_t size)</a> 15490792Sgshapiro 15590792Sgshapiro<a href="#defaultapi">int sm_snprintf(char *str, size_t n, char const *fmt, ...)</a> 15690792Sgshapiro 15790792Sgshapiro</pre> 15890792Sgshapiro<a name="timeouts"> 15990792Sgshapiro<h2>Timeouts</h2> 16090792Sgshapiro<p> 16190792SgshapiroFor many of the functions a <i>timeout</i> argument is given. This limits 16290792Sgshapirothe amount of time allowed for the function to complete. There are three 16390792Sgshapiropre-defined values: 16490792Sgshapiro<menu> 16590792Sgshapiro<li> 16690792SgshapiroSM_TIME_DEFAULT - timeout using the default setting for this file type 16790792Sgshapiro</li> 16890792Sgshapiro<li> 16990792SgshapiroSM_TIME_FOREVER - timeout will take forever; blocks until task completed 17090792Sgshapiro</li> 17190792Sgshapiro<li> 17290792SgshapiroSM_TIME_IMMEDIATE - timeout (virtually) now 17390792Sgshapiro</li> 17490792Sgshapiro</menu> 17590792Sgshapiro</p> 17690792Sgshapiro<p> 17790792SgshapiroA function caller can also specify a positive integer value in milliseconds. 17890792SgshapiroA function will return with <i>errno</i> set to EINVAL if a bad value 17990792Sgshapirois given for <i>timeout</i>. 18090792SgshapiroWhen a function times out the function returns in error with <i>errno</i> 18190792Sgshapiroset to <b>EAGAIN</b>. In the future this may change to an exception being 18290792Sgshapirothrown. 18390792Sgshapiro</p> 18490792Sgshapiro<h2>Function Descriptions</h2> 18590792Sgshapiro<dl> 18690792Sgshapiro<!-- SM_IO_FOPEN --> 18790792Sgshapiro<p></p> 18890792Sgshapiro<dt><tt><a name="sm_io_fopen"> 18990792SgshapiroSM_FILE_T * 19090792Sgshapiro<br> 19190792Sgshapirosm_io_fopen(char *pathname, int flags) 19290792Sgshapiro<br> 19390792SgshapiroSM_FILE_T * 19490792Sgshapiro<br> 19590792Sgshapirosm_io_fopen(char *pathname, int flags, MODE_T mode) 19690792Sgshapiro</a></tt></dt> 19790792Sgshapiro<dd> 19890792SgshapiroOpen the file named by <tt>pathname</tt>, and associate a stream with it. 19990792SgshapiroThe arguments are the same as for the <tt>open(2)</tt> system call. 20090792Sgshapiro<br> 20190792SgshapiroIf memory could not be allocated, an exception is raised. 20290792SgshapiroIf successful, an <tt>SM_FILE_T</tt> pointer is returned. 20390792SgshapiroOtherwise, <tt>NULL</tt> is returned and <tt>errno</tt> is set. 20490792Sgshapiro<!-- SM_IO_OPEN --> 20590792Sgshapiro<p></p> 20690792Sgshapiro<dt><tt><a name="sm_io_open"> 20790792SgshapiroSM_FILE_T * 20890792Sgshapiro<br> 20990792Sgshapirosm_io_open(const SM_FILE_T *type, int timeout, const void *info, int flags, void *rpool) 21090792Sgshapiro</a></tt></dt> 21190792Sgshapiro<dd> 21290792SgshapiroOpens a file by <i>type</i> directed by <i>info</i>. <i>Type</i> is a filled-in 21390792SgshapiroSM_FILE_T structure from the following builtin list 21490792Sgshapiro(<a href="#builtins"><b>descriptions below</b></a>) 21590792Sgshapiroor one specified by the program. 21690792Sgshapiro<menu> 21790792Sgshapiro<li> 21890792SgshapiroSmFtString 21990792Sgshapiro</li> 22090792Sgshapiro<li> 22190792SgshapiroSmFtStdio 22290792Sgshapiro</li> 22390792Sgshapiro<li> 22490792SgshapiroSmFtStdiofd 22590792Sgshapiro</li> 22690792Sgshapiro<li> 22790792Sgshapirosmioin <b>*</b> 22890792Sgshapiro</li> 22990792Sgshapiro<li> 23090792Sgshapirosmioout <b>*</b> 23190792Sgshapiro</li> 23290792Sgshapiro<li> 23390792Sgshapirosmioerr <b>*</b> 23490792Sgshapiro</li> 23590792Sgshapiro<li> 23690792Sgshapirosmiostdin <b>*</b> 23790792Sgshapiro</li> 23890792Sgshapiro<li> 23990792Sgshapirosmiostdout <b>*</b> 24090792Sgshapiro</li> 24190792Sgshapiro<li> 24290792Sgshapirosmiostderr <b>*</b> 24390792Sgshapiro</li> 24490792Sgshapiro<li> 24590792SgshapiroSmFtSyslog 24690792Sgshapiro</li> 24790792Sgshapiro</menu> 24890792Sgshapiro<br> 24990792SgshapiroThe above list of file types are already appropriately filled in. Those marked 25090792Sgshapirowith a "<b>*</b>" are already open and may be used directly and immediately. 25190792SgshapiroFor program specified types, to set the <i>type</i> argument easily and with minimal error the macro 25290792Sgshapiro<b>SM_IO_SET_TYPE</b> should be used. The SM_FILE_T structure is fairly 25390792Sgshapirolarge, but only a small portion of it need to be initialized for a new 25490792Sgshapirotype. 25590792SgshapiroSee also <a href="#writefunctions">"Writing Functions for a File Type"</a>. 25690792Sgshapiro<menu> 25790792Sgshapiro<pre> 25890792SgshapiroSM_IO_SET_TYPE(type, name, open, close, read, write, seek, get, set, timeout) 25990792Sgshapiro</pre> 26090792Sgshapiro</menu> 26190792Sgshapiro<br> 26290792Sgshapiro<i>Timeout</i> is set as described in the <a href="#timeouts"><b>Timeouts</b></a> 26390792Sgshapirosection. 26490792Sgshapiro<br> 26590792Sgshapiro<i>Info</i> is information that describes for the file type what is 26690792Sgshapiroto be opened and any associated information. 26790792SgshapiroFor a disk file this would be a file path; with a TCP 26890792Sgshapiroconnection this could be an a structure containing an IP address and port. 26990792Sgshapiro<br><i>Flags</i> is a 27090792Sgshapiroset of sm_io flags that describes how the file is to be interacted with: 27190792Sgshapiro<menu> 27290792Sgshapiro<li> 27390792SgshapiroSM_IO_RDWR - read and write 27490792Sgshapiro</li> 27590792Sgshapiro<li> 27690792SgshapiroSM_IO_RDONLY - read only 27790792Sgshapiro</li> 27890792Sgshapiro<li> 27990792SgshapiroSM_IO_WRONLY - write only 28090792Sgshapiro</li> 28190792Sgshapiro<li> 28290792SgshapiroSM_IO_APPEND - allow write to EOF only 28390792Sgshapiro</li> 28490792Sgshapiro<li> 28590792SgshapiroSM_IO_APPENDRW - allow read-write from EOF only 28690792Sgshapiro</li> 28790792Sgshapiro<li> 28890792SgshapiroSM_IO_RDWRTR - read and write with truncation of file first 28990792Sgshapiro</li> 29090792Sgshapiro</menu> 29190792Sgshapiro<i>Rpool</i> is the address of the rpool that this open is to be associated 29290792Sgshapirowith. When the rpool is released then the close function for this 29390792Sgshapirofile type will be automatically called to close the file for cleanup. 29490792SgshapiroIf NULL is specified for <i>rpool</i> then the close function is not 29590792Sgshapiroassociated (attached) to an rpool. 29690792Sgshapiro<br> 29790792SgshapiroOn cannot allocate memory, an exception is raised. 29890792SgshapiroIf the <i>type</i> is invalid, <tt>sm_io_open</tt> will abort the process. 29990792SgshapiroOn success an SM_FILE_T * pointer is returned. 30090792SgshapiroOn failure the NULL pointer is returned and errno is set. 30190792Sgshapiro</dd> 30290792Sgshapiro<!-- SM_IO_SETINFO --> 30390792Sgshapiro<p></p> 30490792Sgshapiro<dt><tt><a name="sm_io_setinfo"> 30590792Sgshapiroint 30690792Sgshapiro<br> 30790792Sgshapirosm_io_setinfo(SM_FILE_T *sfp, int what, void *valp) 30890792Sgshapiro</a></tt></dt> 30990792Sgshapiro<dd> 31090792SgshapiroFor the open file <i>sfp</i> set the indicated information (<i>what</i>) 31190792Sgshapiroto the new value <i>(valp</i>). 31290792SgshapiroThis will make the change for this SM_FILE_T only. The file 31390792Sgshapirotype that <i>sfp</i> originally belonged to will still be 31490792Sgshapiroconfigured the same way (this is to prevent side-effect 31590792Sgshapiroto other open's of the same file type, particularly with threads). 31690792SgshapiroThe value of <i>what</i> will be file-type dependant since this function 31790792Sgshapirois one of the per file type setable functions. 31890792SgshapiroOne value for <i>what</i> that is valid for all file types is 31990792SgshapiroSM_WHAT_VECTORS. This sets the currently open file with a new function 32090792Sgshapirovector set for open, close, etc. The new values are taken from <i>valp</i> 32190792Sgshapiroa SM_FILE_T filled in by the used via the macro SM_IO_SET_TYPE 32290792Sgshapiro(see and <a href="#writefunctions"> 32390792Sgshapiro"Writing Functions for a File Type"</a> for more information). 32490792Sgshapiro<br> 32590792SgshapiroOn success 0 (zero) is returned. On failure -1 is returned and errno is set. 32690792Sgshapiro</dd> 32790792Sgshapiro<!-- SM_IO_GETINFO --> 32890792Sgshapiro<p></p> 32990792Sgshapiro<dt><tt><a name="sm_io_getinfo"> 33090792Sgshapiroint 33190792Sgshapiro<br> 33290792Sgshapirosm_io_getinfo(SM_FILE_T *sfp, int what, void *valp) 33390792Sgshapiro</a></tt></dt> 33490792Sgshapiro<dd> 33590792SgshapiroFor the open file <i>sfp</i> get the indicated information (<i>what</i>) 33690792Sgshapiroand place the result in <i>(valp</i>). 33790792SgshapiroThis will obtain information for SM_FILE_T only and may be different than 33890792Sgshapirothe information for the file type it was originally opened as. 33990792SgshapiroThe value of <i>what</i> will be file type dependant since this function 34090792Sgshapirois one of the per file type setable functions. 34190792SgshapiroOne value for <i>what</i> that is valid for all file types is 34290792SgshapiroSM_WHAT_VECTORS. This gets from the currently open file a copy of 34390792Sgshapirothe function vectors and stores them in <i>valp</i> a SM_FILE_T 34490792Sgshapiro(see <a href="#writefunctions"> 34590792Sgshapiro"Writing Functions for a File Type"</a> for more information). 34690792Sgshapiro<br> 34790792SgshapiroOn success 0 (zero) is returned. On failure -1 is returned and errno is set. 34890792Sgshapiro</dd> 34990792Sgshapiro<!-- SM_IO_AUTOFLUSH --> 35090792Sgshapiro<p></p> 35190792Sgshapiro<dt><tt><a name="sm_io_autoflush"> 35290792Sgshapirovoid 35390792Sgshapiro<br> 35490792Sgshapirosm_io_autoflush(SM_FILE_T *fp1, *SM_FILE_T fp2) 35590792Sgshapiro</a></tt></dt> 35690792Sgshapiro<dd> 35790792SgshapiroAssociate a read of <i>fp1</i> with a data flush for <i>fp2</i>. If a read 35890792Sgshapiroof <i>fp1</i> discovers that there is no data available to be read, then 35990792Sgshapiro<i>fp2</i> will have it's data buffer flushed for writable data. It is 36090792Sgshapiroassumed that <i>fp1</i> is open for reading and <i>fp2</i> is open 36190792Sgshapirofor writing. 36290792Sgshapiro<br> 36390792SgshapiroOn return the old file pointer associated with <i>fp1</i> for flushing 36490792Sgshapirois returned. A return of NULL is no an error; this merely indicates no 36590792Sgshapiroprevious association. 36690792Sgshapiro</dd> 36790792Sgshapiro<!-- SM_IO_AUTOMODE --> 36890792Sgshapiro<p></p> 36990792Sgshapiro<dt><tt><a name="sm_io_automode"> 37090792Sgshapirovoid 37190792Sgshapiro<br> 37290792Sgshapirosm_io_automode(SM_FILE_T *fp1, *SM_FILE_T fp2) 37390792Sgshapiro<dt><tt><a name="sm_io_automode"> 37490792Sgshapiro</a></tt></dt> 37590792Sgshapiro<dd> 37690792SgshapiroAssociate the two file pointers for blocking/non-blocking mode changes. 37790792SgshapiroIn the handling of timeouts <i>sm_io</i> may need to switch the mode of 37890792Sgshapiroa file between blocking and non-blocking. If the underlying file descriptor 37990792Sgshapirohas been duplicated with <tt>dup(2)</tt> and these descriptors are used 38090792Sgshapiroby <i>sm_io</i> (for example with an SmFtStdiofd file type), then this API 38190792Sgshapiroshould be called to associate them. Otherwise odd behavior (i.e. errors) 38290792Sgshapiromay result that is not consistently reproducable nor easily identifiable. 38390792Sgshapiro</dd> 38490792Sgshapiro<!-- SM_IO_CLOSE --> 38590792Sgshapiro<p></p> 38690792Sgshapiro<dt><tt><a name="sm_io_close"> 38790792Sgshapiroint 38890792Sgshapiro<br> 38990792Sgshapirosm_io_close(SM_FILE_T *sfp, int timeout) 39090792Sgshapiro</a></tt></dt> 39190792Sgshapiro<dd> 39290792SgshapiroRelease all resources (file handles, memory, etc.) associated with 39390792Sgshapirothe open SM_FILE_T <i>sfp</i>. If buffering is active then the 39490792Sgshapirobuffer is flushed before any resources are released. 39590792Sgshapiro<i>Timeout</i> is set as described in the <a href="#timeouts"><b>Timeouts</b></a> 39690792Sgshapirosection. 39790792SgshapiroThe first resources released after buffer flushing will be the 39890792Sgshapirobuffer itself. Then the <b>close</b> function specified in the 39990792Sgshapirofile type at open will be called. It is the responsibility 40090792Sgshapiroof the <b>close</b> function to release any file type 40190792Sgshapirospecific resources allocated and to call <tt>sm_io_close()</tt> 40290792Sgshapirofor the next file type layer(s) that the current file type uses (if any). 40390792Sgshapiro<br> 40490792SgshapiroOn success 0 (zero) is returned. On failure SM_IO_EOF is returned and 40590792Sgshapiroerrno is set. 40690792Sgshapiro</dd> 40790792Sgshapiro</dl> 40890792Sgshapiro<h2> 40990792Sgshapiro<a name="builtins">Description of Builtin File Types</a> 41090792Sgshapiro</h2> 41190792Sgshapiro<p> 41290792SgshapiroThere are several builtin file types as mentioned in <tt>sm_io_open()</tt>. 41390792SgshapiroMore file types may be added later. 41490792Sgshapiro</p> 41590792Sgshapiro<dl> 41690792Sgshapiro<p></p> 41790792Sgshapiro<dt><tt>SmFtString</tt></dt> 41890792Sgshapiro<dd> 41990792SgshapiroOperates on a character string. <i>SmFtString</i> is a file type only. 42090792SgshapiroThe string starts at the location 0 (zero) 42190792Sgshapiroand ends at the last character. A read will obtain the requested 42290792Sgshapironumber of characters if available; else as many as possible. A read 42390792Sgshapirowill not terminate the read characters with a NULL ('\0'). A write 42490792Sgshapirowill place the number of requested characters at the current location. 42590792SgshapiroTo append to a string either the pointer must currently be at the end 42690792Sgshapiroof the string or a seek done to position the pointer. The file type 42790792Sgshapirohandles the space needed for the string. Thus space needed for the 42890792Sgshapirostring will be grown automagically without the user worrying about 42990792Sgshapirospace management. 43090792Sgshapiro</dd> 43190792Sgshapiro<dt><tt>SmFtStdio</tt></dt> 43290792Sgshapiro<dd> 43390792SgshapiroA predefined SM_FILE_T structure with function vectors pointing to 43490792Sgshapirofunctions that result in the file-type behaving as the system stdio 43590792Sgshapironormally does. The <i>info</i> portion of the <tt>sm_io_open</tt> 43690792Sgshapirois the path of the file to be opened. Note that this file type 43790792Sgshapirodoes not interact with the system's stdio. Thus a program mixing system 43890792Sgshapirostdio and sm_io stdio (SmFtStdio) will result in uncoordinated input 43990792Sgshapiroand output. 44090792Sgshapiro</dd> 44190792Sgshapiro<dt><tt>SmFtStdiofd</tt></dt> 44290792Sgshapiro<dd> 44390792SgshapiroA predefined SM_FILE_T structure with function vectors pointing to 44490792Sgshapirofunctions that result in the file-type behaving as the system stdio 44590792Sgshapironormally does. The <i>info</i> portion of the <tt>sm_io_open</tt> 44690792Sgshapirois a file descriptor (the value returned by open(2)). Note that this file type 44790792Sgshapirodoes not interact with the system's stdio. Thus a program mixing system 44890792Sgshapirostdio and sm_io stdio (SmFtStdio) will result in uncoordinated input 44990792Sgshapiroand output. 45090792Sgshapiro</dd> 45190792Sgshapiro<dt><tt>smioin</tt></dt> 45290792Sgshapiro<dt><tt>smioout</tt></dt> 45390792Sgshapiro<dt><tt>smioerr</tt></dt> 45490792Sgshapiro<dd> 45590792SgshapiroThe three types <i>smioin</i>, <i>smioout</i> and <i>smioerr</i> are grouped 45690792Sgshapirotogether. These three types 45790792Sgshapiroperform in the same manner as <b>stdio</b>'s <i>stdin</i>, <i>stdout</i> 45890792Sgshapiroand <i>stderr</i>. These types are both the names and the file pointers. 45990792SgshapiroThey are already open when a program starts (unless the parent explictly 46090792Sgshapiroclosed file descriptors 0, 1 and 2). 46190792SgshapiroThus <tt>sm_io_open()</tt> should never be called for these types: 46290792Sgshapirothe named file pointers should be used directly. 46390792Sgshapiro<i>Smioin</i> and <i>smioout</i> are buffered 46490792Sgshapiroby default. <i>Smioerr</i> is not buffered by default. Calls to <b>stdio</b> 46590792Sgshapiroare safe to make when using these three<b>sm_io</b> file pointers. 46690792SgshapiroThere is no interaction between <b>sm_io</b> and <b>stdio</b>. Hence, 46790792Sgshapirodue to buffering, the sequence of input and output data from both <b>sm_io</b> 46890792Sgshapiroand <b>stdio</b> at the same time may appear unordered. For 46990792Sgshapirocoordination between <b>sm_io</b> and <b>stdio</b> use the three 47090792Sgshapirofile pointers below (<i>smiostdin, smiostdout, smiostderr</i>). 47190792Sgshapiro</dd> 47290792Sgshapiro<dt><tt>smiostdin</tt></dt> 47390792Sgshapiro<dt><tt>smiostdout</tt></dt> 47490792Sgshapiro<dt><tt>smiostderr</tt></dt> 47590792Sgshapiro<dd> 47690792SgshapiroThe three types <i>smiostdin</i>, <i>smioostdut</i> and <i>smiostderr</i> 47790792Sgshapiroare grouped together. These three types 47890792Sgshapiroperform in the same manner as <b>stdio</b>'s <i>stdin</i>, <i>stdout</i> 47990792Sgshapiroand <i>stderr</i>. These types are both the names and file pointers. 48090792SgshapiroThey are already open when a program starts (unless the parent explictly 48190792Sgshapiroclose file descriptors 0, 1 and 2). 48290792SgshapiroThus <tt>sm_io_open()</tt> should 48390792Sgshapironever be called: the named file pointers should be used directly. 48490792SgshapiroCalls to <b>stdio</b> are safe to make when using these three<b>sm_io</b> 48590792Sgshapirofile pointers though no code is shared between the two libaries. 48690792SgshapiroHowever, the input and output between <i>sm_io</i> and <i>stdio</i> is 48790792Sgshapirocoordinated for these three file pointers: <i>smiostdin</i>, 48890792Sgshapiro<i>smiostdout</i> and <i>smiostderr</i> are layered on-top-of 48990792Sgshapirothe system's <i>stdio</i>. 49090792Sgshapiro<i>Smiostdin</i>, <i>smiostdout</i> 49190792Sgshapiroand <i>Smiostderr</i> are not buffered by default. 49290792SgshapiroHence, due to buffering in <i>stdio</i> only, the sequence of input and 49390792Sgshapirooutput data from both <b>sm_io</b> and <b>stdio</b> at the same time will 49490792Sgshapiroappear ordered. If <i>sm_io</i> buffering is turned on then the 49590792Sgshapiroinput and output can appear unordered or lost. 49690792Sgshapiro</dd> 49790792Sgshapiro<dt><tt>SmFtSyslog</tt></dt> 49890792Sgshapiro<dd> 49990792SgshapiroThis opens the channel to the system log. Reads are not allowed. Writes 50090792Sgshapirocannot be undone once they have left the <i>sm_io</i> buffer. 50190792SgshapiroThe man pages for <tt>syslog(3)</tt> should be read for information 50290792Sgshapiroon syslog. 50390792Sgshapiro</dd> 50490792Sgshapiro</dl> 50590792Sgshapiro<p></p> 50690792Sgshapiro<hr> 50790792Sgshapiro<p></p> 50890792Sgshapiro<h2> 50990792Sgshapiro<a name="writefunctions"> 51090792SgshapiroWriting Functions for a File Type 51190792Sgshapiro</a> 51290792Sgshapiro</h2> 51390792Sgshapiro<p> 51490792SgshapiroWhen writing functions to create a file type a function needs to 51590792Sgshapirobe created for each function vector in the SM_FILE_T structure 51690792Sgshapirothat will be passed to <tt>sm_io_open()</tt> or <tt>sm_io_setinfo()</tt>. 51790792SgshapiroOtherwise the setting will be rejected and <i>errno</i> set to EINVAL. 51890792SgshapiroEach function should accept and handle the number and types of arguments as 51990792Sgshapirodescribed in the portion of the SM_FILE_T structure shown below: 52090792Sgshapiro</p> 52190792Sgshapiro<pre> 52290792Sgshapiro int (*open) __P((SM_FILE_T *fp, const void *, int flags, 52390792Sgshapiro const void *rpool)); 52490792Sgshapiro int (*close) __P((SM_FILE_T *fp)); 52590792Sgshapiro int (*read) __P((SM_FILE_T *fp, char *buf, size_t size)); 52690792Sgshapiro int (*write) __P((SM_FILE_T *fp, const char *buf, size_t size)); 52790792Sgshapiro off_t (*seek) __P((SM_FILE_T *fp, off_t offset, int whence)); 52890792Sgshapiro int (*getinfo) __P((SM_FILE_T *fp, int what, void *valp)); 52990792Sgshapiro int (*setinfo) __P((SM_FILE_T *fp, int what, void *valp)); 53090792Sgshapiro</pre> 53190792Sgshapiro<p> 53290792SgshapiroThe macro SM_IO_SET_TYPE should be used to initialized an SM_FILE_T as a file 53390792Sgshapirotype for an <tt>sm_io_open()</tt>: 53490792Sgshapiro<menu> 53590792Sgshapiro<pre> 53690792SgshapiroSM_IO_SET_TYPE(type, name, open, close, read, write, seek, get, set, timeout) 53790792Sgshapiro</pre> 53890792Sgshapiro<br> 53990792Sgshapirowhere: 54090792Sgshapiro<menu> 54190792Sgshapiro<li> 54290792Sgshapirotype - is the SM_FILE_T being filled-in 54390792Sgshapiro</li> 54490792Sgshapiro<li> 54590792Sgshapironame - a human readable character string for human identification purposes 54690792Sgshapiro</li> 54790792Sgshapiro<li> 54890792Sgshapiroopen - the vector to the open function 54990792Sgshapiro</li> 55090792Sgshapiro<li> 55190792Sgshapiroclose - the vector to the close function 55290792Sgshapiro</li> 55390792Sgshapiro<li> 55490792Sgshapiroread - the vector to the read function 55590792Sgshapiro</li> 55690792Sgshapiro<li> 55790792Sgshapirowrite - the vector to the write function 55890792Sgshapiro</li> 55990792Sgshapiro<li> 56090792Sgshapiroseek - the vector to the seek function 56190792Sgshapiro</li> 56290792Sgshapiro<li> 56390792Sgshapiroset - the vector to the set function 56490792Sgshapiro</li> 56590792Sgshapiro<li> 56690792Sgshapiroget - the vector to the get function 56790792Sgshapiro</li> 56890792Sgshapiro<li> 56990792Sgshapirotimeout - the default to be used for a timeout when SM_TIME_DEFAULT specified 57090792Sgshapiro</li> 57190792Sgshapiro</menu> 57290792Sgshapiro</menu> 57390792SgshapiroYou should avoid trying to change or use the other structure members of the 57490792SgshapiroSM_FILE_T. The file pointer content (internal structure members) of an active 57590792Sgshapirofile should only be set and observed with the "info" functions. 57690792SgshapiroThe two exceptions to the above statement are the structure members 57790792Sgshapiro<i>cookie</i> and <i>ival</i>. <i>Cookie</i> is of type <tt>void *</tt> 57890792Sgshapirowhile <i>ival</i> is of type <tt>int</tt>. These two structure members exist 57990792Sgshapirospecificly for your created file type to use. The <i>sm_io</i> functions 58090792Sgshapirowill not change or set these two structure members; only specific file type 58190792Sgshapirowill change or set these variables. 58290792Sgshapiro</p> 58390792Sgshapiro<p> 58490792SgshapiroFor maintaining information privately about status for a file type the 58590792Sgshapiroinformation should be encapsulated in a <i>cookie</i>. A <i>cookie</i> 58690792Sgshapirois an opaque type that contains information that is only known to 58790792Sgshapirothe file type layer itself. The <i>sm_io</i> package will know 58890792Sgshapironothing about the contents of the <i>cookie</i>; <i>sm_io</i> only 58990792Sgshapiromaintains the location of the <i>cookie</i> so that it may be passed 59090792Sgshapiroto the functions of a file type. It is up to the file type to 59190792Sgshapirodetermine what to do with the <i>cookie</i>. It is the responsibility 59290792Sgshapiroof the file type's open to create the cookie and point the SM_FILE_T's 59390792Sgshapiro<i>cookie</i> at the address of the cookie. 59490792SgshapiroIt is the responsibility of close to clean up 59590792Sgshapiroany resources that the cookie and instance of the file type have used. 59690792Sgshapiro</p> 59790792Sgshapiro<p> 59890792SgshapiroFor the <i>cookie</i> to be passed to all members of a function type 59990792Sgshapirocleanly the location of the cookie must assigned during 60090792Sgshapirothe call to open. The file type functions should not attempt to 60190792Sgshapiromaintain the <i>cookie</i> internally since the file type may have 60290792Sgshapiroserveral instances (file pointers). 60390792Sgshapiro</p> 60490792Sgshapiro<p> 60590792SgshapiroThe SM_FILE_T's member <i>ival</i> may be used in a manner similar to 60690792Sgshapiro<i>cookie</i>. It is not to be used for maintaining the file's offset 60790792Sgshapiroor access status (other members do that). It is intended as a "light" 60890792Sgshapiroreference. 60990792Sgshapiro</p> 61090792Sgshapiro<p> 61190792SgshapiroThe file type vector functions are called by the <tt>sm_io_*()</tt> 61290792Sgshapirofunctions after <i>sm_io</i> processing has occurred. The <i>sm_io</i> 61390792Sgshapiroprocessing validates SM_FILE_T's and may then handle the call entirely 61490792Sgshapiroitself or pass the request to the file type vector functions. 61590792Sgshapiro</p> 61690792Sgshapiro<p> 61790792SgshapiroAll of the "int" functions should return -1 (minus one) on failure 61890792Sgshapiroand 0 (zero) or greater on success. <i>Errno</i> should be set to 61990792Sgshapiroprovide diagnostic information to the caller if it has not already 62090792Sgshapirobeen set by another function the file type function used. 62190792Sgshapiro</p> 62290792Sgshapiro<p> 62390792SgshapiroExamples are a wonderful manner of clarifying details. Below is an example 62490792Sgshapiroof an open function. 62590792Sgshapiro</p> 62690792Sgshapiro<p> 62790792SgshapiroThis shows the setup. 62890792Sgshapiro<menu> 62990792Sgshapiro<pre> 63090792SgshapiroSM_FILE_T *fp; 63190792SgshapiroSM_FILE_T SM_IO_SET_TYPE(vector, "my_type", myopen, myclose, myread, mywrite, 63290792Sgshapiro myseek, myget, myset, SM_TIME_FOREVER); 63390792Sgshapiro 63490792Sgshapirofp = sm_io_open(&vector, 1000, "data", SM_IO_RDONLY, NULL); 63590792Sgshapiro 63690792Sgshapiroif (fp == NULL) 63790792Sgshapiro return(-1); 63890792Sgshapiro</pre> 63990792SgshapiroThe above code open's a file of type "my_type". The <i>info</i> is set 64090792Sgshapiroto a string "data". "data" may be the name of a file or have some special 64190792Sgshapiromeaning to the file type. For sake of the example, we will have it be 64290792Sgshapirothe name of a file in the home directory of the user running the program. 64390792SgshapiroNow the only file type function that is dependent on this information 64490792Sgshapirowill be the open function. 64590792Sgshapiro<br> 64690792SgshapiroWe have also specified read-only access (SM_IO_RDONLY) and that no <i>rpool</i> 64790792Sgshapirowill be used. The <i>timeout</i> has been set to 1000 milliseconds which 64890792Sgshapirodirects that the file and all associated setup should be done within 64990792Sgshapiro1000 milliseconds or return that the function erred (with errno==EAGAIN). 65090792Sgshapiro<pre> 65190792Sgshapiroint myopen(fp, info, flags, rpools) 65290792Sgshapiro SM_FILE_T *fp; 65390792Sgshapiro const void *info; 65490792Sgshapiro int flags; 65590792Sgshapiro void *rpool; 65690792Sgshapiro{ 65790792Sgshapiro /* 65890792Sgshapiro ** now we could do the open raw (i.e with read(2)), but we will 65990792Sgshapiro ** use file layering instead. We will use the <i>stdio</i> file 66090792Sgshapiro ** type (different than the system's stdio). 66190792Sgshapiro */ 66290792Sgshapiro struct passwd *pw; 66390792Sgshapiro char path[PATH_MAX]; 66490792Sgshapiro 66590792Sgshapiro pw = getpwuid(getuid()); 66690792Sgshapiro sm_io_snprintf(path, PATH_MAX, "%s/%s", pw->pw_dir, info); 66790792Sgshapiro 66890792Sgshapiro /* 66990792Sgshapiro ** Okay. Now the path pass-in has been prefixed with the 67090792Sgshapiro ** user's HOME directory. We'll call the regular stdio (SmFtStdio) 67190792Sgshapiro ** now to handle the rest of the open. 67290792Sgshapiro */ 67390792Sgshapiro fp->cookie = sm_io_open(SmFtStdio, path, flags, rpools); 67490792Sgshapiro if (fp->cookie == NULL) 67590792Sgshapiro return(-1) /* errno set by sm_io_open call */ 67690792Sgshapiro else 67790792Sgshapiro return(0); 67890792Sgshapiro} 67990792Sgshapiro</pre> 68090792SgshapiroLater on when a write is performed the function <tt>mywrite</tt> will 68190792Sgshapirobe invoked. To match the above <tt>myopen</tt>, <tt>mywrite</tt> could 68290792Sgshapirobe written as: 68390792Sgshapiro<pre> 68490792Sgshapiroint mywrite(fp, buf, size) 68590792Sgshapiro SM_FILE_T *fp; 68690792Sgshapiro char *buf; 68790792Sgshapiro size_t size; 68890792Sgshapiro{ 68990792Sgshapiro /* 69090792Sgshapiro ** As an example, we can change, modify, refuse, filter, etc. 69190792Sgshapiro ** the content being passed through before we ask the SmFtStdio 69290792Sgshapiro ** to do the actual write. 69390792Sgshapiro ** This example is very simple and contrived, but this keeps it 69490792Sgshapiro ** clear. 69590792Sgshapiro */ 69690792Sgshapiro if (size == 0) 69790792Sgshapiro return(0); /* why waste the cycles? */ 69890792Sgshapiro if (*buf == 'X') 69990792Sgshapiro *buf = 'Y'; 70090792Sgshapiro 70190792Sgshapiro /* 70290792Sgshapiro ** Note that the file pointer passed to the next level is the 70390792Sgshapiro ** one that was stored in the cookie during the open. 70490792Sgshapiro */ 70590792Sgshapiro return(sm_io_write(fp->cookie, buf, size)); 70690792Sgshapiro} 70790792Sgshapiro</pre> 70890792SgshapiroAs a thought-exercise for the fair reader: how would you modify the 70990792Sgshapiroabove two functions to make a "tee". That is the program will call 71090792Sgshapiro<tt>sm_io_open</tt> or <tt>sm_io_write</tt> and two or more files will 71190792Sgshapirobe opened and written to. (Hint: create a cookie to hold two or more 71290792Sgshapirofile pointers). 71390792Sgshapiro</menu> 71490792Sgshapiro</p> 71590792Sgshapiro<p></p> 71690792Sgshapiro<hr> 71790792Sgshapiro<br> 71890792Sgshapiro<hr> 71990792Sgshapiro<p></p> 72090792Sgshapiro<center> 72190792Sgshapiro<h1> 72290792Sgshapiro<a name="defaultapi"> 72390792Sgshapirolibsm sm_io default API definition 72490792Sgshapiro</a> 72590792Sgshapiro</h1> 72690792Sgshapiro</center> 72790792Sgshapiro<h2> Introduction </h2> 72890792Sgshapiro<p> 72990792SgshapiroA number of <i>sm_io</i> API's perform similar to their <i>stdio</i> 73090792Sgshapirocounterparts (same name as when the "sm_io_" is removed). 73190792SgshapiroOne difference between <i>sm_io</i> and <i>stdio</i> functions is that 73290792Sgshapiroif a "file pointer" (FILE/SM_FILE_T) 73390792Sgshapirois one of the arguments for the function, then it is now the first 73490792Sgshapiroargument. <i>Sm_io</i> is standardized so that when a file pointer is 73590792Sgshapiroone of the arguments to function then it will always be the first 73690792Sgshapiroarguement. Many of the <i>sm_io</i> function take a <i>timeout</i> 73790792Sgshapiroargument (see <a href="#timeouts"><b>Timeouts</b></a>). 73890792Sgshapiro</p> 73990792Sgshapiro<p> 74090792SgshapiroThe API you have selected is one of these. Please consult the 74190792Sgshapiroappropriate <i>stdio</i> man page for now. 74290792Sgshapiro</p> 74390792Sgshapiro 74490792Sgshapiro</body> 74590792Sgshapiro</html> 746