OSSP CVS Repository

ossp - ossp-pkg/sio/BRAINSTORM/att-sfio.txt
Not logged in
[Honeypot]  [Browse]  [Directory]  [Home]  [Login
[Reports]  [Search]  [Ticket]  [Timeline
  [Raw

ossp-pkg/sio/BRAINSTORM/att-sfio.txt



SFIO(3)                                                   SFIO(3)


NNAAMMEE
       ssffiioo - safe/fast string/file input/output

SSYYNNOOPPSSIISS
       #include   <sfio.h>

   DDAATTAA TTYYPPEESS
       Void_t;
       Sfoff_t;
       Sflong_t;
       Sfulong_t;
       Sfdouble_t;

       Sfio_t;

       Sfdisc_t;
       ssize_t    (*Sfread_f)(Sfio_t*, Void_t*, size_t, Sfdisc_t*);
       ssize_t    (*Sfwrite_f)(Sfio_t*, const Void_t*, size_t, Sfdisc_t*);
       Sfoff_t    (*Sfseek_f)(Sfio_t*, Sfoff_t, int, Sfdisc_t*);
       int        (*Sfexcept_f)(Sfio_t*, int, Void_t*, Sfdisc_t*);

       Sffmt_t;
       int        (*Sffmtext_f)(Sfio_t*, Void_t*, Sffmt_t*);
       int        (*Sffmtevent_f)(Sfio_t*, int, Void_t*, Sffmt_t*);

       SFIO_VERSION

   BBIITT FFLLAAGGSS
       SF_STRING
       SF_READ
       SF_WRITE
       SF_APPEND
       SF_LINE
       SF_SHARE
       SF_PUBLIC
       SF_MALLOC
       SF_STATIC
       SF_IOCHECK
       SF_BUFCONST
       SF_WHOLE

   OOPPEENNIINNGG//CCLLOOSSIINNGG SSTTRREEAAMMSS
       Sfio_t*    sfnew(Sfio_t* f, Void_t* buf, size_t size, int fd, int flags);
       Sfio_t*    sfopen(Sfio_t* f, const char* string, const char* mode);
       Sfio_t*    sfpopen(Sfio_t* f, const char* cmd, const char* mode);
       Sfio_t*    sftmp(size_t size);
       int        sfclose(Sfio_t* f);

   IINNPPUUTT//OOUUTTPPUUTT OOPPEERRAATTIIOONNSS
       int        sfgetc(Sfio_t* f);
       int        sfputc(Sfio_t* f, int c);
       int        sfnputc(Sfio_t* f, int c, int n);
       int        sfungetc(Sfio_t* f, int c);




                          05 August 1999                        1





SFIO(3)                                                   SFIO(3)


       Sfulong_t  sfgetu(Sfio_t* f);
       int        sfputu(Sfio_t* f, Sfulong_t v);
       Sflong_t   sfgetl(Sfio_t* f);
       int        sfputl(Sfio_t* f, Sflong_t v);
       Sfdouble_t sfgetd(Sfio_t* f);
       int        sfputd(Sfio_t* f, Sfdouble_t v);

       char*      sfgetr(Sfio_t* f, int rsc, int type);
       ssize_t    sfputr(Sfio_t* f, const char* s, int rsc);
       Sfoff_t    sfmove(Sfio_t* fr, Sfio_t* fw, Sfoff_t n, int rsc);

       ssize_t    sfread(Sfio_t* f, Void_t* buf, size_t n);
       ssize_t    sfwrite(Sfio_t* f, const Void_t* buf, size_t n);
       Sfoff_t    sfseek(Sfio_t* f, Sfoff_t offset, int type);
       Void_t*    sfreserve(Sfio_t* f, ssize_t n, int lock);

   DDAATTAA FFOORRMMAATTTTIINNGG
       int        sfscanf(Sfio_t* f, const char* format, ...);
       int        sfsscanf(const char* s, const char* format, ...);
       int        sfvsscanf(const char* s, const char* format, va_list args);
       int        sfvscanf(Sfio_t* f, const char* format, va_list args);

       int        sfprintf(Sfio_t* f, const char* format, ...);
       char*      sfprints(const char* format, ...);
       int        sfsprintf(char* s, int n, const char* format, ...);
       int        sfvsprintf(char* s, int n, const char* format, va_list args);
       int        sfvprintf(Sfio_t* f, const char* format, va_list args);

       Sffmt_t;
       int        (*Sffmtext_f)(Sfio_t* f, Void_t* v, Sffmt_t* fe);
       int        (*Sffmtevent_f)(Sfio_t* f, int type, Void_t* v, Sffmt_t* fe);
       void       va_copy(va_list to, va_list fr);
       long       sffmtversion(Sffmt_t* fe, type);

   BBUUFFFFEERRIINNGG,, SSYYNNCCHHRROONNIIZZAATTIIOONN
       Void_t*    sfsetbuf(Sfio_t* f, Void_t* buf, size_t size);
       int        sfsync(Sfio_t* f);
       int        sfpoll(Sfio_t** flist, int n, int timeout);
       Sfio_t*    sfpool(Sfio_t* f, Sfio_t* poolf, int mode);
       int        sfpurge(Sfio_t* f);

   DDIISSCCIIPPLLIINNEE,, EEVVEENNTT HHAANNDDLLIINNGG
       Sfdisc_t*  sfdisc(Sfio_t* f, Sfdisc_t* disc);
       int        sfraise(Sfio_t* f, int type, Void_t* data);
       ssize_t    sfrd(Sfio_t* f, Void_t* buf, size_t n, Sfdisc_t* disc);
       ssize_t    sfwr(Sfio_t* f, const Void_t* buf, size_t n, Sfdisc_t* disc);
       Sfoff_t    sfsk(Sfio_t* f, Sfoff_t offset, int type, Sfdisc_t* disc);

   SSTTRREEAAMM CCOONNTTRROOLL
       int        sfset(Sfio_t* f, int flags, int i);
       int        sfsetfd(Sfio_t* f, int fd);
       Sfio_t*    sfstack(Sfio_t* base, Sfio_t* top);
       Sfio_t*    sfswap(Sfio_t* f1, Sfio_t* f2);




                          05 August 1999                        2





SFIO(3)                                                   SFIO(3)


   SSTTRREEAAMM IINNFFOORRMMAATTIIOONN
       Sfoff_t    sfsize(Sfio_t* f);
       Sfoff_t    sftell(Sfio_t* f);
       ssize_t    sfvalue(Sfio_t* f);
       int        sffileno(Sfio_t* f);

       int        sfstacked(Sfio_t* f);
       int        sfeof(Sfio_t* f);
       int        sferror(Sfio_t* f);
       int        sfclrerr(Sfio_t* f);
       int        sfclrlock(Sfio_t* f);

       int        sfnotify(void (*notify)(Sfio_t* f, int type, int fd));

   MMIISSCCEELLLLAANNEEOOUUSS FFUUNNCCTTIIOONNSS
       ssize_t    sfslen();
       int        sfulen(Sfulong_t v);
       int        sfllen(Sflong_t v);
       int        sfdlen(Sfdouble_t v);
       ssize_t    sfpkrd(int fd, Void_t* buf, size_t n,
                         int rsc, long tm, int peek);

   FFUULLLL SSTTRRUUCCTTUURREE SSFFIIOO__TT
       #include   <sfio_t.h>
       #define    SFNEW(buf,size,file,flags,disc)

   EEXXAAMMPPLLEE DDIISSCCIIPPLLIINNEESS
       int        sfdcdio(Sfio_t* f, size_t bufsize);
       int        sfdcdos(Sfio_t* f);
       int        sfdcfilter(Sfio_t* f, const char* cmd);
       int        sfdclzw(Sfio_t* f);
       int        sfdcseekable(Sfio_t* f);
       int        sfdcslow(Sfio_t* f);
       int        sfdcsubstream(Sfio_t* f, Sfio_t* parent,
                                Sfoff_t offset, Sfoff_t extent);
       int        sfdctee(Sfio_t* f, Sfio_t* tee);
       int        sfdcunion(Sfio_t* f, Sfio_t** array, int n);

   SSTTDDIIOO--CCOOMMPPAATTIIBBIILLIITTYY
       #include   <stdio.h>
       cc ... -lstdio -lsfio

DDEESSCCRRIIPPTTIIOONN
       Sfio  is  a  library  of  I/O functions to manage buffered
       streams.  Each Sfio stream is a _f_i_l_e _s_t_r_e_a_m,  representing
       a  file  (see open(2)), or a _s_t_r_i_n_g _s_t_r_e_a_m, representing a
       memory  segment.   Beyond  the  usual  I/O  operations  on
       streams,  Sfio  provides I/O disciplines for extended data
       processing, stream stacks for recursive stream processing,
       and  stream pools for automatic data synchronization.  The
       sfprintf()/sfscanf()  functions  allow   applications   to
       define  their  own formatting patterns as well as to rede-
       fine existing patterns.




                          05 August 1999                        3





SFIO(3)                                                   SFIO(3)


       A  discipline  defines  analogues  of  the  system   calls
       read(2),  write(2)  and  lseek(2).   Such  system calls or
       their discipline replacements are used to  process  stream
       data.  Henceforth, ``_s_y_s_t_e_m _c_a_l_l'' will mean a system call
       or its discipline replacement.

       A system call is said to cause an exception if its  return
       value  is  non-positive.   Unless  overridden by exception
       handlers (see sfdisc()), an interrupted system call (errno
       ==  EINTR on UNIX systems) will be automatically reinvoked
       to continue the ongoing operation.

       The buffer of a stream is typically a memory segment allo-
       cated  via malloc(3) or supplied by the application.  File
       streams may also use memory mapping (mmap(2)) if  that  is
       more efficient.  When memory mapping is used, the underly-
       ing file should not  be  truncated  while  the  stream  is
       active.   Memory  mapping  can  be turned off using sfset-
       buf().

       There are three _s_t_a_n_d_a_r_d _s_t_r_e_a_m_s: sfstdin for input  (file
       descriptor  0 on UNIX systems), sfstdout for normal output
       (file descriptor 1), and sfstderr for error  output  (file
       descriptor 2).



   DDAATTAA TTYYPPEESS
     VVooiidd__tt**
       This  defines  a type suitable to exchange data of unknown
       types between application and Sfio.   Void_t  is  a  macro
       defined as void for ANSI-C and C++ and char for other com-
       pilation environments.


     SSffooffff__tt
       This defines an integral  type  suitable  to  address  the
       largest possible file extent.


     SSffuulloonngg__tt,, SSfflloonngg__tt,, SSffddoouubbllee__tt
       These  are  respectively  the  largest  unsigned  integer,
       signed integer, and floating  point  value  types  on  the
       local platform.


     SSffiioo__tt
       This defines the stream type.


     SSffddiisscc__tt
     ssssiizzee__tt ((**SSffrreeaadd__ff))((SSffiioo__tt**,, VVooiidd__tt**,, ssiizzee__tt,, SSffddiisscc__tt**))





                          05 August 1999                        4





SFIO(3)                                                   SFIO(3)


       ssssiizzee__tt   ((**SSffwwrriittee__ff))((SSffiioo__tt**,,   ccoonnsstt  VVooiidd__tt**,,  ssiizzee__tt,,
       SSffddiisscc__tt**))
     SSffooffff__tt ((**SSffsseeeekk__ff))((SSffiioo__tt**,, SSffooffff__tt,, iinntt,, SSffddiisscc__tt**))
     iinntt ((**SSffeexxcceepptt__ff))((SSffiioo__tt**,, iinntt,, VVooiidd__tt**,, SSffddiisscc__tt**))
       Sfdisc_t defines a stream discipline structure.  Sfread_f,
       Sfwrite_f  and  Sfseek_f are the types of discipline func-
       tions to replace the system calls: read(2),  write(2)  and
       lseek(2).   Sfexcept_f  is  the  type of an event-handling
       function.  See sfdisc() for more details.


     SSffffmmtt__tt
     iinntt ((**SSffffmmtteexxtt__ff))((SSffiioo__tt**,, VVooiidd__tt**,, SSffffmmtt__tt**))
     iinntt ((**SSffffmmtteevveenntt__ff))((SSffiioo__tt**,, iinntt,, VVooiidd__tt**,, SSffffmmtt__tt**))
       Sffmt_t defines a formatting environment that can be  used
       to  extend  scanning  and formatting in the sfprint()/sfs-
       canf() functions. Sffmtext_f and Sffmtevent_f  define  the
       types  of  extension  functions definable in Sffmt_t.  See
       Sffmt_t below for more details.


     SSFFIIOO__VVEERRSSIIOONN
       This is a macro value of type long int  that  defines  the
       current   version   number   of  Sfio.  For  example,  the
       Sfio1998's version number is 19980501L (which  also  indi-
       cates its release date).


   BBIITT FFLLAAGGSS
       A number of bit flags control stream operations.  They are
       set either at stream initialization or by calling sfset().
       Following are the flags:

       SF_STRING:
              The stream is memory-based.

       SF_READ, SF_WRITE, SF_APPEND:
              Flags SF_READ and SF_WRITE indicate readability and
              writability.   Flag  SF_APPEND  asserts  that   the
              stream is a file opened in append mode (see open(2)
              and fcntl(2)) so that data is always output at  the
              end of file.  On systems without direct support for
              append mode, Sfio uses lseek(2) or  its  discipline
              replacement to approximate this behavior.

       SF_LINE:
              The   stream  is  line-oriented.   For  a  SF_WRITE
              stream, this means that buffered  data  is  flushed
              whenever  a new-line character, \n, is output.  For
              a SF_READ stream, SF_LINE is only significant  dur-
              ing  calls  to  functions  in the sfscanf() family.
              SF_LINE is set on initialization of any stream rep-
              resenting a terminal device.




                          05 August 1999                        5





SFIO(3)                                                   SFIO(3)


       SF_SHARE, SF_PUBLIC:
              Flag   SF_SHARE  means  that  the  underlying  file
              descriptor is shared by independent  entities  (for
              example, multiple processes).

              For a seekable file stream, SF_SHARE means that the
              logical stream and the physical file positions will
              be  made  the  same before a system call to perform
              physical I/O.  There are  different  possibilities.
              If SF_PUBLIC is not set, the physical file position
              is made equal to the logical stream  position.   If
              SF_PUBLIC  is  set,  there  are  two cases.  If the
              physical file position has changed  from  its  last
              known position, the logical stream position is made
              equal to the new physical file position.   Finally,
              if  the  physical file location remains the same as
              its last known position, the physical file position
              is made the same as the logical stream position.

              For  an  unseekable stream (e.g., pipes or terminal
              devices), if  possible,  SF_SHARE  means  that  the
              block   and   record   I/O   operations  (sfread(),
              sfwrite(),  sfmove(),  sfgetr(),  sfputr(),   sfre-
              serve(),  sfscanf()  and  sfvprintf()) will ensure:
              (1) after each writing  operation,  the  stream  is
              synchronized  and  (2)  each reading operation only
              reads the requested amount.   Note,  however,  that
              (2) is not always possible without proper OS facil-
              ities such as recv(2) or streamio(4).

              A standard stream that is seekable will be initial-
              ized with SF_SHARE|SF_PUBLIC.

       SF_MALLOC:
              The  stream  buffer  was obtained via malloc(3) and
              can be reallocated or freed.

       SF_STATIC:
              The stream  structure  should  not  be  freed  when
              closed (sfclose()).  This flag is used by an appli-
              cations that allocate their own stream  structures.
              Such applications must use the header file sfio_t.h
              instead of sfio.h.

       SF_IOCHECK:
              If the stream has a discipline  exception  handler,
              exceptions will be raised in sfsync(), sfpurge() or
              before a  system  call  read(2)  or  write(2)  (see
              sfdisc()).

       SF_BUFCONST:
              The  application  guarantees  that  a stream buffer
              obtained via sfreserve() or sfgetr()  will  not  be
              modified.    This   allows   Sfio  to  tune  buffer



                          05 August 1999                        6





SFIO(3)                                                   SFIO(3)


              management and memory maps.  For example, a memory-
              mapped  stream  will  map  with  MAP_SHARED  on and
              PROT_WRITE off so that the file itself will  likely
              be the backing store for mapped pages.

       SF_WHOLE:
              This  flag guarantees that data written in any sin-
              gle sfwrite() or sfputr() call will always be  out-
              put  as a whole to the output device.  This is use-
              ful  in  certain  applications  (e.g.,  networking)
              where a complex object must be output without being
              split in different system  calls.   Note  that  the
              respective  stream still buffers data as the buffer
              can accomodate.



   OOPPEENNIINNGG//CCLLOOSSIINNGG SSTTRREEAAMMSS
     SSffiioo__tt** ssffnneeww((SSffiioo__tt** ff,, VVooiidd__tt** bbuuff,, ssiizzee__tt ssiizzee,,  iinntt  ffdd,,
       iinntt ffllaaggss))
       This  function creates or renews a stream.  It returns the
       new stream on success and NULL on error.

       f:     If f is NULL, a new stream is created.   Otherwise,
              f  is reused.  In this case, if flags does not have
              SF_EOF, f shall  be  closed  via  sfclose()  before
              being  reused.   During  a  stream renewal, buffer,
              pool and  discipline  stack  are  preserved.   Note
              that,  except  for  SF_STATIC  streams,  renewing a
              stream already  closed  will  result  in  undefined
              behavior.

       buf, size:
              These determine a buffering scheme.  See sfsetbuf()
              for more details.

       fd:    If  SF_STRING  is  specified  in  flags,  this   is
              ignored.  Otherwise, fd is a file descriptor (e.g.,
              from open(2)) to use for raw data I/O.   Note  that
              Sfio  supports  unseekable  file descriptors opened
              for both read and write, e.g., sockets.

       flags: This is composed from SF_EOF and bit values defined
              in the BBIITT FFLLAAGGSS section.


      SSffiioo__tt**  ssffooppeenn((SSffiioo__tt**  ff,, ccoonnsstt cchhaarr** ssttrriinngg,, ccoonnsstt cchhaarr**
       mmooddee))
       If string is NULL and f is a file stream that has not per-
       formed  any  I/O operation, sfopen() will change the modes
       of f according to mode.  In this case, sfopen() returns  f
       on success and NULL on error.  This somewhat unusual usage
       of sfopen() is good for changing the predefined  modes  of
       standard streams.



                          05 August 1999                        7





SFIO(3)                                                   SFIO(3)


       sfopen()  is normally used to create a new stream or renew
       a stream.  In this case, it returns the new stream on suc-
       cess  and  NULL  on  error.  Below are the meanings of the
       arguments:

       f:     This is treated as in sfnew().

       string:
              This is a file name or a string to perform I/O  on.

       mode:  This  is composed from the set of letters {s, r, w,
              +, a, x, b, t}.

              s specifies opening a string stream.  string can be
              a  null-terminated  string  or  NULL.  Specifying s
              alone is equivalent to specifying sr.  If s is  not
              specified, string defines a file name.

              r  and  w specify read and write modes.  Write mode
              creates and/or truncates the given file to make  an
              empty  file.   The  +  modifier  indicates that the
              stream is opened for both read and write.

              a specifies append mode, i.e., data is always  out-
              put at end of file.

              x specifies exclusive mode, i.e., a file opened for
              writing should not already exist.

              b and t specify binary and text modes.


     SSffiioo__tt** ssffppooppeenn((SSffiioo__tt** ff,,  ccoonnsstt  cchhaarr**  ccmmdd,,  ccoonnsstt  cchhaarr**
       mmooddee))
       This  function  opens  a  stream  that  corresponds to the
       coprocess cmd.  The argument mode should be composed  from
       r,  w, and +.  The argument f, if not NULL, is a stream to
       be renewed  (see  sfnew()).   sfpopen()  returns  the  new
       stream or NULL on error.

       The  standard  input/output  of  cmd  is  connected to the
       application via a pipe if the stream is opened  for  writ-
       ing/reading.  If the stream is opened for both reading and
       writing, there  will  be  two  different  associated  file
       descriptors,  one for each type of I/O (note the effect on
       sffileno()).

       On opening a coprocess for writing (i.e., mode contains  w
       or +), the signal handler for SIGPIPE in the parent appli-
       cation will be set to SIG_IGN if it  is  SIG_DFL  at  that
       time.   This  protects  the  parent application from being
       accidentally killed on any attempt to write to a coprocess
       that  closes  its  reading end.  Applications that need to
       detect  such  write  errors  should  use  disciplines  and



                          05 August 1999                        8





SFIO(3)                                                   SFIO(3)


       exception handlers (see sfdisc()).

       The  command  cmd  is  executed by an _i_n_t_e_r_p_r_e_t_e_r which is
       either /bin/sh or an executable  command  defined  by  the
       environment  variable  SHELL.   In either case, the inter-
       preter is invoked with 2 arguments,  respectively  -c  and
       the  given command cmd. When the interpreter is /bin/sh or
       /bin/ksh, sfpopen() may execute the command cmd itself  if
       there are no shell meta-characters in cmd.


     SSffiioo__tt** ssffttmmpp((ssiizzee__tt ssiizzee))
       This  function  creates  a  stream for temporary data.  It
       returns the new stream or NULL on error.

       A stream created by sftmp() can be completely or partially
       memory-resident.   If  size is SF_UNBOUND, the stream is a
       pure string stream.  If size is zero, the stream is a pure
       file  stream.  Otherwise, the stream is first created as a
       string stream but when its buffer grows larger  than  size
       or  on any attempt to change disciplines, a temporary file
       is  created.   Two  environment  variables,  TMPPATH   and
       TMPDIR,  direct  where  temporary files are created.  TMP-
       PATH, if  defined,  specifies  a  colon-separated  set  of
       directories  to be used in a round-robin fashion to create
       files.  If TMPPATH is undefined, TMPDIR  can  be  used  to
       specify a single directory to create files.  If neither of
       TMPPATH and TMPDIR are defined, /tmp is used.


     iinntt ssffcclloossee((SSffiioo__tt** ff))
       This function closes the stream f and frees its resources.
       SF_STATIC should be used if the stream space is to be pre-
       served.  If f is the base of  a  stream  stack  (see  sfs-
       tack()),  all  streams on the stack are closed.  If f is a
       sfpopen-stream, sfclose() waits until the associated  com-
       mand  terminates  and  returns its exit status.  sfclose()
       returns -1 for failure and 0 for success.

       SF_READ|SF_SHARE and  SF_WRITE  streams  are  synchronized
       before  closing  (see  sfsync()).   If  f has disciplines,
       their exception handlers will be called twice.  The  first
       exception  handler  call  has  the type argument as one of
       SF_CLOSE or SF_NEW (see sfdisc().)  The latter, SF_NEW  is
       used  when a stream is being closed via sfnew() so that it
       can be renewed.  The second call uses type as SF_FINAL and
       is  done  after  all closing operations have succeeded but
       before the stream itself is deallocated.  In either  case,
       if   the  exception  handler  returns  a  negative  value,
       sfclose() will immediately  return  this  value.   If  the
       exception handler returns a positive value, sfclose() will
       immediately return a zero value.





                          05 August 1999                        9





SFIO(3)                                                   SFIO(3)


   IINNPPUUTT//OOUUPPUUTT OOPPEERRAATTIIOONNSS
     iinntt ssffggeettcc((SSffiioo__tt** ff))
     iinntt ssffppuuttcc((SSffiioo__tt** ff,, iinntt cc))
       These functions  read/write  a  byte   from/to  stream  f.
       sfgetc()  returns  the byte read or -1 on error.  sfputc()
       returns c on success and -1 on error.


     ssssiizzee__tt ssffnnppuuttcc((SSffiioo__tt** ff,, iinntt cc,, ssiizzee__tt nn))
       This function attempts to write the byte c to f  n  times.
       It  returns  the number of bytes actually written or -1 on
       failure.


     iinntt ssffuunnggeettcc((SSffiioo__tt** ff,, iinntt cc))
       This function pushes the byte c back into f.  If c matches
       the  byte  immediately  before  the  current  position  in
       buffered data, the current position is  simply  backed  up
       (note  the  effect  on sftell() and sfseek()). There is no
       theoretical limit on the  number  of  bytes  that  can  be
       pushed  back  into a stream. Pushed back bytes not part of
       buffered data will be  discarded  on  any  operation  that
       implies  buffer  synchronization.  sfungetc() returns c on
       success and -1 on failure.


     SSffuulloonngg__tt ssffggeettuu((SSffiioo__tt** ff))
     iinntt ssffppuuttuu((SSffiioo__tt** ff,, SSffuulloonngg__tt vv))
       These functions read and write Sfulong_t values in a  com-
       pact  variable-length portable format.  Portability across
       a write architecture and a read architecture requires that
       the  bit order in a byte is the same on both architectures
       and the written value is storable in an Sfulong_t  on  the
       read  architecture.  sfgetu() returns the value read or -1
       on error.  sfputu() returns the number of bytes written or
       -1 on error.  See also sfulen().


     SSfflloonngg__tt ssffggeettll((SSffiioo__tt** ff))
     iinntt ssffppuuttll((SSffiioo__tt** ff,, SSfflloonngg__tt vv))
       These  functions  are similar to sfgetu() and sfputu() but
       for reading and writing  (signed)  Sflong_t  values.   See
       also sfllen().


     SSffddoouubbllee__tt ssffggeettdd((SSffiioo__tt** ff))
     iinntt ssffppuuttdd((SSffiioo__tt** ff,, SSffddoouubbllee__tt vv))
       These functions read and write Sfdouble_t values.  In this
       case, portability depends on the input and  output  archi-
       tectures  having the same floating point value representa-
       tion.  Values are coded and  decoded  using  ldexp(3)  and
       frexp(3) so they are constrained to the sizes supported by
       these functions.  See also sfdlen().




                          05 August 1999                       10





SFIO(3)                                                   SFIO(3)


     cchhaarr** ssffggeettrr((SSffiioo__tt** ff,, iinntt rrsscc,, iinntt ttyyppee))
       This function reads a record of data ending in the  record
       separator  rsc.  After sfgetr() returns, the length of the
       record even if it is  incomplete  can  be  retrieved  with
       sfvalue().   sfgetr()  returns  the  record on success and
       NULL on error.

       The type argument is composed of some subset of the  below
       bit flags:

       SF_STRING:
              A  null  byte  will replace the record separator to
              make the record into a C  string.   Otherwise,  the
              record separator is left alone.

       SF_LOCKR:
              Upon  successfully obtaining a record r, the stream
              will be locked from  further  access  until  it  is
              released with a call sfread(f,r,0).

       SF_LASTR:
              This should be used only after a failed sfgetr() to
              retrieve the last incomplete record. In this  case,
              rsc is ignored.


     ssssiizzee__tt ssffppuuttrr((SSffiioo__tt** ff,, ccoonnsstt cchhaarr** ss,, iinntt rrsscc))
       This  function  writes  the null-terminated string s to f.
       If rsc is non-negative, (unsigned char)rsc is output after
       the  string.  sfputr() returns the number of bytes written
       or -1 on failure.


     SSffooffff__tt ssffmmoovvee((SSffiioo__tt** ffrr,, SSffiioo__tt** ffww,, SSffooffff__tt nn,, iinntt rrsscc))
       This function moves objects from input stream fr to output
       stream  fw.   sfmove() returns the number of objects moved
       or -1 on failure.

       An object is either a byte or a  record.   The  latter  is
       indicated by a non-negative value for the record separator
       character rsc.  If n is negative, all of fr will be moved.
       Otherwise,  n indicates the number of objects to move.  If
       either fr or fw is NULL, it acts as if it is a stream cor-
       responding  to /dev/null, the UNIX device that has no read
       data and throws away any write  data.   For  example,  the
       call sfmove(f,(Sfio_t*)0,(Sfoff_t)(-1),'\n') simply counts
       the number of lines in stream f.


     ssssiizzee__tt ssffrreeaadd((SSffiioo__tt** ff,, VVooiidd__tt** bbuuff,, ssiizzee__tt nn))
       This function reads up to n bytes from f into buffer  buf.
       It  returns  the  number  of  bytes actually read or -1 on
       error.




                          05 August 1999                       11





SFIO(3)                                                   SFIO(3)


     ssssiizzee__tt ssffwwrriittee((SSffiioo__tt** ff,, ccoonnsstt VVooiidd__tt** bbuuff,, ssiizzee__tt nn))
       This function writes n bytes from  buf  to  f.   If  f  is
       SF_STRING, and the buffer is not large enough, an SF_WRITE
       exception shall be raised.  sfwrite() returns  the  number
       of bytes written or -1 on failure.


     SSffooffff__tt ssffsseeeekk((SSffiioo__tt** ff,, SSffooffff__tt ooffffsseett,, iinntt ttyyppee))
       This  function  sets a new I/O position for f.  It returns
       the new position or -1 on failure.

       If the stream is a SF_STRING stream and the new address is
       beyond  the  current  buffer  extent, an SF_SEEK exception
       will be raised (see sfdisc()).

       The new position is determined based on  offset  and  type
       which is composed from the bit flags:

       0 or SEEK_SET:
              offset is the desired position.

       1 or SEEK_CUR:
              offset  is  relative  to  the current position (see
              SF_PUBLIC below).

       2 or SEEK_END:
              offset is relative to the physical end of file.

       SF_SHARE:
              The stream is treated as if it has the control  bit
              SF_SHARE  on.  This implies that a system call seek
              will be done to ensure that the location seeking to
              is valid.

       SF_PUBLIC:
              The  stream is treated as if it has the control bit
              SF_PUBLIC on.  If the physical  file  position  has
              changed  from  its last known location, the current
              position is taken as  the  new  physical  position.
              Otherwise,  the  current  position  is  the logical
              stream position.


     VVooiidd__tt** ssffrreesseerrvvee((SSffiioo__tt** ff,, ssssiizzee__tt nn,, iinntt lloocckk))
       This function reserves a data block from f.  For a SF_READ
       stream,  a  data  block  is  a  segment  of data and for a
       SF_WRITE stream, it is a buffer suitable for writing.  For
       consistency, a stream opened with SF_READ|SF_WRITE will be
       treated as if it is a SF_READ stream (see sfset() for set-
       ting a particular mode.)  sfreserve() returns the obtained
       data block on success and NULL on failure.

       After a sfreserve() call,  whether  or  not  it  succeeds,
       sfvalue() can be used to obtain the size of the (may-have-



                          05 August 1999                       12





SFIO(3)                                                   SFIO(3)


       been) available data block.

       n != 0:
              f will be filled or flushed as  necessary  to  make
              available  a  data block of size at least the abso-
              lute value of n.  If this is successful and lock is
              non-positive,  the I/O position will advance by the
              size of the available data block when n is negative
              or  by  exactly n when n is positive.  For example,
              sfreserve(f,-1,0)  returns  a  positive  size  data
              block  and  advances  the I/O position by its size.
              On the other hand, sfreserve(f,1,0) returns a posi-
              tive  size data block and advances the I/O position
              by exactly 1.

       n == 0:
              If lock is zero, f will be  filled  or  flushed  as
              necessary to ensure that a positive-size data block
              is available.  If lock  is  non-zero,  no  fill  or
              flush  will  be performed.  In addition, if lock is
              positive, f will be  locked  from  further  access.
              Therefore,  an  application  can  lock f with sfre-
              serve(f,0,1).

       lock:  When lock is positive, there are restrictions.   If
              f  is  SF_READ  and  not  using memory-mapping (see
              sfsetbuf()), reservation must be limited to  stream
              buffer  size.  If f is SF_READ|SF_SHARE and unseek-
              able, sfreserve() will peek at incoming data  using
              either   recv(2)  or  streamio(4)  without  reading
              ahead.  In this case, if peeking is  not  supported
              by  the underlying platform, sfreserve() will fail.
              Note that SF_SHARE is automatically on for  sfstdin
              so programs (e.g., //bbiinn//ssoorrtt) that will consume all
              of input anyway should turn this bit off to  reduce
              the number of system calls.

              If  a  reservation  successfully  results in a data
              block data, and lock is positive,  the  stream  I/O
              position  does  not  advance  and  f will be locked
              until  unlocked  with  sfread/sfwrite(f,data,size).
              sfread()  should  be  used  on read-only stream and
              sfwrite() should be used on write-only  stream.   A
              stream in both read and write modes can release the
              lock with either call (with associated  operational
              semantics!)



   DDAATTAA FFOORRMMAATTTTIINNGG
       Data printing and scanning are done via the sfprintf() and
       sfscanf() family of functions.  These functions are  simi-
       lar  to  their ANSI-C fprintf() and fscanf() counterparts.
       However, the Sfio versions have  been  extended  for  both



                          05 August 1999                       13





SFIO(3)                                                   SFIO(3)


       portability  and generality.  In particular, a notion of a
       formatting environment stack is introduced.  Each  format-
       ting  element  on  the stack defines a separate _f_o_r_m_a_t_t_i_n_g
       _p_a_i_r of a format specification string, char*  format  (the
       usual second argument in the formatting functions), and an
       argument list, va_list args (the third argument  in  func-
       tions  sfvprintf() and sfvscanf()).  A formatting environ-
       ment element  may  also  specify  extension  functions  to
       obtain  or  assign  arguments and to provide new semantics
       for  pattern  processing.   To  simplify  the  description
       below,  whenever  we  talk  about an argument list, unless
       noted otherwise, it is understood that this  means  either
       the true argument list when there is no extension function
       or the action to be taken by such a function in processing
       arguments.  The manipulation of the formatting environment
       stack is done via the pattern ! discussed below.


   %%!! aanndd SSffffmmtt__tt
       The pattern  %!  manipulates  the  formatting  environment
       stack  to (1) change the top environment to a new environ-
       ment, (2) stack a new environment on top  of  the  current
       top,  or  (3)  pop the top environment.  The bottom of the
       environment stack always contains  a  virtual  environment
       with  the  original formatting pair and without any exten-
       sion functions.

       The top environment of a stack, say fe,  is  automatically
       popped whenever its format string is completely processed.
       In this case, its  event-handling  function  (if  any)  is
       called  as (*eventf)(f,SF_FINAL,NIL(Void_t*),fe).  The top
       environment can also be popped by giving an argument  NULL
       to  %!   or  by returning a negative value in an extension
       function.  In these cases, the event-handling function  is
       called  as  (*eventf)(f,SF_DPOP,form,fe) where form is the
       remainder of the format string. A  negative  return  value
       from the event handling function will prevent the environ-
       ment from being popped.

       A formatting environment is a structure  of  type  Sffmt_t
       which contains the following elements:

           Sffmtext_f   extf;   /* extension processor        */
           Sffmtevent_f eventf; /* event handler              */

           char*        form;   /* format string to stack     */
           va_list      args;   /* corresponding arg list     */

           int          fmt;    /* pattern being processed    */
           ssize_t      size;   /* object size                */
           int          flags;  /* formatting control flags   */
           int          width;  /* width of field             */
           int          precis; /* precision required         */
           int          base;   /* conversion base            */



                          05 August 1999                       14





SFIO(3)                                                   SFIO(3)


           char*        t_str;  /* type string in parentheses */
           int          n_str;  /* length of t_str            */

       The  first four elements of Sffmt_t must be defined by the
       application.   The  two  function  fields  should  not  be
       changed  during processing.  Other elements of Sffmt_t are
       set on calls to the extension function  Sffmt_t.extf  and,
       in turn, can be modified by this function to redirect for-
       matting or scanning.  For example, consider a call from  a
       sfprintf()  function  to  process  an  unknown  pattern %t
       (which we may take to mean ``time'') based on a formatting
       environment  fe.   fe->extf  may reset fe->fmt to `d' upon
       returing to cause sfprintf() to process  the  value  being
       formatted as an integer.

       Below are the fields of Sffmt_t:

       extf:  extf  is  a function to extend scanning and format-
              ting patterns.  Its usage is discussed below.

       eventf:
              This is a function to process events  as  discussed
              earlier.

       form and args:
              This  is  the  formatting  pair  of a specification
              string and corresponding argument  list.   When  an
              environment fe is being inserted into the stack, if
              fe->form is NULL, the top environment is changed to
              fe  and its associated extension functions but pro-
              cessing of the current formatting  pair  continues.
              On the other hand, if fe->form is not NULL, the new
              environment is pushed onto the stack so  that  pat-
              tern  processing will start with the new formatting
              pair as well as any associated extension functions.
              During  processing,  whenever  extf is called, form
              and args will be set to the current values  of  the
              formatting pair in use.

       fmt:   This is the pattern being processed.

       size:  This is the size of the object being processed.

       flags: This  is  a collection of bits defining the format-
              ting flags specified for  the  pattern.   The  bits
              are:

              SFFMT_LEFT: Flag - in sfprintf().

              SFFMT_SIGN: Flag + in sfprintf().

              SFFMT_BLANK: Flag _s_p_a_c_e in sfprintf().

              SFFMT_ZERO: Flag 0 in sfprintf().



                          05 August 1999                       15





SFIO(3)                                                   SFIO(3)


              SFFMT_THOUSAND: Flag ' in sfprintf().

              SFFMT_LONG: Flag l in sfprintf() and sfscanf().

              SFFMT_LLONG: Flag ll in sfprintf() and sfscanf().

              SFFMT_SHORT: Flag h in sfprintf() and sfscanf().

              SFFMT_LDOUBLE:  Flag L in sfprintf() and sfscanf().

              SFFMT_IFLAG: flag I in sfprintf() and sfscanf().

              SFFMT_ALTER: Flag # in sfprintf() and sfscanf().

              SFFMT_SKIP: Flag * in sfscanf().

              SFFMT_ARGPOS: This  indicates  argument  processing
              for pos$.

              SFFMT_VALUE:  This  is  set by fe->extf to indicate
              that it is returning a value to be formatted or the
              address of an object to be assigned.


       width: This is the field width.

       precis:
              This is the precision.

       base:  This is the conversion base.

       t_str and n_str:
              This is the type string and its size.


     iinntt ((**SSffffmmtteexxtt__ff))((SSffiioo__tt** ff,, VVooiidd__tt** vv,, SSffffmmtt__tt** ffee))
       This  is  the  type  of the extension function fe->extf to
       process patterns and arguments.  Arguments are always pro-
       cessed  in  order  and fe->extf is called exactly once per
       argument.  Note that, when pos$ (below) is not  used  any-
       where  in  a  format string, each argument is used exactly
       once per a corresponding pattern.  In that case,  fe->extf
       is  called as soon as the pattern is recognized and before
       any scanning or formatting.  On the other hand, when  pos$
       is used in a format string, an argument may be used multi-
       ple times.  In this case, all arguments shall be processed
       in  order  by  calling  fe->extf exactly once per argument
       before any pattern processing.  This case is signified  by
       the flag SFFMT_ARGPOS in fe->flags.

       In  addition  to  the  predefined  formatting patterns and
       other application-defined patterns, fe->extf may be called
       with  fe->fmt  being  one  of  `(' (left parenthesis), `.'
       (dot), and `I'.  The left parenthesis requests a string to



                          05 August 1999                       16





SFIO(3)                                                   SFIO(3)


       be used as the type string discussed below.  In this case,
       upon returning, fe->extf should set the fe->size field  to
       be  the  length of the string or a negative value to indi-
       cate a null-terminated string.  The dot requests an  inte-
       ger  for  width,  precision,  or  base.  In this case, the
       fe->size field will indicate how many dots  have  appeared
       in the pattern specification.  The `I' requests an integer
       to define the object size.

       f:     This is the input/output stream in the calling for-
              matting  function.   During a call to fe->extf, the
              stream shall be unlocked so that fe->extf can  read
              from or write to it as appropriate.

       v:     For  both  sfscanf()  and  sfprintf()  functions, v
              points to a location suitable for storing any prim-
              itive  data  types,  i.e., scalars or pointers.  On
              return, fe->extf treats v as discussed below.

       fe:    This is the current formatting environment.

       The return value rv of fe->extf directs  further  process-
       ing.   There are two cases.  When pos$ is present, a nega-
       tive return value means to ignore fe in  further  argument
       processing while a non-negative return value is treated as
       the case rv  ==  0  below.   When  pos$  is  not  present,
       fe->extf is called per argument immediately before pattern
       processing and its return values are treated as below:

       rv < 0:
              The environment stack is immediately popped.

       rv == 0:
              The extension function has not consumed (in a scan-
              ning  case) or output (in a printing case) data out
              of or into the given stream  f.   The  fields  fmt,
              flags,  size,  width,  precis  and base of fe shall
              direct further processing.

              For sfprintf() functions, if fe->flags has the  bit
              SFFMT_VALUE,  fe->extf  should  have  set *v to the
              value to be processed; otherwise, a value should be
              obtained  from  the  argument  list.  Likewise, for
              sfscanf()  functions,  SFFMT_VALUE  means  that  *v
              should  have  a  suitable  address;  otherwise,  an
              address to assign value should be obtained from the
              argument list.

              When  pos$ is present, if fe->extf changes fe->fmt,
              this pattern shall be used regardless of  the  pat-
              tern  defined  in  the  format string. On the other
              hand, if fe->fmt is unchanged by fe->extf, the pat-
              tern  in  the  format string is used.  In any case,
              the  effective  pattern  should  be  one   of   the



                          05 August 1999                       17





SFIO(3)                                                   SFIO(3)


              standardly defined pattern.  Otherwise, it shall be
              treated as unmatched.

       rv > 0:
              The extension function has accessed the stream f to
              the  extent of rv bytes.  Processing of the current
              pattern ceases except that, for scanning functions,
              if  fe->flags  does not contain the bit SFFMT_SKIP,
              the assignment count shall increase by 1.


   vvooiidd vvaa__ccooppyy((vvaa__lliisstt ttoo,, vvaa__lliisstt ffrr))
       This macro function portably copies the argument  list  fr
       to  the  argument  list  to.  It should be used to set the
       field Sffmt_t.args.


   lloonngg ssffffmmttvveerrssiioonn((SSffffmmtt__tt** ffee,, iinntt ttyyppee))
       This macro function initializes the formatting environment
       fe  with  a version number if type is non-zero. Otherwise,
       it returns the current value of the version number of  fe.
       This  is useful for applications to find out when the for-
       mat of the structure Sffmt_t changes.  Note that the  ver-
       sion  number  corresponds to the Sfio version number which
       is defined in the macro value SFIO_VERSION.


     iinntt ssffpprriinnttff((SSffiioo__tt** ff,, ccoonnsstt cchhaarr** ffoorrmmaatt,, ......))
     cchhaarr** ssffpprriinnttss((ccoonnsstt cchhaarr** ffoorrmmaatt,, ......))
     iinntt ssffsspprriinnttff((cchhaarr** ss,, iinntt nn,, ccoonnsstt cchhaarr** ffoorrmmaatt,, ......))
     iinntt ssffvvsspprriinnttff((cchhaarr** ss,, iinntt nn,, ccoonnsstt cchhaarr**  ffoorrmmaatt,,  vvaa__lliisstt
       aarrggss))
     iinntt ssffvvpprriinnttff((SSffiioo__tt** ff,, ccoonnsstt cchhaarr** ffoorrmmaatt,, vvaa__lliisstt aarrggss))
       These   functions  format  output  data.   sfprintf()  and
       sfvprintf() write to output  stream  f.   sfsprintf()  and
       sfvsprintf()  write  to  buffer  s  which  is  of  size n.
       sfprints() constructs output in some Sfio-defined  buffer.
       sfvprintf()  is  the  underlying  primitive  for the other
       functions.  Except for sfprints() which  returns  a  null-
       terminated string or NULL, other functions return the num-
       ber of output bytes or -1 on failure.

       The  length   of   string   constructed   by   sfprints(),
       sfsprintf(), or sfvsprintf() can be retrieved by sfslen().

       The standard patterns are: n, s, c, %, h, i, d, p,  u,  o,
       x,  X,  g,  G, e, E, f and !.  Except for ! which shall be
       described  below,  see   the   ANSI-C   specification   of
       fprintf(3)  for  details  on the other patterns.  Let z be
       some pattern type. A  formatting  pattern  is  defined  as
       below:

           %[pos$][flag][width][.precision][.base][(type)]z




                          05 August 1999                       18





SFIO(3)                                                   SFIO(3)


       pos$:  A  pattern  can specify which argument in the argu-
              ment list to use.  This is done via pos$ where  pos
              is  the  argument position.  Arguments are numbered
              so that the first argument after format is at posi-
              tion 1.  If pos is not specified, the argument fol-
              lowing the most recently used  one  will  be  used.
              The  pattern  %!  (see below) cannot be used subse-
              quent to a usage of pos$.  Doing so may cause unex-
              pected behaviors.

       flag:  The flag characters are h, l, L, I, -, +, _s_p_a_c_e, 0,
              ' and #.

              Flag I defines the size or type of the object being
              formatted.   There  are  two cases: (1) I by itself
              and (2) I followed by either a  decimal  number  or
              `*'.

              In  the  first case, for integer and floating point
              patterns, the  object  type  is  taken  to  be  the
              largest  appropriate  type  (i.e., one of Sflong_t,
              Sfulong_t or Sfdouble_t).   For  conversion  speci-
              fiers s and c, the flag is ignored.

              In  the  second  case,  a given decimal value would
              define a size while `*' would cause the size to  be
              obtained from the argument list.  Then, if the con-
              version specifier  is  s,  this  size  defines  the
              length  of  the  string  or strings being formatted
              (see the discussion of base  below).   For  integer
              and  floating  point  patterns, the size is used to
              select a type from one of the below lists as  indi-
              cated by the conversion specifier:

                  Sflong_t, long, int, short
                  Sfulong_t, unsigned long, unsigned int, unsigned short
                  Sfdouble_t, double, float

              The  selection  algorithm always matches types from
              left to right in any given list.   Although  selec-
              tion is generally based on sizes in bytes, for com-
              patibility with Microsoft-C, the size 64 is matched
              with  an  appropriate  type with the same number of
              bits, if any.  If the given size does not match any
              of  the  listed  types,  it shall match one of int,
              unsigned int, and double as defined by the  format-
              ting pattern.

              Below  are a few examples of using the I flag.  The
              first example prints  an  Sflong_t  integer.   This
              example  is actually not portable and only works on
              platforms where sizeof(Sflong_t) is 8.  The  second
              example  shows  how  to  that  portably.  The third
              example specifies printing a string of  length  16.



                          05 August 1999                       19





SFIO(3)                                                   SFIO(3)


              This  length shall be used regardless of whether or
              not the given string is shorter or longer than  16.
              The last example shows the use of the pattern %n to
              assign the amount of data  already  output  into  a
              short integer n_output.

                  sfprintf(sfstdout,"%I8d", Sflong_obj);
                  sfprintf(sfstdout,"%I*d", sizeof(Sflong_obj), Sflong_obj);
                  sfprintf(sfstdout,"%I*s", 16, s);
                  sfprintf(sfstdout,"%d%I*n", 1001, sizeof(short), &n_output);

              Flags  h,  l,  and  L are the ANSI-C conventions to
              select the types of input  objects.   For  example,
              %hd  indicates  a  short  int while %ld indicates a
              long int.  The flags ll and L address  respectively
              the largest integer and floating value types, i.e.,
              Sfulong_t, Sflong_t, and Sfdouble_t.

              Flag - left-justifies data within the field (other-
              wise, right-justification).

              Flag  +  means that a signed conversion will always
              begin with a plus or minus sign.

              Flag _s_p_a_c_e is ignored if + is specified; otherwise,
              it  means  that  if the first character of a signed
              conversion is not a sign or if the result is empty,
              a space will be prepended.

              Flag 0 means padding with zeros on the left.

              Flag ' outputs thousands-separator used by the cur-
              rent locale.  setlocale(3) should have been used to
              set the desired locale.

              Flag  # indicates an alternative format processing.
              For %o, the first digit is always a zero.   For  %x
              and  %X, a non-zero result will have a prefix 0x or
              0X. For %e, %E, %f, %g, and %G, the  result  always
              contains  a  decimal point. For %g and %G, trailing
              zeros will not be removed. For %d, %i and  %u,  the
              form  is  _b_a_s_e_#_n_u_m_b_e_r  where _b_a_s_e is the conversion
              base and _n_u_m_b_e_r is represented by digits  for  this
              _b_a_s_e.  For example, a base 2 conversion with %#..2d
              for 10 is 2#1010 instead of 1010  as  printed  with
              %..2d.

       width: This  defines  the  width  of the printing field. A
              value to be printed will be justified and padded if
              necessary to fill out the field width.

       precis:
              After  a  first  dot  appears,  an  integral  value
              defines a  precision.   For  floating  point  value



                          05 August 1999                       20





SFIO(3)                                                   SFIO(3)


              patterns, precision is the number of precision dig-
              its.  For %c, precision defines the number of times
              to  repeat  the character being formatted.  For %s,
              precision defines the maximum number of  characters
              to output.

       base:  After  a  second  dot  appears,  an  integral value
              defines a conversion base.

              For %i, %d, and %u, a conversion base should be  in
              the inclusive range [2,64].  If base is not in this
              range, it is defined to be 10.  The digits to  rep-
              resent numbers are:

                  01234567890
                  abcdefghijklmnopqrstuvwxyz
                  ABCDEFGHIJKLMNOPQRSTUVWXYZ
                  @_

              For  %s,  when  base is defined (i.e., at least two
              dots appeared in the  pattern  specification),  the
              input  argument  is taken as a NULL-terminated list
              of strings instead of a single string.  Each string
              is formatted based on the usual width and precision
              rules.  If base is non-zero, it  defines  an  ASCII
              character  used  to separate the formatted strings.
              Below is an example showing both the call  and  the
              result  of printing a NULL-terminated list of three
              strings apple, orange, and grape:

                  sfprintf(sfstdout,"%..*s",',',list);
                  apple,orange,grape

              Likewise, for %c, when base is defined,  the  input
              argument  is  taken  as  a  null-terminated  string
              instead of a single character.  Each  character  is
              formatted  based  on the normal width and precision
              rules.   In  addition,  if  base  is  non-zero,  it
              defines  an  ASCII  character  used to separate the
              formatted characters if there are more than one.

       (str): This defines a string  str  to  be  passed  to  the
              extension function Sffmt_t.extf.  Parentheses shall
              be balanced.  If str is *, the string  is  obtained
              from the argument list.



     iinntt ssffssccaannff((SSffiioo__tt** ff,, ccoonnsstt cchhaarr** ffoorrmmaatt,, ......))
     iinntt ssffssssccaannff((ccoonnsstt cchhaarr** ss,, ccoonnsstt cchhaarr** ffoorrmmaatt,, ......))
      iinntt  ssffvvssssccaannff((ccoonnsstt  cchhaarr**  ss,, ccoonnsstt cchhaarr** ffoorrmmaatt,, vvaa__lliisstt
       aarrggss))





                          05 August 1999                       21





SFIO(3)                                                   SFIO(3)


     iinntt ssffvvssccaannff((SSffiioo__tt** ff,, ccoonnsstt cchhaarr** ffoorrmmaatt,, vvaa__lliisstt aarrggss))
       These functions scan data items.  sfscanf() scans from the
       input  stream f while sfsscanf() and sfvsscanf() scan from
       the null-terminated string s.  sfvscanf() is the  underly-
       ing  primitive  that  performs  the actual scanning.  Item
       types are  determined  from  patterns  in  string  format.
       These  functions  return  the number of items successfully
       scanned or -1 on error.

       A white space character (blank, tab, or new-line) in  for-
       mat  normally  matches  a  maximal sequence of input white
       space characters.  However, if  the  input  stream  is  in
       SF_LINE  mode  (see  sfset()),  a  new-line character only
       matches white spaces up to an  input  new-line  character.
       This  is  useful  to  avoid  blocking  when scanning typed
       inputs.

       The standard scan patterns are: i, d, u, o, x, X, p, n, f,
       e,  E,  g, G, c, %, s, [] and !.  Except for ! which shall
       be  described  below,  see  the  ANSI-C  specification  of
       fscanf(3)  for  details  on other patterns.  Let z be some
       pattern type. A formatting pattern is specified as below:

           %[*][pos$][width][.width.base][(type)][flag]z


       pos$:  A pattern can specify which argument in  the  argu-
              ment  list to use.  This is done via pos$ where pos
              is the argument position.  Arguments  are  numbered
              so that the first argument after format is at posi-
              tion 1.  If pos is not specified, the argument fol-
              lowing  the  most  recently  used one will be used.
              The pattern %! (see below) cannot  be  used  subse-
              quent to a usage of pos$.

       *:     This discards the corresponding scanned item.

       width and base:
              width  defines  the maximum number of bytes to scan
              and base defines the  base  of  an  integral  value
              being  scanned.  The `.' (dot) notation also allows
              specifying a `*' (star) to obtain  the  value  from
              the  argument  list.  The  below  example specifies
              scanning 4 bytes to obtain the value of an  integer
              in  base 10. At the end of scanning, the variable v
              should have the value 1234.

                  sfsscanf("12345678","%.*.*d", 4, 10, &v);


       (str): This defines a string  str  to  be  passed  to  the
              extension function Sffmt_t.extf.  Parentheses shall
              be balanced.  If str is *, the string  is  obtained
              from the argument list.



                          05 August 1999                       22





SFIO(3)                                                   SFIO(3)


       flag:  This is #, I, or some sequence of h, l, and L.

              Flag  #  is significant for pattern %i and %[.  For
              %i, it means that the # symbol does  not  have  its
              usual meaning in an input sequence base#value.  For
              example, the scanning result of %#i on input 2#1001
              is 2 and the next sfgetc() call will return #.  For
              %[, if the next character in the input stream  does
              not  match  the  given  scan  set  of characters, #
              causes a match to a null string instead of a  fail-
              ure.

              Flag I defines the size or type of the object being
              formatted.  There are two cases: (1)  I  by  itself
              and  (2)  I  followed by either a decimal number or
              `*'.

              In the first case, for integer and  floating  point
              patterns,  the  object  type  is  taken  to  be the
              largest appropriate type (i.e.,  one  of  Sflong_t,
              Sfulong_t or Sfdouble_t).  For string patterns such
              as %s, the flag is ignored.

              In the second case, a  given  decimal  value  would
              define  a size while `*' would cause the size to be
              obtained from the argument list.  For  string  pat-
              terns  such  as  %s  or  %[,  this size defines the
              length of the buffer to store scanned data.  Speci-
              fying  a buffer size only limits the amount of data
              copied into the buffer.  Scanned  data  beyond  the
              buffer  limit  will  be discarded.  For integer and
              floating point patterns, the size is used to select
              a  type from one of the below lists as indicated by
              the conversion specifier:

                  Sflong_t, long, int, short
                  Sfulong_t, unsigned long, unsigned int, unsigned short
                  Sfdouble_t, double, float

              The selection algorithm always matches  types  from
              left  to  right in any given list.  Although selec-
              tion is generally based on sizes in bytes, for com-
              patibility with Microsoft-C, the size 64 is matched
              with an appropriate type with the  same  number  of
              bits, if any.  If the given size does not match any
              of the listed types, it shall  match  one  of  int,
              unsigned  int,  and double as indicated by the for-
              matting pattern.

              Below are examples of using the I flag.  The  first
              example  scans  a 64-bit integer.  The second scans
              some floating point value whose size is  explicitly
              computed  and  given.   The  last  example  scans a
              string into a buffer with the given size 128.  Note



                          05 August 1999                       23





SFIO(3)                                                   SFIO(3)


              that if the scanned string is longer than 127, only
              the first  127  bytes  shall  be  copied  into  the
              buffer.  The rest of the scanned data shall be dis-
              carded.

                   sfscanf(sfstdin,"%I64d", &int64_obj);
                   sfscanf(sfstdin,"%I*f", sizeof(float_obj), &float_obj);
                   sfscanf(sfstdin,"%I*s", 128, buffer);

              Flags h, l, and L are the  ANSI-C  conventions  for
              indicating  the  type  of  a  scanned element.  For
              example, %hd means scanning a short int.  The flags
              ll and L mean respectively scanning an integer or a
              floating  point  value  with  largest  size   (i.e,
              Sflong_t or Sfdouble_t).

       The %i, %d and %u patterns scan numbers in bases from 2 to
       64.  %i scans integral values in self-describing  formats.
       Except for octal, decimal and hexadecimal numbers with the
       usual formats, numbers in general bases are assumed to  be
       of  the form: _b_a_s_e_#_v_a_l_u_e where _b_a_s_e is a number in base 10
       and _v_a_l_u_e is a number in the  given  base.   For  example,
       2#1001  is  the binary representation of the decimal value
       9.  If _b_a_s_e is 36 or less, the digits for _v_a_l_u_e can be any
       combination  of  [0-9], [a-z], [A-Z] where upper and lower
       case digits are not distinguishable.  If  _b_a_s_e  is  larger
       than 36, the set of digits is:

           0123456789
           abcdefghijklmnopqrstuvwxyz
           ABCDEFGHIJKLMNOPQRSTUVWXYZ
           @_



   BBUUFFFFEERRIINNGG,, SSYYNNCCHHRROONNIIZZAATTIIOONN
     VVooiidd__tt** ssffsseettbbuuff((SSffiioo__tt** ff,, VVooiidd__tt** bbuuff,, ssiizzee__tt ssiizzee))
       This  function sets the buffering scheme for the stream f.
       Except for buffer inquiry (see the case size == 0,) f will
       be  synchronized before any buffer modification.  If a new
       buffer is successfully set and the old buffer has not been
       deallocated,  sfsetbuf()  returns  the  address of the old
       buffer.  Otherwise, it returns NULL.

       After a sfsetbuf() call, sfvalue() returns the size of the
       returned buffer.

       size == SF_UNBOUND:
              Sfio  will  pick a suitable buffer size.  If buf is
              NULL, Sfio will  also  pick  a  suitable  buffering
              scheme  (such  as  memory  mapping.)  If buf is not
              NULL, its actual value is ignored  but  the  buffer
              will  be allocated via malloc(3).  This can be used
              to avoid memory mapping.



                          05 August 1999                       24





SFIO(3)                                                   SFIO(3)


       size > 0:
              This is the suggested size to use for buffering  or
              memory  mapping.   If buf is NULL, Sfio will pick a
              suitable buffering scheme as discussed  above.   If
              buf  is  not  NULL,  then  buf and size determine a
              buffer of the given size.

       size == 0:
              If buf is NULL, the stream will be unbuffered.   If
              buf  is  not  NULL,  sfsetbuf()  simply returns the
              stream buffer.  In this case, no  attempt  will  be
              made to synchronize the stream.


     iinntt ssffssyynncc((SSffiioo__tt** ff))
       This  function synchronizes the logical and physical views
       of stream f.  For a SF_WRITE stream, this means  to  write
       out  any  buffered  data.   For  a  seekable  SF_READ file
       stream, the physical file position  is  aligned  with  the
       logical  stream  position and, if SF_SHARE is on, buffered
       data is discarded.  If f is NULL, all streams are synchro-
       nized.   If  f  is  the  base  of a stream stack (see sfs-
       tack()), all stacked streams are synchronized.  Note  that
       a  stacked stream can only be synchronized this way.  If f
       is in a pool (see sfpool()) but not being  the  head,  the
       pool  head  is  synchronized.  After a successful synchro-
       nization, if f has flag SF_IOCHECK,  a  SF_SYNC  event  is
       raised.  sfsync() returns a negative value for failure and
       0 for success.


     iinntt ssffppoollll((SSffiioo__tt**** fflliisstt,, iinntt nn,, iinntt ttiimmeeoouutt))
       This function polls a set of streams to see if I/O  opera-
       tions  can be performed on them without blocking.  This is
       useful for multiplexing I/O over a set of streams.   If  a
       stream  has  a  discipline,  the exception function may be
       called before and after the stream is polled (see sfdisc()
       for  details).   sfpoll()  returns  the  number  of  ready
       streams or -1 on failure.

       flist and n:
              flist is an array of n streams to be polled.   Upon
              return,  ready  streams  are  moved to the front of
              flist in the same relative order.

       timeout:
              This defines an ellapse  time  in  milliseconds  to
              wait  to  see  if  any stream is ready for I/O.  If
              timeout is negative, sfpoll() will block until some
              stream  become ready.  Note that SF_STRING and nor-
              mal file streams never block and are  always  ready
              for  I/O.   If  a  stream  with discipline is being
              polled and its readiness  is  as  yet  undetermined
              (e.g.,  empty  buffer,)  the  discipline  exception



                          05 August 1999                       25





SFIO(3)                                                   SFIO(3)


              function will be called with SF_DPOLL before normal
              actions are taken.


     SSffiioo__tt** ssffppooooll((SSffiioo__tt** ff,, SSffiioo__tt** ppoooollff,, iinntt mmooddee))
       This  function  manipulates  pools of streams.  In a pool,
       only one stream is at the head and can have buffered data.
       All  other  streams  in  the pool will be synchronized.  A
       stream becomes head when it is used for  some  I/O  opera-
       tion.  sfpool() returns NULL on failure.

       f and poolf:
              If  f  is NULL, sfpool() simply returns the head of
              the pool containing poolf.  If f is  not  NULL  and
              poolf is NULL, f is deleted from its pool.  In this
              case, if no other stream from  the  same  pool  can
              become  head, sfpool() will return NULL; otherwise,
              it returns some stream from the  remainder  of  the
              pool.  If both f and poolf are not NULL, f is moved
              from its current pool (if any) into the  same  pool
              with poolf.  In this case, poolf is returned.

       mode:  If  poolf  is  already  in a pool, mode is ignored.
              Otherwise,  mode  should  be  0  or  SF_SHARE.    A
              SF_SHARE  pool contains streams with SF_WRITE mode.
              In addition,  on  change  to  a  new  head  stream,
              buffered  write  data of the current head is trans-
              ferred to the new head.


     iinntt ssffppuurrggee((SSffiioo__tt** ff))
       This function discards all buffered data  unless  f  is  a
       SF_STRING  stream.   Note  that  if  f is a SF_READ stream
       based on an unseekable device, purged  data  will  not  be
       recoverable.   If  f  is  a sfpopen-stream opened for both
       read and write, data of both the read and write pipe  ends
       will  be  purged (see sfset() to selectively turn off read
       or write mode if one set of  data  is  to  be  preserved.)
       After  purging,  if  f  has  flag  SF_IOCHECK,  the  event
       SF_PURGE is raised.  sfpurge() returns -1 for failure  and
       0 for success.



   DDIISSCCIIPPLLIINNEE,, EEVVEENNTT--HHAANNDDLLIINNGG
       A  file stream uses the system calls read(2), write(2) and
       lseek(2) to read, write and  position  in  the  underlying
       file.   Disciplines enable application-defined I/O methods
       including exception handling and data pre/post-processing.


     SSffddiisscc__tt** ssffddiisscc((SSffiioo__tt** ff,, SSffddiisscc__tt** ddiisscc))
       Each  stream has a discipline stack whose bottom is a vir-
       tual discipline  representing  the  actual  system  calls.



                          05 August 1999                       26





SFIO(3)                                                   SFIO(3)


       sfdisc()  manipulates the discipline stack of stream f.  f
       will be synchronized before any discipline stack manipula-
       tion.   After  a successful discipline stack manipulation,
       the stream I/O position (see sfseek()  and  sftell())  and
       extent  (see sfsize()) are updated to reflect that defined
       by  the  top  discipline.   If  disc  is   SF_POPDISC   or
       (Sfdisc_t*)0,  the  top  element  of the stack, if any, is
       popped and its address is returned.   Otherwise,  disc  is
       pushed  onto  the discipline stack.  In this case, if suc-
       cessful, sfdisc() returns the discipline that  was  pushed
       down.  sfdisc() returns NULL on failure.

       Note that a discipline can be used only on one stream at a
       time.  An application should take care to allocate differ-
       ent  discipline structures for use with different streams.
       A discipline structure is of the type Sfdisc_t which  con-
       tains the following public fields:

           Sfread_f   readf;
           Sfwrite_f  writef;
           Sfseek_f   seekf;
           Sfexcept_f exceptf;


       The first three fields of Sfdisc_t specify alternative I/O
       functions.  If any of them is NULL, it is inherited from a
       discipline  pushed earlier on the stack.  Note that a file
       stream  always  has  read(2),   write(2),   lseek(2)   and
       NIL(Sfexcept_f)  as  the _l_o_g_i_c_a_l _b_o_t_t_o_m _d_i_s_c_i_p_l_i_n_e.  Argu-
       ments to I/O discipline functions have the same meaning as
       that  of the functions sfrd(), sfwr() and sfsk() described
       below.

       The exception function, (*exceptf)() announces exceptional
       events   during   I/O   operations.    It   is  called  as
       (*exceptf)(Sfio_t* f, int type, Void_t*  value,  Sfdisc_t*
       disc).   Unless  noted  otherwise,  the  return  value  of
       (*exceptf)() is used as follows:

       <0:    The on-going operation shall terminate.

       >0:    If the event was raised due to an  I/O  error,  the
              error  has been repaired and the on-going operation
              shall continue normally.

       =0:    The on-going  operation  performs  default  actions
              with  respect to the raised event.  For example, on
              a reading error or reaching end of  file,  the  top
              stream of a stack will be popped and closed and the
              on-going  operation  continue  with  the  new   top
              stream.

       The  argument type of (*exceptf)() identifies the particu-
       lar exceptional event:



                          05 August 1999                       27





SFIO(3)                                                   SFIO(3)


       SF_LOCKED:
              The stream is in a locked state.

       SF_READ, SF_WRITE:
              These events are raised around reading and  writing
              operations.

              If  SF_IOCHECK  is  on,  SF_READ  and  SF_WRITE are
              raised  immediately  before  read(2)  and  write(2)
              calls.   In  this  case,  *((ssize_t*)value) is the
              amount of data to be processed.  The  return  value
              of  (*exceptf)(),  if  negative, indicates that the
              stream is not ready for I/O and the calling  opera-
              tion  will  abort with failure.  If it is positive,
              the stream is ready for I/O but the  amount  should
              be  restricted  to  the  amount  specified  by this
              value.  If the return value is zero, the I/O opera-
              tion is carried out normally.

              SF_READ  and  SF_WRITE are also raised on operation
              failures.  In such a  case,  *((ssize_t*)value)  is
              the return value from the failed operation.

       SF_SEEK:
              This event is raised when a seek operation fails.

       SF_NEW, SF_CLOSE, SF_FINAL:
              These  events  are  raised during a stream closing.
              SF_NEW is raised for a stream about to be closed to
              be renewed (see sfnew()).  SF_CLOSE is raised for a
              stream about to  be  closed.   SF_FINAL  is  raised
              after a stream has been closed and before its space
              is to be  destroyed  (see  sfclose()).   For  these
              events,  a  non-zero return value from (*exceptf)()
              causes sfclose() to  return  immediately  with  the
              same value.

       SF_DPUSH, SF_DPOP, SF_DBUFFER:
              Events  SF_DPUSH and SF_DPOP are raised when a dis-
              cipline  is  about  to   be   pushed   or   popped.
              (Sfdisc_t*)value  is  the  to-be top discipline, if
              any.

              A stream buffer is always synchronized before push-
              ing  or popping a discipline.  If this synchroniza-
              tion  fails,  SF_DBUFFER  will   be   raised   with
              *((size_t*)value)  being  the  amount  of  buffered
              data.  If the return value of exceptf is  positive,
              the  push  or pop operation will continue normally;
              otherwise, sfdisc() returns failure.

       SF_DPOLL:
              This event is raised by  sfpoll()  to  see  if  the
              stream  is ready for I/O.  *((int*)value) indicates



                          05 August 1999                       28





SFIO(3)                                                   SFIO(3)


              a time-out interval to  wait.   A  negative  return
              value  from  the exception function means blocking.
              A positive return value means non-blocking.  A zero
              return  value  means that sfpoll() should query the
              stream file descriptor using default methods.

       SF_READY:
              This event is raised by  sfpoll()  for  each  ready
              stream  after  they  are  determined.   A  negative
              return  value  from  the  exeption  handler  causes
              sfpoll() to return immediately with the same return
              value.  A positive return value causes sfpoll()  to
              retry polling the whole set of streams.

       SF_SYNC, SF_PURGE:
              If SF_IOCHECK is set, these events are raised imme-
              diately after sfsync()  or  sfpurge()  successfully
              complete  their  operations and before they return.
              Note that sfsync() is implied when  a  SF_WRITE  or
              SF_SHARE|SF_READ  stream is closed.  Note also that
              SF_SYNC is not raised  for  a  stream  synchronized
              during a call sfsync((Sfio_t*)0).

       SF_ATEXIT:
              This  event  is  raised for each open stream before
              the process exits.


     iinntt ssffrraaiissee((SSffiioo__tt** ff,, iinntt ttyyppee,, VVooiidd__tt** ddaattaa))
       This function calls all exception  handlers  of  stream  f
       with  the event type and associated data.  If an exception
       handler returns  a  non-zero  value,  sfraise()  immediate
       returns the same value.  Application-defined events should
       start from the value SF_EVENT so  as  to  avoid  confusion
       with system-defined events, sfraise() returns 0 on success
       and -1 on failure.


     ssssiizzee__tt ssffrrdd((SSffiioo__tt** ff,, VVooiidd__tt**  bbuuff,,  ssiizzee__tt  nn,,  SSffddiisscc__tt**
       ddiisscc))
      ssssiizzee__tt  ssffwwrr((SSffiioo__tt**  ff,,  ccoonnsstt  VVooiidd__tt**  bbuuff,,  ssiizzee__tt  nn,,
       SSffddiisscc__tt** ddiisscc))
     SSffooffff__tt ssffsskk((SSffiioo__tt** ff,, SSffooffff__tt ooffffsseett,, iinntt ttyyppee,,  SSffddiisscc__tt**
       ddiisscc))
       These functions provides safe methods for a discipline I/O
       function to invoke earlier discipline I/O functions and to
       properly  handle  exceptions.   They should not be used in
       any other context.  sfrd() and sfwr() return the number of
       bytes  read or written.  sfsk() returns the new seek posi-
       tion.  On error, all three  functions  return  a  negative
       value  which  should  be  -1  or the value returned by the
       exception handler.





                          05 August 1999                       29





SFIO(3)                                                   SFIO(3)


   SSTTRREEAAMM CCOONNTTRROOLL
     iinntt ssffsseett((SSffiioo__tt** ff,, iinntt ffllaaggss,, iinntt sseett))
       This function sets control flags for  the  stream  f.   It
       returns the previous set of flags or 0 on error.

       Settable   flags   are:   SF_READ,  SF_WRITE,  SF_IOCHECK,
       SF_LINE, SF_SHARE,  SF_PUBLIC,  SF_MALLOC,  SF_STATIC  and
       SF_BUFCONST.  Note that SF_READ and SF_WRITE can be turned
       on  or  off   only   if   the   stream   was   opened   as
       SF_READ|SF_WRITE.   Turning off one of them means that the
       stream is to be treated exclusively in the other mode.  It
       is not possible to turn off both.  If legal, an attempt to
       turn on either SF_READ or SF_WRITE will cause  the  stream
       to be in the given I/O mode.

       set == 0:
              If  flags is zero, the current set of flags is sim-
              ply returned.  Note that when  a  stream  is  first
              opened,  not  all  of its flags are initialized yet
              (more below). If flags is non-zero, an  attempt  is
              made to turn off the specified flags.

       set != 0:
              If  flags is zero, the stream is initialized if not
              yet done so.  Then the  current  set  of  flags  is
              returned.  If flags is non-zero, an attempt is made
              to turn on the specified flags.


     iinntt ssffsseettffdd((SSffiioo__tt** ff,, iinntt ffdd))
       This function changes the file descriptor of f.  Before  a
       change is realized, (*notify)(f,SF_SETFD,newfd) (see sfno-
       tify()) is called.  sfsetfd() returns -1  on  failure  and
       the new file descriptor on success.

       fd >= 0:
              If  the current file descriptor is non-negative, it
              will be changed using dup(3) to a value  larger  or
              equal  to fd.  Upon a successful change, the previ-
              ous file descriptor will be closed.  If the current
              file  descriptor  is negative, it will be set to fd
              and the stream will be reinitialized.

       fd < 0:
              The stream is synchronized (see sfsync())  and  its
              file  descriptor  will be set to this value.  Then,
              except for sfclose(), the stream will be inaccessi-
              ble  until  a future sfsetfd() call resets the file
              descriptor  to   a   non-negative   value.    Thus,
              sfsetfd(f,-1) can be used to avoid closing the file
              descriptor of f when f is closed.






                          05 August 1999                       30





SFIO(3)                                                   SFIO(3)


     SSffiioo__tt** ssffssttaacckk((SSffiioo__tt** bbaassee,, SSffiioo__tt** ttoopp))
       This function stacks or  unstacks  stream.   Every  stream
       stack  is  identified  by  a base stream via which all I/O
       operations  are  performed.   However,  an  I/O  operation
       always  takes effect on the top stream.  If the top stream
       reaches the end of file or has an unrecoverable error con-
       dition,  it  is  automatically popped and closed (see also
       sfdisc() for alternative handling of these conditions).

       base:  This is the base stream of the  stack.   If  it  is
              NULL, sfstack() does nothing and returns top.

       top:   If  this is SF_POPSTACK or (Sfio_t*)0, the stack is
              popped and sfstack()  returns  the  popped  stream.
              Otherwise,  top is pushed on top of the stack iden-
              tified by  base  and  sfstack()  returns  the  base
              stream.


     SSffiioo__tt** ssffsswwaapp((SSffiioo__tt** ff11,, SSffiioo__tt** ff22))
       This  function swaps contents of f1 and f2.  This fails if
       either stream is in a stream stack but not  being  a  base
       stream.   If  f2 is NULL, a new stream is constructed as a
       duplicate of f1.  sfswap() returns f2 or f1  duplicate  on
       success and NULL on failure.



   SSTTRREEAAMM IINNFFOORRMMAATTIIOONN
     SSffooffff__tt ssffssiizzee((SSffiioo__tt** ff))
       This  function returns the size of stream f (see sfnew()).
       If f is not seekable or if its size is  not  determinable,
       sfsize() returns -1.


     SSffooffff__tt ssfftteellll((SSffiioo__tt** ff))
       This  function  returns the current I/O position in stream
       f.  Note that if f is SF_APPEND and  a  writing  operation
       was  just  performed,  the  current I/O position is at the
       physical end of file.  If f is unseekable, sftell  returns
       the  number  of bytes read from or written to f.  See also
       sfungetc().


     ssssiizzee__tt ssffvvaalluuee((SSffiioo__tt** ff))
       This function returns the  string  or  buffer  length  for
       sfreserve(), sfsetbuf(), and sfgetr().


     iinntt ssffffiilleennoo((SSffiioo__tt** ff))
       This function returns the file descriptor of stream f.






                          05 August 1999                       31





SFIO(3)                                                   SFIO(3)


     iinntt ssffssttaacckkeedd((SSffiioo__tt** ff))
       This  function  returns  a  non-zero value if stream f has
       been stacked.


     iinntt ssffeeooff((SSffiioo__tt** ff))
     iinntt ssffeerrrroorr((SSffiioo__tt** ff))
     iinntt ssffccllrreerrrr((SSffiioo__tt** ff))
       sfeof() tells whether or not the stream has an end-of-file
       condition.   sferror() tells whether or not the stream has
       an error condition.  sfclrerr()  clears  both  end-of-file
       and  error  conditions.   The end-of-file and error condi-
       tions are also cleared on an I/O operation.


     iinntt ssffccllrrlloocckk((SSffiioo__tt** ff))
       This function restores the stream back to a normal  state.
       This  means  clearing  locks  and  possibly  throwing away
       unprocessed data.  As such, this operation is  unsafe  and
       should  be  used  with  care.  For example, it may be used
       before a long jump (longjmp(3)) out of some discipline I/O
       function  to  restore  the internal stream states.  sfclr-
       lock() returns the current set of flags.


     iinntt ssffnnoottiiffyy((((vvooiidd((**))nnoottiiffyy))((SSffiioo__tt**,, iinntt,, iinntt)) ))
       This  sets  a  function  (*notify)()  to  be   called   as
       (*notify)(f,type,file)  on  various  stream events.  Argu-
       ments f and file are stream and related  file  descriptor.
       Argument type indicates the reason for the call:

       SF_NEW:
              f  is  being opened and file is the underlying file
              descriptor.

       SF_CLOSE:
              f and file are being closed.

       SF_SETFD:
              The file descriptor of f is being changed  to  file
              (see sfsetfd().)

       SF_READ:
              An attempt to change f to read mode failed.

       SF_WRITE:
              An attempt to change f to write mode failed.



   MMIISSCCEELLLLAANNEEOOUUSS FFUUNNCCTTIIOONNSS
     ssssiizzee__tt ssffsslleenn(())
       This  function  returns  the  length of a string just con-
       structed  by  sfsprintf()   or   sfprints().    See   also



                          05 August 1999                       32





SFIO(3)                                                   SFIO(3)


       sfvalue().


     iinntt ssffuulleenn((SSffuulloonngg__tt vv))
     iinntt ssfflllleenn((SSfflloonngg__tt vv))
     iinntt ssffddlleenn((SSffddoouubbllee__tt vv))
       These  functions  return  respectively the number of bytes
       required to code the  Sfulong_t,  Sflong_t  or  Sfdouble_t
       value v by sfputu(), sfputl() or sfputd().


      ssssiizzee__tt  ssffppkkrrdd((iinntt  ffdd,, cchhaarr** bbuuff,, ssiizzee__tt nn,, iinntt rrsscc,, lloonngg
       ttmm,, iinntt aaccttiioonn))
       This function acts directly on the file descriptor fd.  It
       does a combination of peeking on incoming data and a time-
       out read.  Upon success, it returns the  number  of  bytes
       received.   A return value of 0 means that the end-of-file
       condition has been detected.  A negative value  represents
       an error.

       buf, n:
              These  define  a  buffer  and its size to read data
              into.

       rsc:   If >=0,  this  defines  a  record  separator.   See
              action for detail.

       tm:    If  >=0,  this defines a time interval in millisec-
              onds to wait for incoming data.

       action:
              When rsc >= 0, the absolute  value  of  action,  _r,
              determines  the  number  of records to be read.  If
              action > 0, sfpkrd() will peek on incoming data but
              will not read past it. Therefore, a future sfpkrd()
              or read(2) will see the same data again.  If action
              == 0, sfpkrd() will not peek.  If action < 0, there
              are two cases: if rsc < 0, sfpkrd() reads n  bytes;
              otherwise,  exactly  _r  records will be read.  Note
              that, in the last case,  reading  records  from  an
              unseekable  device  may  be  slow if the underlying
              platform does not allow peeking on such a device.



   FFUULLLL SSTTRRUUCCTTUURREE SSFFIIOO__TT
     ##iinncclluuddee <<ssffiioo__tt..hh>>
       Most applications based on Sfio only need to  include  the
       header  file  sfio.h  which  defines an abbreviated Sfio_t
       structure without certain fields private  to  Sfio.   How-
       ever,  there  are times (e.g., debugging) when an applica-
       tion may require more details about the full Sfio_t struc-
       ture.  In such cases, the header file sfio_t.h can be used
       in place of sfio.h.  Note that an application  doing  this



                          05 August 1999                       33





SFIO(3)                                                   SFIO(3)


       will become sensitive to changes in the internal architec-
       ture of Sfio.


     ##ddeeffiinnee SSFFNNEEWW((bbuuff,,ssiizzee,,ffiillee,,ffllaaggss,,ddiisscc))
       This macro function is defined  in  sfio_t.h  for  use  in
       static initialization of an Sfio_t structure.  It requires
       five arguments:

       buf, size:
              These define a buffer and its size.

       file:  This defines the underlying file descriptor if any.

       flags: This is composed from bit flags described above.

       disc:  This defines a discipline if any.



   EEXXAAMMPPLLEE DDIISSCCIIPPLLIINNEESS
       The  below  functions  create  disciplines and insert them
       into the given streams f. These functions return 0 on suc-
       cess and -1 on failure.


   iinntt ssffddccddiioo((SSffiioo__tt** ff,, ssiizzee__tt bbuuffssiizzee))
       This  creates a discipline that uses the direct IO feature
       available on file systems such as SGI's XFS  to  speed  up
       IO.   The  argument  bufsize suggests a buffer size to use
       for data transfer.


   iinntt ssffddccddooss((SSffiioo__tt** ff))
       This creates a discipline to  read  DOS  text  files.   It
       basically transforms pairs of \r\n to \n.


   iinntt ssffddccffiilltteerr((SSffiioo__tt** ff,, ccoonnsstt cchhaarr** ccmmdd))
       This  creates  a  discipline that sends data from f to the
       given command cmd to process, then  reads  back  the  pro-
       cessed data.


   iinntt ssffddccllzzww((SSffiioo__tt** ff))
       This creates a discipline that would decompress data in f.
       The stream f should have data from a source compressed  by
       the Unix ccoommpprreessss program.


   iinntt ssffddccsseeeekkaabbllee((SSffiioo__tt** ff))
       This creates a discipline that makes an unseekable reading
       stream seekable.




                          05 August 1999                       34





SFIO(3)                                                   SFIO(3)


   iinntt ssffddccssllooww((SSffiioo__tt** ff))
       This creates a discipline that makes all  Sfio  operations
       return immediately on interrupts. This is useful for deal-
       ing with slow devices.


   iinntt ssffddccssuubbssttrreeaamm((SSffiioo__tt** ff,, SSffiioo__tt** ppaarreenntt,,  SSffooffff__tt  ooffffsseett,,
       SSffooffff__tt eexxtteenntt))
       This  creates a discipline that makes f acts as if it cor-
       responds exactly to the subsection of parent  starting  at
       offset with size extent.


   iinntt ssffddcctteeee((SSffiioo__tt** ff,, SSffiioo__tt** tteeee))
       This  creates  a  discipline that copies to the stream tee
       any data written to f.


   iinntt ssffddccuunniioonn((SSffiioo__tt** ff,, SSffiioo__tt**** aarrrraayy,, iinntt nn))
       This creates a discipline that makes f act as if it is the
       concatenation of the n streams given in array.



   SSTTDDIIOO--CCOOMMPPAATTIIBBIILLIITTYY
       Sfio  provides  two  compatibility packages to Stdio-based
       applications, a source level interface and a binary  level
       library.   These  packages provide a union of functions in
       popular Stdio implementations.

       The  source  Stdio-compatibility  interface  provides  the
       header  file  stdio.h  that  defines  a  set  of macros or
       inlined functions to map Stdio calls to Sfio  ones.   This
       mapping  may benignly extend or change the meaning of cer-
       tain original Stdio operations. For  example,  the  Sfio's
       version  of  popen()  allows  a coprocess to be opened for
       both reading and writing unlike the  original  call  which
       only  allows  a  coprocess to be opened for a single mode.
       Similarly, the Sfio's fopen() call can be used  to  create
       string streams in addition to file streams.

       The  binary  Stdio-compatibility library, libstdio.a, pro-
       vides a complete implementation of Stdio  functions  suit-
       able for linking applications already compiled with native
       header stdio.h.  Functions in this implementation are also
       slightly altered or extended as discussed above.

       Below are the supported Stdio functions:

       FILE*  fopen(const char* file, const char* mode);
       FILE*  freopen(const char* file, const char* mode, FILE* stream);
       FILE*  fdopen(int filedesc, const char* mode);
       FILE*  popen(const char* command, const char* mode);
       FILE*  tmpfile();



                          05 August 1999                       35





SFIO(3)                                                   SFIO(3)


       int    fclose(FILE* stream);
       int    pclose(FILE* stream);

       void   setbuf(FILE* stream, char* buf);
       int    setvbuf(FILE* stream, char* buf, int mode, size_t size);
       void   setbuffer(FILE* stream, char* buf, size_t size);
       int    setlinebuf(FILE* stream);
       int    fflush(FILE* stream);
       int    fpurge(FILE* stream);

       int    fseek(FILE* stream, long offset, int whence);
       void   rewind(FILE* stream);
       int    fgetpos(FILE* stream, fpos_t* pos);
       int    fsetpos(FILE* stream, fpos_t* pos);
       long   ftell(FILE* stream);

       int    getc(FILE* stream);
       int    fgetc(FILE* stream);
       int    getchar(void);
       int    ungetc(int c, FILE* stream);
       int    getw(FILE* stream);
       char*  gets(char* s);
       char*  fgets(char* s, int n, FILE* stream);
       size_t fread(Void_t* ptr, size_t size, size_t nelt, FILE* stream);

       int    putc(int c, FILE* stream);
       int    fputc(int c, FILE* stream);
       int    putchar(int c);
       int    putw(int w, FILE* stream);
       int    puts(const char* s, FILE* stream);
       int    fputs(const char* s, FILE* stream);
       size_t fwrite(const Void_t* ptr, size_t size, size_t nelt, FILE* stream);

       int    fscanf(FILE* stream, const char* format, ...);
       int    vfscanf(FILE* stream, const char* format, va_list args);
       int    _doscan(FILE* stream, const char* format, va_list args);
       int    scanf(const char* format, ...);
       int    vscanf(const char* format, va_list args);
       int    sscanf(const char* s, const char* format, ...);
       int    vsscanf(const char* s, const char* format, va_list args);

       int    fprintf(FILE* stream, const char* format, ...);
       int    vfprintf(FILE* stream, const char* format, va_list args);
       int    _doprnt(FILE* stream, const char* format, va_list args);
       int    printf(const char* format, ...);
       int    vprintf(const char* format, va_list args);
       int    sprintf(const char* s, const char* format, ...);
       int    snprintf(const char* s, int n, const char* format, ...);
       int    vsprintf(const char* s, const char* format, va_list args);
       int    vsnprintf(const char* s, int n, const char* format, va_list args);

       int    feof(FILE* stream);
       int    ferror(FILE* stream);
       int    clearerr(FILE* stream);



                          05 August 1999                       36





SFIO(3)                                                   SFIO(3)


   RREECCEENNTT CCHHAANNGGEESS
       A  few  exception  types  have  been added. In particular,
       exception handlers  shall  be  raised  with  SF_LOCKED  on
       accessing  a  locked  stream.  Before a process exits, the
       event SF_ATEXIT is raised for each open stream.

       A number of disciplines have been added for  various  pro-
       cessing  functions.   Of  interests are disciplines to use
       the direct I/O feature on IRIX6.2, read  DOS  text  files,
       and decompress files compressed by Unix _c_o_m_p_r_e_s_s.

       Various new stream and function flags have been added. For
       example, the third argument of sfgetr() is now  a  set  of
       bit  flags and not just a three-value object. However, the
       old semantics of this argument of sfgetr() is  still  sup-
       ported.

       The    sfopen()   call   has   been   extended   so   that
       sfopen(f,NULL,mode) can be used to changed the mode  of  a
       file  stream before any I/O operations.  This is most use-
       ful for changing the modes of the standard streams.

       The buffering strategy has been significantly enhanced for
       streams  that perform many seek operations. Also, the han-
       dling of stream and file positions have been better clari-
       fied  so  that  applications  that  share file descriptors
       across streams and/or processes can be sure that the  file
       states will be consistent.


AAUUTTHHOORRSS
       Kiem-Phong Vo, kpv@research.att.com,
       David G. Korn, dgk@research.att.com, and
       Glenn S. Fowler, gsf@research.att.com.























                          05 August 1999                       37



CVSTrac 2.0.1