"Fossies" - the Fresh Open Source Software Archive

Member "sendmail-8.15.2/libsm/io.html" (5 Mar 2014, 27260 Bytes) of package /linux/misc/sendmail.8.15.2.tar.gz:

As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) HTML source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    1 <html>
    2 <head>
    3 <title>libsm sm_io general overview</title>
    4 </head>
    5 <body>
    6 <a href="index.html">Back to libsm overview</a>
    7 <center>
    8 <h1>libsm sm_io general overview</h1>
    9 <br> $Id: io.html,v 1.3 2001-03-17 03:22:50 gshapiro Exp $
   10 </center>
   11 <h2> Introduction </h2>
   12 <p>
   13 The <i>sm_io</i> portion of the <i>libsm</i> library is similar to
   14 the <i>stdio</i> library. It is derived from the Chris Torek version
   15 of the <i>stdio</i> library (BSD). There are some key differences
   16 described below between <i>sm_io</i> and <i>stdio</i> but many
   17 similarities will be noticed.
   18 </p>
   19 <p>
   20 A key difference between <i>stdio</i> and <i>sm_io</i> is that the
   21 functional code that does the open, close, read, write, etc. on a file
   22 can be different for different files. For example, with <i>stdio</i>
   23 the functional code (read, write) is either the default supplied in the
   24 library or a "programmer specified" set of functions set via
   25 <i>sm_io_open()</i>. Whichever set of functions are specified <b>all</b>
   26 open's, read's, write's, etc use the same set of functions. In contrast, with
   27 <i>sm_io</i> a different set of functions can be specified with each
   28 active file for read's, write's, etc. These different function sets
   29 are identified as <b>file types</b> (see <tt>sm_io_open()</tt>). Each function
   30 set can handle the actions directly, pass the action request to
   31 another function set or do some work before passing it on to another function
   32 set. The setting of a function set for a file type can be done for
   33 a file type at any time (even after the type is open).
   34 </p>
   35 <p>
   36 A second difference is the use of <a href="rpool.html"><b>rpools</b></a>.
   37 An <b>rpool</b> is specified with the opening of a file
   38 (<tt>sm_io_open()</tt>).
   39 This allows of a file to be associated with an rpool so that when the
   40 rpool is released the open file will be closed; the <tt>sm_io_open()</tt>
   41 registers that <tt>sm_io_close()</tt> should be called when the rpool is
   42 released.
   43 </p>
   44 <p>
   45 A third difference is that the I/O functions take a <i>timeout</i>
   46 argument. This allows the setting of a maximum amount of time allowable
   47 for the I/O to be completed. This means the calling program does not need
   48 to setup it's own timeout mechanism. NOTE: SIGALRM's should not be
   49 active in the calling program when an I/O function with a <i>timeout</i>
   50 is used.
   51 </p>
   52 <p>
   53 When converting source code from <i>stdio</i> to <i>sm_io</i> be
   54 very careful to NOTE: the arguments to functions have been rationalized.
   55 That is, unlike <i>stdio</i>, all <i>sm_io</i> functions that
   56 take a file pointer (SM_FILE_T *) argument have the file pointer
   57 as the first argument. Also not all functions with <i>stdio</i> have
   58 an identical matching <i>sm_io</i> API: the API list has been thinned
   59 since a number of <i>stdio</i> API's overlapped in functionality.
   60 Remember many functions also have a <i>timeout</i> argument added.
   61 </p>
   62 <p>
   63 When a file is going to be opened, the file type is included with
   64 <tt>sm_io_open()</tt>.
   65 A file type is either one automatically included with the <i>sm_io</i>
   66 library or one created by the program at runtime.
   67 File types can be either buffered or unbuffered. When buffered the buffering
   68 is either the builtin <i>sm_io</i> buffering or as done by the file type.
   69 File types can be disk files, strings, TCP/IP connections or whatever
   70 your imagination can come up with that can be read and/or written to.
   71 </p>
   72 <p>
   73 Information about a particular file type or pointer can be obtained or set with
   74 the <i>sm_io</i> "info" functions.
   75 The <tt>sm_io_setinfo()</tt> and <tt>sm_io_getinfo()</tt> functions work on
   76 an active file pointer.
   77 </p>
   78 <h2>Include files</h2>
   79 <p>
   80 There is one main include file for use with sm_io: <i>io.h</i>. Since the
   81 use of <b>rpools</b> is specified with <tt>sm_io_open()</tt> an
   82 <b>rpool</b> may
   83 be created and thus <i>rpool.h</i> may need to be included as well
   84 (before io.h).
   85 </p>
   86 <pre>
   87 #include &lt;rpool.h&gt;
   88 #include &lt;io.h&gt;
   89 </pre>
   91 <h2>Functions/API's</h2>
   92 <p>
   93 Below is a list of the functions for <i>sm_io</i> listed in
   94 alphabetical order. Currently these functions return error codes
   95 and set errno when appropriate. These (may?/will?) change to
   96 raising exceptions later.
   97 </p>
   98 <pre>
   99 <a href="#sm_io_autoflush">SM_FILE_T *sm_io_autoflush(SM_FILE_T *fp, SM_FILE_T *)</a>
  101 <a href="#sm_io_automode">void sm_io_automode(SM_FILE_T *fp, SM_FILE_T *)</a>
  103 <a href="#defaultapi">void sm_io_clearerr(SM_FILE_T *fp)</a>
  105 <a href="#sm_io_close">int sm_io_close(SM_FILE_T *fp, int timeout)</a>
  107 <a href="#defaultapi">int sm_io_dup(SM_FILE_T *fp)</a>
  109 <a href="#defaultapi">int sm_io_eof(SM_FILE_T *fp)</a>
  111 <a href="#defaultapi">int sm_io_error(SM_FILE_T *fp)</a>
  113 <a href="#defaultapi">char * sm_io_fgets(SM_FILE_T *fp, int timeout, char *buf, int n)</a>
  115 <a href="#defaultapi">int sm_io_flush(SM_FILE_T *fp, int timeout)</a>
  117 <a href="#sm_io_fopen">int sm_io_fopen(char *pathname, int flags [, MODE_T mode])</a>
  119 <a href="#defaultapi">int sm_io_fprintf(SM_FILE_T *fp, int timeout, const char *fmt, ...)</a>
  121 <a href="#defaultapi">int sm_io_fputs(s, int, SM_FILE_T *fp)</a>
  123 <a href="#defaultapi">int sm_io_fscanf(SM_FILE_T *fp, int timeout, char const *fmt, ...) </a>
  125 <a href="#defaultapi">int sm_io_getc(SM_FILE_T *fp, int timeout)</a>
  127 <a href="#sm_io_getinfo">void sm_io_getinfo(SM_FILE_T *sfp, int what, void *valp)</a>
  129 <a href="#sm_io_open">SM_FILE_T * sm_io_open(SM_FILE_T type, int timeout, void *info, int flags, void *rpool)</a>
  131 <a href="#defaultapi">int sm_io_purge(SM_FILE_T *fp)</a>
  133 <a href="#defaultapi">int sm_io_putc(SM_FILE_T *fp, int timeout, int c)</a>
  135 <a href="#defaultapi">size_t sm_io_read(SM_FILE_T *fp, int timeout, char *buf, size_t size)</a>
  137 <a href="#sm_io_reopen">SM_FILE_T * sm_io_open(SM_FILE_T type, int timeout, void *info, int flags, void *rpool)</a>
  139 <a href="#defaultapi">void sm_io_rewind(SM_FILE_T *fp, int timeout)</a>
  141 <a href="#defaultapi">int sm_io_seek(SM_FILE_T *fp, off_t offset, int timeout, int whence)</a>
  143 <a href="#sm_io_setinfo">void sm_io_setinfo(SM_FILE_T *sfp, int what, void *valp)</a>
  145 <a href="#defaultapi">int sm_io_setvbuf(SM_FILE_T *fp, int timeout, char *buf, int mode, size_t size)</a>
  147 <a href="#defaultapi">int sm_io_sscanf(const char *str, char const *fmt, ...)</a>
  149 <a href="#defaultapi">long sm_io_tell(SM_FILE_T *fp, int timeout)</a>
  151 <a href="#defaultapi">int sm_io_ungetc(SM_FILE_T *fp, int timeout, int c)</a>
  153 <a href="#defaultapi">size_t sm_io_write(SM_FILE_T *fp, int timeout, char *buf, size_t size)</a>
  155 <a href="#defaultapi">int sm_snprintf(char *str, size_t n, char const *fmt, ...)</a>
  157 </pre>
  158 <a name="timeouts">
  159 <h2>Timeouts</h2>
  160 <p>
  161 For many of the functions a <i>timeout</i> argument is given. This limits
  162 the amount of time allowed for the function to complete. There are three
  163 pre-defined values:
  164 <menu>
  165 <li>
  166 SM_TIME_DEFAULT - timeout using the default setting for this file type
  167 </li>
  168 <li>
  169 SM_TIME_FOREVER - timeout will take forever; blocks until task completed
  170 </li>
  171 <li>
  172 SM_TIME_IMMEDIATE - timeout (virtually) now
  173 </li>
  174 </menu>
  175 </p>
  176 <p>
  177 A function caller can also specify a positive integer value in milliseconds.
  178 A function will return with <i>errno</i> set to EINVAL if a bad value
  179 is given for <i>timeout</i>.
  180 When a function times out the function returns in error with <i>errno</i>
  181 set to <b>EAGAIN</b>. In the future this may change to an exception being
  182 thrown.
  183 </p>
  184 <h2>Function Descriptions</h2>
  185 <dl>
  186 <!-- SM_IO_FOPEN -->
  187 <p></p>
  188 <dt><tt><a name="sm_io_fopen">
  189 SM_FILE_T *
  190 <br>
  191 sm_io_fopen(char *pathname, int flags)
  192 <br>
  193 SM_FILE_T *
  194 <br>
  195 sm_io_fopen(char *pathname, int flags, MODE_T mode)
  196 </a></tt></dt>
  197 <dd>
  198 Open the file named by <tt>pathname</tt>, and associate a stream with it.
  199 The arguments are the same as for the <tt>open(2)</tt> system call.
  200 <br>
  201 If memory could not be allocated, an exception is raised.
  202 If successful, an <tt>SM_FILE_T</tt> pointer is returned.
  203 Otherwise, <tt>NULL</tt> is returned and <tt>errno</tt> is set.
  204 <!-- SM_IO_OPEN -->
  205 <p></p>
  206 <dt><tt><a name="sm_io_open">
  207 SM_FILE_T *
  208 <br>
  209 sm_io_open(const SM_FILE_T *type, int timeout, const void *info, int flags, void *rpool)
  210 </a></tt></dt>
  211 <dd>
  212 Opens a file by <i>type</i> directed by <i>info</i>. <i>Type</i> is a filled-in
  213 SM_FILE_T structure from the following builtin list
  214 (<a href="#builtins"><b>descriptions below</b></a>)
  215 or one specified by the program. 
  216 <menu>
  217 <li>
  218 SmFtString
  219 </li>
  220 <li>
  221 SmFtStdio
  222 </li>
  223 <li>
  224 SmFtStdiofd
  225 </li>
  226 <li>
  227 smioin <b>*</b>
  228 </li>
  229 <li>
  230 smioout <b>*</b>
  231 </li>
  232 <li>
  233 smioerr <b>*</b>
  234 </li>
  235 <li>
  236 smiostdin <b>*</b>
  237 </li>
  238 <li>
  239 smiostdout <b>*</b>
  240 </li>
  241 <li>
  242 smiostderr <b>*</b>
  243 </li>
  244 <li>
  245 SmFtSyslog
  246 </li>
  247 </menu>
  248 <br>
  249 The above list of file types are already appropriately filled in. Those marked
  250 with a "<b>*</b>" are already open and may be used directly and immediately.
  251 For program specified types, to set the <i>type</i> argument easily and with minimal error the macro
  252 <b>SM_IO_SET_TYPE</b> should be used. The SM_FILE_T structure is fairly
  253 large, but only a small portion of it need to be initialized for a new
  254 type.
  255 See also <a href="#writefunctions">"Writing Functions for a File Type"</a>.
  256 <menu>
  257 <pre>
  258 SM_IO_SET_TYPE(type, name, open, close, read, write, seek, get, set, timeout)
  259 </pre>
  260 </menu>
  261 <br>
  262 <i>Timeout</i> is set as described in the <a href="#timeouts"><b>Timeouts</b></a>
  263 section.
  264 <br>
  265 <i>Info</i> is information that describes for the file type what is
  266 to be opened and any associated information.
  267 For a disk file this would be a file path; with a TCP
  268 connection this could be an a structure containing an IP address and port.
  269 <br><i>Flags</i> is a
  270 set of sm_io flags that describes how the file is to be interacted with:
  271 <menu>
  272 <li>
  273 SM_IO_RDWR  - read and write
  274 </li>
  275 <li>
  276 SM_IO_RDONLY    - read only
  277 </li>
  278 <li>
  279 SM_IO_WRONLY    - write only
  280 </li>
  281 <li>
  282 SM_IO_APPEND    - allow write to EOF only
  283 </li>
  284 <li>
  285 SM_IO_APPENDRW  - allow read-write from EOF only
  286 </li>
  287 <li>
  288 SM_IO_RDWRTR    - read and write with truncation of file first
  289 </li>
  290 </menu>
  291 <i>Rpool</i> is the address of the rpool that this open is to be associated
  292 with. When the rpool is released then the close function for this
  293 file type will be automatically called to close the file for cleanup.
  294 If NULL is specified for <i>rpool</i> then the close function is not
  295 associated (attached) to an rpool.
  296 <br>
  297 On cannot allocate memory, an exception is raised.
  298 If the <i>type</i> is invalid, <tt>sm_io_open</tt> will abort the process.
  299 On success an SM_FILE_T * pointer is returned.
  300 On failure the NULL pointer is returned and errno is set.
  301 </dd>
  302 <!-- SM_IO_SETINFO -->
  303 <p></p>
  304 <dt><tt><a name="sm_io_setinfo">
  305 int
  306 <br>
  307 sm_io_setinfo(SM_FILE_T *sfp, int what, void *valp)
  308 </a></tt></dt>
  309 <dd>
  310 For the open file <i>sfp</i> set the indicated information (<i>what</i>)
  311 to the new value <i>(valp</i>).
  312 This will make the change for this SM_FILE_T only. The file
  313 type that <i>sfp</i> originally belonged to will still be
  314 configured the same way (this is to prevent side-effect
  315 to other open's of the same file type, particularly with threads).
  316 The value of <i>what</i> will be file-type dependant since this function
  317 is one of the per file type setable functions.
  318 One value for <i>what</i> that is valid for all file types is
  319 SM_WHAT_VECTORS. This sets the currently open file with a new function
  320 vector set for open, close, etc. The new values are taken from <i>valp</i>
  321 a SM_FILE_T filled in by the used via the macro SM_IO_SET_TYPE
  322 (see and <a href="#writefunctions">
  323 "Writing Functions for a File Type"</a> for more information).
  324 <br>
  325 On success 0 (zero) is returned. On failure -1 is returned and errno is set.
  326 </dd>
  327 <!-- SM_IO_GETINFO -->
  328 <p></p>
  329 <dt><tt><a name="sm_io_getinfo">
  330 int
  331 <br>
  332 sm_io_getinfo(SM_FILE_T *sfp, int what, void *valp)
  333 </a></tt></dt>
  334 <dd>
  335 For the open file <i>sfp</i> get the indicated information (<i>what</i>)
  336 and place the result in <i>(valp</i>).
  337 This will obtain information for SM_FILE_T only and may be different than
  338 the information for the file type it was originally opened as.
  339 The value of <i>what</i> will be file type dependant since this function
  340 is one of the per file type setable functions.
  341 One value for <i>what</i> that is valid for all file types is
  342 SM_WHAT_VECTORS. This gets from the currently open file a copy of
  343 the function vectors and stores them in <i>valp</i> a SM_FILE_T
  344 (see <a href="#writefunctions">
  345 "Writing Functions for a File Type"</a> for more information).
  346 <br>
  347 On success 0 (zero) is returned. On failure -1 is returned and errno is set.
  348 </dd>
  349 <!-- SM_IO_AUTOFLUSH -->
  350 <p></p>
  351 <dt><tt><a name="sm_io_autoflush">
  352 void
  353 <br>
  354 sm_io_autoflush(SM_FILE_T *fp1, *SM_FILE_T fp2)
  355 </a></tt></dt>
  356 <dd>
  357 Associate a read of <i>fp1</i> with a data flush for <i>fp2</i>. If a read
  358 of <i>fp1</i> discovers that there is no data available to be read, then
  359 <i>fp2</i> will have it's data buffer flushed for writable data. It is
  360 assumed that <i>fp1</i> is open for reading and <i>fp2</i> is open
  361 for writing.
  362 <br>
  363 On return the old file pointer associated with <i>fp1</i> for flushing
  364 is returned. A return of NULL is no an error; this merely indicates no
  365 previous association.
  366 </dd>
  367 <!-- SM_IO_AUTOMODE -->
  368 <p></p>
  369 <dt><tt><a name="sm_io_automode">
  370 void
  371 <br>
  372 sm_io_automode(SM_FILE_T *fp1, *SM_FILE_T fp2)
  373 <dt><tt><a name="sm_io_automode">
  374 </a></tt></dt>
  375 <dd>
  376 Associate the two file pointers for blocking/non-blocking mode changes.
  377 In the handling of timeouts <i>sm_io</i> may need to switch the mode of
  378 a file between blocking and non-blocking. If the underlying file descriptor
  379 has been duplicated with <tt>dup(2)</tt> and these descriptors are used
  380 by <i>sm_io</i> (for example with an SmFtStdiofd file type), then this API
  381 should be called to associate them. Otherwise odd behavior (i.e. errors)
  382 may result that is not consistently reproducable nor easily identifiable.
  383 </dd>
  384 <!-- SM_IO_CLOSE -->
  385 <p></p>
  386 <dt><tt><a name="sm_io_close">
  387 int
  388 <br>
  389 sm_io_close(SM_FILE_T *sfp, int timeout)
  390 </a></tt></dt>
  391 <dd>
  392 Release all resources (file handles, memory, etc.) associated with
  393 the open SM_FILE_T <i>sfp</i>. If buffering is active then the
  394 buffer is flushed before any resources are released.
  395 <i>Timeout</i> is set as described in the <a href="#timeouts"><b>Timeouts</b></a>
  396 section.
  397 The first resources released after buffer flushing will be the
  398 buffer itself. Then the <b>close</b> function specified in the
  399 file type at open will be called. It is the responsibility
  400 of the <b>close</b> function to release any file type
  401 specific resources allocated and to call <tt>sm_io_close()</tt>
  402 for the next file type layer(s) that the current file type uses (if any).
  403 <br>
  404 On success 0 (zero) is returned. On failure SM_IO_EOF is returned and
  405 errno is set.
  406 </dd>
  407 </dl>
  408 <h2>
  409 <a name="builtins">Description of Builtin File Types</a>
  410 </h2>
  411 <p>
  412 There are several builtin file types as mentioned in <tt>sm_io_open()</tt>.
  413 More file types may be added later.
  414 </p>
  415 <dl>
  416 <p></p>
  417 <dt><tt>SmFtString</tt></dt>
  418 <dd>
  419 Operates on a character string. <i>SmFtString</i> is a file type only.
  420 The string starts at the location 0 (zero)
  421 and ends at the last character. A read will obtain the requested
  422 number of characters if available; else as many as possible. A read
  423 will not terminate the read characters with a NULL ('\0'). A write
  424 will place the number of requested characters at the current location.
  425 To append to a string either the pointer must currently be at the end
  426 of the string or a seek done to position the pointer. The file type
  427 handles the space needed for the string. Thus space needed for the
  428 string will be grown automagically without the user worrying about
  429 space management.
  430 </dd>
  431 <dt><tt>SmFtStdio</tt></dt>
  432 <dd>
  433 A predefined SM_FILE_T structure with function vectors pointing to
  434 functions that result in the file-type behaving as the system stdio
  435 normally does. The <i>info</i> portion of the <tt>sm_io_open</tt>
  436 is the path of the file to be opened. Note that this file type
  437 does not interact with the system's stdio. Thus a program mixing system
  438 stdio and sm_io stdio (SmFtStdio) will result in uncoordinated input
  439 and output.
  440 </dd>
  441 <dt><tt>SmFtStdiofd</tt></dt>
  442 <dd>
  443 A predefined SM_FILE_T structure with function vectors pointing to
  444 functions that result in the file-type behaving as the system stdio
  445 normally does. The <i>info</i> portion of the <tt>sm_io_open</tt>
  446 is a file descriptor (the value returned by open(2)).  Note that this file type
  447 does not interact with the system's stdio. Thus a program mixing system
  448 stdio and sm_io stdio (SmFtStdio) will result in uncoordinated input
  449 and output.
  450 </dd>
  451 <dt><tt>smioin</tt></dt>
  452 <dt><tt>smioout</tt></dt>
  453 <dt><tt>smioerr</tt></dt>
  454 <dd>
  455 The three types <i>smioin</i>, <i>smioout</i> and <i>smioerr</i> are grouped
  456 together. These three types
  457 perform in the same manner as <b>stdio</b>'s <i>stdin</i>, <i>stdout</i>
  458 and <i>stderr</i>.  These types are both the names and the file pointers.
  459 They are already open when a program starts (unless the parent explictly
  460 closed file descriptors 0, 1 and 2).
  461 Thus <tt>sm_io_open()</tt> should never be called for these types:
  462 the named file pointers should be used directly.
  463 <i>Smioin</i> and <i>smioout</i> are buffered
  464 by default. <i>Smioerr</i> is not buffered by default. Calls to <b>stdio</b>
  465 are safe to make when using these three<b>sm_io</b> file pointers.
  466 There is no interaction between <b>sm_io</b> and <b>stdio</b>. Hence,
  467 due to buffering, the sequence of input and output data from both <b>sm_io</b>
  468 and <b>stdio</b> at the same time may appear unordered. For
  469 coordination between <b>sm_io</b> and <b>stdio</b> use the three
  470 file pointers below (<i>smiostdin, smiostdout, smiostderr</i>).
  471 </dd>
  472 <dt><tt>smiostdin</tt></dt>
  473 <dt><tt>smiostdout</tt></dt>
  474 <dt><tt>smiostderr</tt></dt>
  475 <dd>
  476 The three types <i>smiostdin</i>, <i>smioostdut</i> and <i>smiostderr</i>
  477 are grouped together. These three types
  478 perform in the same manner as <b>stdio</b>'s <i>stdin</i>, <i>stdout</i>
  479 and <i>stderr</i>.  These types are both the names and file pointers.
  480 They are already open when a program starts (unless the parent explictly
  481 close file descriptors 0, 1 and 2).
  482 Thus <tt>sm_io_open()</tt> should
  483 never be called: the named file pointers should be used directly.
  484 Calls to <b>stdio</b> are safe to make when using these three<b>sm_io</b>
  485 file pointers though no code is shared between the two libaries.
  486 However, the input and output between <i>sm_io</i> and <i>stdio</i> is
  487 coordinated for these three file pointers: <i>smiostdin</i>,
  488 <i>smiostdout</i> and <i>smiostderr</i> are layered on-top-of
  489 the system's <i>stdio</i>.
  490 <i>Smiostdin</i>, <i>smiostdout</i>
  491 and <i>Smiostderr</i> are not buffered by default.
  492 Hence, due to buffering in <i>stdio</i> only, the sequence of input and
  493 output data from both <b>sm_io</b> and <b>stdio</b> at the same time will
  494 appear ordered. If <i>sm_io</i> buffering is turned on then the
  495 input and output can appear unordered or lost.
  496 </dd>
  497 <dt><tt>SmFtSyslog</tt></dt>
  498 <dd>
  499 This opens the channel to the system log. Reads are not allowed. Writes
  500 cannot be undone once they have left the <i>sm_io</i> buffer.
  501 The man pages for <tt>syslog(3)</tt> should be read for information
  502 on syslog.
  503 </dd>
  504 </dl>
  505 <p></p>
  506 <hr>
  507 <p></p>
  508 <h2>
  509 <a name="writefunctions">
  510 Writing Functions for a File Type
  511 </a>
  512 </h2>
  513 <p>
  514 When writing functions to create a file type a function needs to
  515 be created for each function vector in the SM_FILE_T structure
  516 that will be passed to <tt>sm_io_open()</tt> or <tt>sm_io_setinfo()</tt>.
  517 Otherwise the setting will be rejected and <i>errno</i> set to EINVAL.
  518 Each function should accept and handle the number and types of arguments as
  519 described in the portion of the SM_FILE_T structure shown below:
  520 </p>
  521 <pre>
  522         int      (*open) __P((SM_FILE_T *fp, const void *, int flags,
  523                               const void *rpool));
  524         int      (*close) __P((SM_FILE_T *fp));
  525         int      (*read)  __P((SM_FILE_T *fp, char *buf, size_t size));
  526         int      (*write) __P((SM_FILE_T *fp, const char *buf, size_t size));
  527         off_t    (*seek)  __P((SM_FILE_T *fp, off_t offset, int whence));
  528         int      (*getinfo) __P((SM_FILE_T *fp, int what, void *valp));
  529         int      (*setinfo) __P((SM_FILE_T *fp, int what, void *valp));
  530 </pre>
  531 <p>
  532 The macro SM_IO_SET_TYPE should be used to initialized an SM_FILE_T as a file
  533 type for an <tt>sm_io_open()</tt>:
  534 <menu>
  535 <pre>
  536 SM_IO_SET_TYPE(type, name, open, close, read, write, seek, get, set, timeout)
  537 </pre>
  538 <br>
  539 where:
  540 <menu>
  541 <li>
  542 type    - is the SM_FILE_T being filled-in
  543 </li>
  544 <li>
  545 name    - a human readable character string for human identification purposes
  546 </li>
  547 <li>
  548 open    - the vector to the open function
  549 </li>
  550 <li>
  551 close   - the vector to the close function
  552 </li>
  553 <li>
  554 read    - the vector to the read function
  555 </li>
  556 <li>
  557 write   - the vector to the write function
  558 </li>
  559 <li>
  560 seek    - the vector to the seek function
  561 </li>
  562 <li>
  563 set - the vector to the set function
  564 </li>
  565 <li>
  566 get - the vector to the get function
  567 </li>
  568 <li>
  569 timeout - the default to be used for a timeout when SM_TIME_DEFAULT specified
  570 </li>
  571 </menu>
  572 </menu>
  573 You should avoid trying to change or use the other structure members of the
  574 SM_FILE_T. The file pointer content (internal structure members) of an active
  575 file should only be set and observed with the "info" functions.
  576 The two exceptions to the above statement are the structure members
  577 <i>cookie</i> and <i>ival</i>. <i>Cookie</i> is of type <tt>void *</tt>
  578 while <i>ival</i> is of type <tt>int</tt>. These two structure members exist
  579 specificly for your created file type to use. The <i>sm_io</i> functions
  580 will not change or set these two structure members; only specific file type
  581 will change or set these variables.
  582 </p>
  583 <p>
  584 For maintaining information privately about status for a file type the
  585 information should be encapsulated in a <i>cookie</i>. A <i>cookie</i>
  586 is an opaque type that contains information that is only known to
  587 the file type layer itself. The <i>sm_io</i> package will know
  588 nothing about the contents of the <i>cookie</i>; <i>sm_io</i> only
  589 maintains the location of the <i>cookie</i> so that it may be passed
  590 to the functions of a file type. It is up to the file type to
  591 determine what to do with the <i>cookie</i>. It is the responsibility
  592 of the file type's open to create the cookie and point the SM_FILE_T's
  593 <i>cookie</i> at the address of the cookie.
  594 It is the responsibility of close to clean up
  595 any resources that the cookie and instance of the file type have used.
  596 </p>
  597 <p>
  598 For the <i>cookie</i> to be passed to all members of a function type
  599 cleanly the location of the cookie must assigned during
  600 the call to open. The file type functions should not attempt to
  601 maintain the <i>cookie</i> internally since the file type may have
  602 serveral instances (file pointers).
  603 </p>
  604 <p>
  605 The SM_FILE_T's member <i>ival</i> may be used in a manner similar to
  606 <i>cookie</i>. It is not to be used for maintaining the file's offset
  607 or access status (other members do that). It is intended as a "light"
  608 reference.
  609 </p>
  610 <p>
  611 The file type vector functions are called by the <tt>sm_io_*()</tt>
  612 functions after <i>sm_io</i> processing has occurred. The <i>sm_io</i>
  613 processing validates SM_FILE_T's and may then handle the call entirely
  614 itself or pass the request to the file type vector functions.
  615 </p>
  616 <p>
  617 All of the "int" functions should return -1 (minus one) on failure
  618 and 0 (zero) or greater on success. <i>Errno</i> should be set to
  619 provide diagnostic information to the caller if it has not already
  620 been set by another function the file type function used.
  621 </p>
  622 <p>
  623 Examples are a wonderful manner of clarifying details. Below is an example
  624 of an open function.
  625 </p>
  626 <p>
  627 This shows the setup.
  628 <menu>
  629 <pre>
  630 SM_FILE_T *fp;
  631 SM_FILE_T SM_IO_SET_TYPE(vector, "my_type", myopen, myclose, myread, mywrite,
  632                 myseek, myget, myset, SM_TIME_FOREVER);
  634 fp = sm_io_open(&vector, 1000, "data", SM_IO_RDONLY, NULL);
  636 if (fp == NULL)
  637     return(-1);
  638 </pre>
  639 The above code open's a file of type "my_type". The <i>info</i> is set
  640 to a string "data". "data" may be the name of a file or have some special
  641 meaning to the file type. For sake of the example, we will have it be
  642 the name of a file in the home directory of the user running the program.
  643 Now the only file type function that is dependent on this information
  644 will be the open function.
  645 <br>
  646 We have also specified read-only access (SM_IO_RDONLY) and that no <i>rpool</i>
  647 will be used. The <i>timeout</i> has been set to 1000 milliseconds which
  648 directs that the file and all associated setup should be done within
  649 1000 milliseconds or return that the function erred (with errno==EAGAIN).
  650 <pre>
  651 int myopen(fp, info, flags, rpools)
  652     SM_FILE_T *fp;
  653         const void *info; 
  654         int flags;
  655         void *rpool;
  656 {
  657     /*
  658     **  now we could do the open raw (i.e with read(2)), but we will
  659     **  use file layering instead. We will use the <i>stdio</i> file
  660     **  type (different than the system's stdio).
  661     */
  662     struct passwd *pw;
  663     char path[PATH_MAX];
  665     pw = getpwuid(getuid());
  666     sm_io_snprintf(path, PATH_MAX, "%s/%s", pw->pw_dir, info);
  668     /*
  669     **  Okay. Now the path pass-in has been prefixed with the
  670     **  user's HOME directory. We'll call the regular stdio (SmFtStdio)
  671     **  now to handle the rest of the open.
  672     */
  673     fp->cookie = sm_io_open(SmFtStdio, path, flags, rpools);
  674     if (fp->cookie == NULL)
  675         return(-1) /* errno set by sm_io_open call */
  676     else
  677         return(0);
  678 }
  679 </pre>
  680 Later on when a write is performed the function <tt>mywrite</tt> will
  681 be invoked. To match the above <tt>myopen</tt>, <tt>mywrite</tt> could
  682 be written as:
  683 <pre>
  684 int mywrite(fp, buf, size)
  685     SM_FILE_T *fp;
  686         char *buf;
  687         size_t size;
  688 {
  689     /*
  690     **  As an example, we can change, modify, refuse, filter, etc.
  691     **  the content being passed through before we ask the SmFtStdio
  692     **  to do the actual write.
  693     **  This example is very simple and contrived, but this keeps it
  694     **  clear.
  695     */
  696     if (size == 0)
  697         return(0); /* why waste the cycles? */
  698     if (*buf == 'X')
  699         *buf = 'Y';
  701     /*
  702     **  Note that the file pointer passed to the next level is the
  703     **  one that was stored in the cookie during the open.
  704     */
  705     return(sm_io_write(fp->cookie, buf, size));
  706 }
  707 </pre>
  708 As a thought-exercise for the fair reader: how would you modify the
  709 above two functions to make a "tee". That is the program will call
  710 <tt>sm_io_open</tt> or <tt>sm_io_write</tt> and two or more files will
  711 be opened and written to. (Hint: create a cookie to hold two or more
  712 file pointers).
  713 </menu>
  714 </p>
  715 <p></p>
  716 <hr>
  717 <br>
  718 <hr>
  719 <p></p>
  720 <center>
  721 <h1>
  722 <a name="defaultapi">
  723 libsm sm_io default API definition
  724 </a>
  725 </h1>
  726 </center>
  727 <h2> Introduction </h2>
  728 <p>
  729 A number of <i>sm_io</i> API's perform similar to their <i>stdio</i>
  730 counterparts (same name as when the "sm_io_" is removed).
  731 One difference between <i>sm_io</i> and <i>stdio</i> functions is that
  732 if a "file pointer" (FILE/SM_FILE_T)
  733 is one of the arguments for the function, then it is now the first
  734 argument. <i>Sm_io</i> is standardized so that when a file pointer is
  735 one of the arguments to function then it will always be the first
  736 arguement. Many of the <i>sm_io</i> function take a <i>timeout</i>
  737 argument (see <a href="#timeouts"><b>Timeouts</b></a>).
  738 </p>
  739 <p>
  740 The API you have selected is one of these. Please consult the
  741 appropriate <i>stdio</i> man page for now.
  742 </p>
  744 </body>
  745 </html>