Annotation of researchv10dc/cmd/odist/pax/man/man3/sfio.3, revision 1.1

1.1     ! root        1: .TH SFIO 3 "21 August 1990"
        !             2: .SH NAME
        !             3: \fBsfio\fR \- safe/fast string/file input/output
        !             4: .SH SYNOPSIS
        !             5: .ta .75i 1.5i 2.25i 3i 3.75i 4.5i 5.25i 6i
        !             6: .PP
        !             7: .nf
        !             8: .ft 5
        !             9: #include       <sfio.h>
        !            10: 
        !            11: #define uchar  unsigned char
        !            12: #define uint   unsigned int
        !            13: #define ulong  unsigned long
        !            14: 
        !            15: Sfile_t*       sfnew(Sfile_t* f, uchar* buf, int size, int fd, int flags);
        !            16: Sfile_t*       sfopen(Sfile_t* f, char* string, char* mode);
        !            17: Sfile_t*       sfdopen(int fd, char* mode);
        !            18: Sfile_t*       sfpopen(char* cmd, char* mode, Sfile_t** fcomp);
        !            19: Sfile_t*       sfstack(Sfile_t* base, Sfile_t* top);
        !            20: Sfile_t*       sfpushed(Sfile_t* f);
        !            21: Sfile_t*       sftmp(int size);
        !            22: 
        !            23: int    sfpool(Sfile_t* f, Sfile_t* poolf, int mode);
        !            24: Sfdisc_t*      sfsetdisc(Sfile_t* f, Sfdisc_t* disc);
        !            25: 
        !            26: int    sfclose(Sfile_t* f);
        !            27: int    sfsync(Sfile_t* f);
        !            28: 
        !            29: int    sfpeek(Sfile_t* f, uchar** bufp);
        !            30: 
        !            31: int    sfgetc(Sfile_t* f);
        !            32: int    sfungetc(Sfile_t* f, int c);
        !            33: ulong  sfgetu(Sfile_t* f);
        !            34: long   sfgetl(Sfile_t* f);
        !            35: double sfgetd(Sfile_t* f);
        !            36: char*  sfgets(Sfile_t* f, char* buf, int size);
        !            37: int    sfread(Sfile_t* f, uchar* buf, int n);
        !            38: int    sfscanf(Sfile_t* f, char* format, ...);
        !            39: int    sfsscanf(char* s, char* format, ...);
        !            40: int    sfvscanf(Sfile_t* f, char* format, va_list args);
        !            41: 
        !            42: int    sfputc(Sfile_t* f, int c);
        !            43: int    sfnputc(Sfile_t* f, int c, int n);
        !            44: int    sfputu(Sfile_t* f, ulong v);
        !            45: int    sfputl(Sfile_t* f, long v);
        !            46: int    sfputd(Sfile_t* f, double v);
        !            47: int    sfputs(Sfile_t* f, char* s, int c);
        !            48: int    sfwrite(Sfile_t* f, uchar* buf, int n);
        !            49: int    sfmove(Sfile_t* fr, Sfile_t* fw, long n, char* seps);
        !            50: int    sfprintf(Sfile_t* f, char* format, ...);
        !            51: int    sfsprintf(char* s, int size, char* format, ...);
        !            52: int    sfvprintf(Sfile_t* f, char* format, va_list args);
        !            53: 
        !            54: void   sfnotice(void (*noticef)(Sfile_t* f, int type));
        !            55: int    sfset(Sfile_t* f, int flags, int i);
        !            56: uchar* sfsetbuf(Sfile_t* f, uchar* buf, int size);
        !            57: int    sffileno(Sfile_t* f);
        !            58: int    sfeof(Sfile_t* f);
        !            59: int    sferror(Sfile_t* f);
        !            60: int    sfclearerr(Sfile_t* f);
        !            61: int    sfclrlock(Sfile_t* f);
        !            62: int    sfslen();
        !            63: int    sfulen(ulong v);
        !            64: int    sfllen(long v);
        !            65: int    sfdlen(double v);
        !            66: 
        !            67: long   sforigin(Sfile_t* f);
        !            68: long   sfseek(Sfile_t* f, long addr, int offset);
        !            69: long   sftell(Sfile_t* f);
        !            70: 
        !            71: char*  sfecvt(double v, int n, int* decpt, int* sign);
        !            72: char*  sffcvt(double v, int n, int* decpt, int* sign);
        !            73: .fR
        !            74: .fi
        !            75: .SH DESCRIPTION
        !            76: .PP
        !            77: \fIsfio\fP is a library of functions to perform input/output on
        !            78: objects called \fIsfio\fP streams.
        !            79: Each \fIsfio\fP stream may correpond to some file descriptor (see \fIopen(2)\fP)
        !            80: or some piece of primary memory.
        !            81: A notion of stream stack is supported for
        !            82: processing of data from complexes of streams.
        !            83: Streams can be pooled so that their buffers can be synchronized
        !            84: properly when switching streams for io.
        !            85: It is also possible to change io disciplines by setting alternative
        !            86: functions for read, write and seek.
        !            87: .PP
        !            88: A stream abstraction is represented by the type \f5Sfile_t\fP which
        !            89: is defined in the header file \f5<sfio.h>\fP. A stream is locked while
        !            90: it is being accessed by some \fIsfio\fP function. A locked stream
        !            91: cannot be further accessed by operations that may change its internal states
        !            92: (see \f5sfclrlock()\fP). Any such access fails and returns
        !            93: an appropriate error code.
        !            94: .PP
        !            95: During an io request, if
        !            96: a system call \f5read\fP or \f5write()\fP (or their
        !            97: discipline counterparts) is interrupted,
        !            98: unless a discipline function has been defined to process it,
        !            99: the calling \fIsfio\fP function will resume the respective system call as necessary.
        !           100: The interrupt condition is defined by \f5errno\ ==\ EINTR\fP (see \f5errno.h\fP).
        !           101: To prevent infinite loops, this condition is always cleared before
        !           102: the system call is resumed.
        !           103: .PP
        !           104: In general, \fIsfio\fP functions either return integer or pointer values.
        !           105: In the event of an error, a function that returns integer value will
        !           106: return \f5-1\fP while a function that returns a pointer value will return
        !           107: \f5NULL\fP.
        !           108: .PP
        !           109: A number of bit flags define stream types and their operations.
        !           110: Following are the flags:
        !           111: .IP
        !           112: \f5SF_READ\fP:
        !           113: The stream is readable.
        !           114: .IP
        !           115: \f5SF_WRITE\fP:
        !           116: The stream is writable.
        !           117: .IP
        !           118: \f5SF_STRING\fP:
        !           119: The stream is a string (a byte array) that
        !           120: is readable if \f5SF_READ\fP is specified or
        !           121: writable if \f5SF_WRITE\fP is specified.
        !           122: .IP
        !           123: \f5SF_APPEND\fP:
        !           124: The stream is a file opened for appending data.
        !           125: This means that data written to the stream is always
        !           126: appended at the end of the file.
        !           127: On operating systems where there is no primitive to specify
        !           128: at file opening time that a file is opened for append only,
        !           129: \f5lseek()\fP (or its discipline replacement) will be used on
        !           130: the file stream to approximate this behavior.
        !           131: .IP
        !           132: \f5SF_RELATIVE\fP:
        !           133: If the stream corresponds to a file,
        !           134: no seek is allowed backward beyond the starting point as defined
        !           135: by \f5lseek(fd,0L,1)\fP (or its discipline replacement)
        !           136: when the stream is initialized by \f5sfnew()\fP (below).
        !           137: .IP
        !           138: \f5SF_LINE\fP:
        !           139: The stream is line-oriented. For write-streams, this means that the
        !           140: buffer is flushed whenever a new-line character is output.
        !           141: For read-streams, this means that \f5sfpeek()\fP (below) will return
        !           142: a buffer of data which ends with a new-line. Note that the amount of
        !           143: data that can be returned is limited by the buffer size.
        !           144: .IP
        !           145: \f5SF_KEEPFD\fP:
        !           146: The file descriptor of the stream will be kept opened when the stream is closed.
        !           147: .IP
        !           148: \f5SF_MALLOC\fP:
        !           149: To indicate that the stream buffer was obtained via \f5malloc()\fP
        !           150: and can be reallocated or freed by the package.
        !           151: .IP
        !           152: \f5SF_REUSE\fP:
        !           153: This flag can be set (\f5sfset()\fP so that when the stream is closed,
        !           154: its data structure and associated information such as pool and discipline
        !           155: is not destroyed.
        !           156: It can also be used in a call to \f5sfnew()\fP (see below).
        !           157: .IP
        !           158: \f5SF_SHARE\fP:
        !           159: This flag indicates that the associated stream is a file stream that may
        !           160: be operated on by means beyond straightforward \fIsfio\fP usage (e.g.,
        !           161: by multiple processes).
        !           162: In this case, each io system call (or its discipline replacement) will be
        !           163: preceded by a \f5lseek()\fP (or its discipline replacement) to ensure that
        !           164: the logical stream location corresponds to the physical file location.
        !           165: .PP
        !           166: \f5sfnew(f,buf,size,fd,flags)\fP
        !           167: is the primitive for creating or renewing streams.
        !           168: For file streams, a number of operations are performed to determine
        !           169: seekability, optimal buffer sizes if not specified, etc.
        !           170: Each stream has a origin.
        !           171: The origin of a \f5SF_STRING\fP stream is always \f50L\fP.
        !           172: If a file stream is not seekable, its origin is defined as \f5-1L\fP.
        !           173: Otherwise, its origin is defined as either the current location or \f50L\fP
        !           174: depending on whether or not the flag \f5SF_RELATIVE\fP is turned on.
        !           175: \f5sfseek()\fP operations are relative to this location.
        !           176: The argument \f5f\fP of \f5sfnew()\fP, if not \f5NULL\fP, is a stream to be modified.
        !           177: If it is \f5NULL\fP, a new stream is created.
        !           178: The argument \f5buf\fP, if not \f5NULL\fP, is a buffer to be used.
        !           179: In this case, \f5size\fP should be positive.
        !           180: If \f5size\fP is 0, the stream is unbuffered.
        !           181: If \f5size\fP is negative, \fIsfio\fP will allocate a buffer.
        !           182: The argument \f5fd\fP is a file descriptor (e.g., from \fIopen()\fP)
        !           183: for io operations if the stream is not an \f5SF_STRING\fP stream.
        !           184: The last argument \f5flags\fP is a bit vector composing from the flags described above.
        !           185: The \f5SF_REUSE\fP flag, if given, indicates that the current attributes
        !           186: of the stream \f5f\fP should be used instead of whatever else is defined by \f5flags\fP.
        !           187: .PP
        !           188: \f5sfopen(f,string,mode)\fP
        !           189: is a high-level function based on \f5sfnew()\fP to create new streams from files
        !           190: or strings.
        !           191: The argument \f5f\fP for \f5sfopen()\fP,
        !           192: if not \f5NULL\fP, is a currently opened stream to be
        !           193: closed and replaced by a new stream corresponding to the object \f5string\fP.
        !           194: The argument \f5mode\fP can be any one of: \f5"r"\fP, \f5"r+"\fP,
        !           195: \f5"w"\fP, \f5"w+"\fP, \f5"a"\fP, \f5"a+"\fP, \f5s\fP and \f5s+\fP.
        !           196: The \f5r\fP, \f5w\fP, and \f5a\fP specify read, write and append mode for file streams.
        !           197: In these cases, the argument \f5string\fP defines a path name to a file.
        !           198: The \f5s\fP specifies that \f5string\fP is a nul-terminated string to be opened for read.
        !           199: The \f5+\fP means that the new stream will be opened for both reading and writing.
        !           200: .PP
        !           201: \f5sfdopen(fd,mode)\fP makes a stream using the file descriptor \f5fd\fP.
        !           202: The \f5mode\fP argument is used in the same way as in \f5sfopen()\fP.
        !           203: .PP
        !           204: \f5sfpopen(cmd,mode,fcomp)\fP
        !           205: opens a stream \f5f\fP which is a pipe to (from) the command \f5cmd\fP
        !           206: if the mode is \f5"w"\fP (\f5"r"\fP). If the mode is \f5"w+"\fP or \f5"r+"\fP,
        !           207: another stream for the opposite operation is created and returned in \f5fcomp\fP.
        !           208: Note that if either of these streams is closed, the other is also closed.
        !           209: .PP
        !           210: \f5sfstack(base,top)\fP is used to push or pop stream stacks.
        !           211: Each stream stack is identified by a \f5base\fP stream
        !           212: via which all io operations are performed.
        !           213: Other streams on the stack are locked so that operations that may change
        !           214: their internal states are forbidden.
        !           215: The type of operations that can be done on a stack is defined by
        !           216: the top level stream. If an io operation is performed and the top level stream
        !           217: reaches the end of file condition or an error condition other than interrupts,
        !           218: it is automatically popped and closed (see also \f5sfsetdisc\fP for alternative
        !           219: handling of these conditions).
        !           220: The first argument of \f5sfstack()\fP specifies the \f5base\fP stream.
        !           221: The second argument, \f5top\fP, if not \f5NULL\fP,
        !           222: is pushed on top of the current top stream.
        !           223: In this case, the \f5base\fP stream pointer is returned.
        !           224: If \f5top\fP is \f5NULL\fP, the stack is popped  and the pointer to
        !           225: the popped stream is returned.
        !           226: .PP
        !           227: \f5sfpushed(f)\fP returns the pointer to the stream pushed below \f5f\fP.
        !           228: .PP
        !           229: \f5sftmp(size)\fP creates a stream for writing and reading temporary data.
        !           230: If \f5size\fP is negative, the stream is a pure \f5SF_STRING\fP stream.
        !           231: Otherwise, the stream is originally created as a \f5SF_STRING\fP stream
        !           232: with a buffer of the given \f5size\fP. A discipline is set so that
        !           233: when this buffer is exhausted, a real temporary file will be created.
        !           234: Any attempt to change this discipline will also cause the temporary file
        !           235: to be created.
        !           236: .PP
        !           237: \f5sfpool(f,poolf,mode)\fP manages pools of streams.
        !           238: In a pool of streams, only one stream is current.
        !           239: A stream becomes current when it is used for some io operation.
        !           240: When a new stream is to become current,
        !           241: the current stream is synchronized (see \f5sfsync()\fP)
        !           242: if its type matches the type of the pool.
        !           243: The first argument of \f5sfpool()\fP, \f5f\fP, is the stream to be manipulated.
        !           244: The second argument, \f5poolf\fP, determines the operation to be done on \f5f\fP.
        !           245: If \f5poolf\fP is \f5NULL\fP, \f5f\fP is deleted from its current pool.
        !           246: Otherwise, \f5f\fP is put into the same pool with \f5poolf\fP.
        !           247: If \f5poolf\fP is already in a pool, the third argument is ignored.
        !           248: Otherwise, it determines the type of the new pool.
        !           249: \f5mode\fP can be constructed by bitwise or-ing of \f5SF_READ\fP and \f5SF_WRITE\fP.
        !           250: .PP
        !           251: \f5sfsetdisc(f,disc)\fP changes
        !           252: the io-discipline of the stream \f5f\fP, i.e.,
        !           253: to specify alternative functions for read, write, seek, and to handle exceptions.
        !           254: The default discipline consists of the system calls \f5read()\fP, \f5write()\fP,
        !           255: and \f5lseek()\fP.
        !           256: The \f5disc\fP argument is either \f5NULL\fP to reset to the default discipline
        !           257: or a pointer to a \f5Sfdisc_t\fP structure which contains the following fields:
        !           258: .PP
        !           259: .nf
        !           260:        \f5int  (*readf)();\fP
        !           261:        \f5int  (*writef)();\fP
        !           262:        \f5long (*seekf)();\fP
        !           263:        \f5int  (*exceptf)();\fP
        !           264:        \f5void*        handle;\fP
        !           265: .fi
        !           266: .PP
        !           267: The first three fields of \f5Sfdisc_t\fP specify alternative io functions.
        !           268: If any of them is \f5NULL\fP, the corresponding system call is used.
        !           269: A discipline io function, say \f5(*readf)()\fP,
        !           270: is called with 4 arguments.
        !           271: The first argument is the stream pointer.
        !           272: The second and third arguments correspond to the second and third arguments
        !           273: of the respected system call.
        !           274: The fourth argument is the \f5handle\fP field of \f5Sfdisc_t\fP.
        !           275: The exception function, \f5(*exceptf)()\fP, if provided, is called
        !           276: when an exception happens during a read/write operation, when a stream
        !           277: is being closed, or when the discipline is being reset.
        !           278: A read/write operation is said to cause an exception if its return value
        !           279: is zero or negative. It is up to the exception function to determine
        !           280: the type of exception (for example, by examining \f5errno\fP).
        !           281: When \f5(*exceptf)()\fP is called, the stream will be opened for general operations.
        !           282: However, \f5(*exceptf)()\fP should not attempt to close the stream.
        !           283: \f5(*exceptf)()\fP is called as:
        !           284: \f5(*exceptf)(f,type,handle)\fP. \f5type\fP is:
        !           285: \f50\fP when the discipline is being reset,
        !           286: \f5SF_EOF\fP when the stream is being closed,
        !           287: \f5SF_READ\fP when an exception happens during a read operation, and
        !           288: \f5SF_WRITE\fP when an exception happens during a write operation.
        !           289: For the cases of \f5SF_READ\fP and \f5SF_WRITE\fP,
        !           290: the executing \fIsfio\fP function will examine the return value of \f5(*exceptf)()\fP
        !           291: for further actions:
        !           292: \fInegative\fP for immediate return,
        !           293: \fIzero\fP for executing default actions associated with the exception,
        !           294: and \fIpositive\fP for resuming execution.
        !           295: Note that a \f5SF_STRING\fP stream does not perform external io so the
        !           296: io functions are not used. However, an exception occurs whenever
        !           297: an io operation exceeds the stream buffer boundary and
        !           298: \f5(*exceptf)()\fP, if defined, will be called as appropriate.
        !           299: \f5sfsetdisc()\fP returns the pointer to the previous discipline
        !           300: or \f5NULL\fP if an error happened.
        !           301: Finally, it is the application's responsibility to manage the space used
        !           302: by the \f5Sfdisc_t\fP structures.
        !           303: .PP
        !           304: \f5sfclose(f)\fP closes the given stream \f5f\fP and frees up its resources.
        !           305: If \f5f\fP is \f5NULL\fP, all streams are closed.
        !           306: If \f5f\fP is a stack of streams, all streams on the stack are closed.
        !           307: If \f5f\fP is a \f5sfpopen\fP-stream, its companion stream, if any, is also closed.
        !           308: Further, \f5sfclose()\fP will wait until the associated command terminates,
        !           309: then return its exit status.
        !           310: A few file flags affect the behavior of \f5sfclose()\fP.
        !           311: If \f5SF_KEEPFD\fP is on, the underlying file descriptor is not closed.
        !           312: If \f5SF_REUSE\fP is on, \f5sfclose()\fP will only synchronize the buffer
        !           313: and close the file descriptor (subject to \f5SF_KEEPFD\fP).
        !           314: The stream structure is left intact, including
        !           315: pool (\f5sfpool()\fP) or discipline (\f5sfsetdisc()\fP) information.
        !           316: .PP
        !           317: \f5sfsync(f)\fP causes the physical file pointer of the stream
        !           318: \f5f\fP to correspond to its logical position.
        !           319: If \f5f\fP is the base of a stack of streams, all streams on the stack
        !           320: are synchronized. Further, a stacked stream can only be synchronized
        !           321: via its base stream.
        !           322: .PP
        !           323: \f5sfpeek(f,bufp)\fP provides a safe method for enquiring
        !           324: information on the internal buffer of a stream.
        !           325: If \f5bufp\fP is \f5NULL\fP, \f5sfpeek()\fP simply returns the amount of data
        !           326: available in the buffer to read if \f5f\fP is in read mode
        !           327: or the amount of buffer available to write if \f5f\fP is in write mode.
        !           328: If \f5bufp\fP is not \f5NULL\fP, \f5sfpeek()\fP provides access to the buffer.
        !           329: For a read stream, if the buffer is empty, it is filled and,
        !           330: for a write-stream, if the buffer is full, it is flushed.
        !           331: Then, for a read stream, \f5bufp\fP is set to the place in the buffer
        !           332: where data is available and, for a write stream,
        !           333: it is set to where data can be written.
        !           334: The return value of \f5sfseek()\fP indicates how much data or space is available
        !           335: in the buffer. However, if the stream is in \f5SF_LINE|SF_READ\fP mode,
        !           336: the return value will be the data length up to and including the new-line character.
        !           337: In this case, if there is not a new-line character in the buffered data,
        !           338: more data may be read.
        !           339: Note that the buffer location is not advanced by \f5sfpeek()\fP.
        !           340: That must be done by a regular io call such as \f5sfread\fP or \f5sfwrite\fP on
        !           341: the pointer returned in \f5bufp\fP.
        !           342: Finally, \f5sfpeek()\fP treats a read/write-stream like a read-stream
        !           343: (however, see also \f5sfset()\fP).
        !           344: .PP
        !           345: \f5sfgetc(f)\fP returns a byte from the stream \f5f\fP or -1 when an end-of-file
        !           346: or error condition is encountered.
        !           347: .PP
        !           348: \f5sfungetc(f,c)\fP puts the byte \f5c\fP back into the stream \f5f\fP.
        !           349: This is guaranteed to work only after a \f5sfgetc()\fP call.
        !           350: .PP
        !           351: \f5sfgetu(f)\fP, \f5sfgetl(f)\fP, and \f5sfgetd(f)\fP return
        !           352: an \fIunsigned long\fP, a \fIlong\fP value, or a \fIdouble\fP value
        !           353: that was coded in a portable fashion
        !           354: (see \f5sfputu()\fP, \f5sfputl()\fP, and \f5sfputd()\fP).
        !           355: If there is not enough data to decode a value,
        !           356: these functions will return \f5-1\fP and the stream is set in an error state
        !           357: (\f5see \f5sferror()\fP).
        !           358: .PP
        !           359: \f5sfgets(f,buf,size)\fP reads a line of input from the stream \f5f\fP.
        !           360: If \f5buf\fP is not \f5NULL\fP and \f5size\fP is positive, \f5sfgets\fP
        !           361: reads up to \f5size-1\fP characters into the buffer \f5buf\fP.
        !           362: Otherwise, the characters are read into a static area that is dynamically
        !           363: grown as necessary. Thus, in this case, there is no limit to line length.
        !           364: A nul-character is appended after the input characters.
        !           365: \f5sfgets()\fP returns the pointer to the new string or \f5NULL\fP when
        !           366: no data was read due to end-of-file or an error condition.
        !           367: After a string is read, its length can be found using \f5sfslen()\fP.
        !           368: .PP
        !           369: \f5sfread(f,buf,n)\fP reads up to \f5n\fP bytes from the stream \f5f\fP and
        !           370: stores them in the given buffer \f5buf\fP.
        !           371: It returns the number of bytes actually read.
        !           372: .PP
        !           373: \f5sfscanf(f,format,...)\fP scans a number of items from the stream \f5f\fP.
        !           374: The item types are determined from the string \f5format\fP.
        !           375: See \fIfscanf()\fP (UNIX User's Manual, Section 3) for details on predefined formats.
        !           376: The standardly supported formats are:
        !           377: \f5i, I, d, D, u, U, o, O, x, X, f, F, e, E, g, G, c, %, s,\fP and \f5[]\fP.
        !           378: The \f5sfscanf()\fP interface also supports additional formats as described below.
        !           379: .IP
        !           380: The pattern \f5%&\fP indicates that the next argument in the argument list of
        !           381: \f5sfscanf()\fP is a function, say \f5(*extf)()\fP, to process patterns that are not
        !           382: predefined by the \f5sfscanf()\fP interface.
        !           383: The prototype of \f5(*extf)()\fP is:
        !           384: .nf
        !           385:        \f5int (*extf)(Sfile_t* f, int fmt, int length, char** rv);\fP
        !           386: .fi
        !           387: \f5f\fP is the same input stream passed to \f5sfvscanf\fP.
        !           388: \f5fmt\fP is the pattern to be processed.
        !           389: \f5length\fP, if non-negative, is the maximum number of input bytes
        !           390: to be read in processing the pattern,
        !           391: \f5rv\fP is used to return the ``address'' of the value to be assigned.
        !           392: \f5(*extf)()\fP returns the size of the value to be assigned.
        !           393: A negative return value from \f5(*extf)()\fP means that the specified pattern
        !           394: cannot be handled. This pattern is treated as if it is not matched.
        !           395: .IP
        !           396: The pattern \f5%@\fP indicates that the next argument in the argument list \f5args\fP
        !           397: is a function, say \f5(*argf)()\fP, to process the values of matched patterns.
        !           398: The prototype of \f5(*argf)()\fP is:
        !           399: .nf
        !           400:        \f5int (*argf)(int fmt, char* value, int n)\fP;
        !           401: .fi
        !           402: If the return value of \f5(*argf)()\fP is negative, the processing
        !           403: of the current format string will be stopped (see \f5%$\fP below).
        !           404: \f5fmt\fP determines the type of \f5value\fP: \f5f\fP for \fIfloat\fP,
        !           405: \f5F\fP for \fIdouble\fP, \f5h\fP for \fIshort\fP, \f5d\fP for \fIint\fP,
        !           406: \f5D\fP for \fIlong\fP, \f5s\fP for \fIchar*\fP. Any other value for \f5fmt\fP
        !           407: means that it is an extended pattern and \f5value\fP contains an address
        !           408: to the scanned value. \f5n\fP contains the size of the object if it is a
        !           409: primitive type. If the object is \f5char*\fP or the address of the scanned
        !           410: value of an extended format, \f5n\fP is the length of this object.
        !           411: .IP
        !           412: The pattern \f5%:\fP indicates that the next two arguments in the argument list
        !           413: \f5args\fP define a new pair of format string and a list of arguments of
        !           414: the type \f5va_list\fP (see \f5varargs.h\fP or \f5stdarg.h\fP).
        !           415: The new pair is pushed on top of the stack and the scanning process continues with them.
        !           416: The top pair of format string and argument list is popped when the processing
        !           417: of the format string is stopped. When a new pair is stacked,
        !           418: \f5(*argf)()\fP and \f5(*extf)()\fP are inherited.
        !           419: They are reset when the stack is popped.
        !           420: .PP
        !           421: \f5sfsscanf(s,format,...)\fP is similar to \f5sfscanf()\fP
        !           422: but it scans data from the string \f5s\fP.
        !           423: .PP
        !           424: \f5sfvscanf(f,format,args)\fP is the primitive underlying \f5sfscanf()\fP
        !           425: and \f5sfscanf()\fP. It also provides a portable variable argument interface.
        !           426: Programs that use \f5sfvscanf()\fP must include either of \f5varargs.h\fP
        !           427: or \f5stdargs.h\fP as appropriate.
        !           428: .PP
        !           429: \f5sfputc(f,c)\fP writes the byte \f5c\fP to the stream \f5f\fP.
        !           430: .PP
        !           431: \f5sfnputc(f,c,n)\fP writes the byte \f5c\fP to the stream \f5f\fP \f5n\fP times.
        !           432: It returns the number of bytes successfully written.
        !           433: .PP
        !           434: \f5sfputu(f,v)\fP, \f5sfputl(f,v)\fP write the \fIunsigned long\fP or \fIlong\fP
        !           435: value \f5v\fP in a format that is byte-order transparent.
        !           436: \f5sfputd(f,v)\fP writes the \fIdouble\fP value \f5v\fP in a portable format.
        !           437: Portability across two different machines
        !           438: requires that the bit order in a byte is the same on both machines.
        !           439: \f5sfputd()\fP also relies on the functions \f5ldexp()\fP and \f5frexp()\fP
        !           440: (See \fIfrexp.3\fP) for coding.
        !           441: Upon success, \f5sfputu()\fP, \f5sfputl()\fP and \f5sfputd()\fP
        !           442: return the number of bytes output.
        !           443: .PP
        !           444: \f5sfputs(f,s,c)\fP writes the null-terminated string \f5s\fP to the stream \f5f\fP.
        !           445: If \f5c\fP is not 0, it is a character to be appended after the string has been output.
        !           446: \f5sfputs()\fP returns the number of bytes written.
        !           447: .PP
        !           448: \f5sfwrite(f,buf,n)\fP writes out \f5n\fP bytes from the buffer \f5buf\fP to the
        !           449: stream \f5f\fP. It returns the number of bytes written.
        !           450: .PP
        !           451: \f5sfmove(fr,fw,n,seps)\fP moves \f5n\fP objects
        !           452: from the stream \f5fr\fP to the stream \f5fw\fP.
        !           453: If either \f5fr\fP or \f5fw\fP is \f5NULL\fP, it acts
        !           454: as if it is a stream corresponding to \fI/dev/null\fP.
        !           455: If \f5n\fP is \f5<0\fP, all of \f5fr\fP is moved.
        !           456: If \f5seps\fP is \f5NULL\fP or an empty string, the objects to be moved are bytes.
        !           457: Otherwise, the moved objects are records separated by bytes defined in \f5seps\fP.
        !           458: In \f5seps\fP, if the first two bytes is \f5\e0\fP, it is mapped to the zero byte.
        !           459: All other cases map a byte to itself.
        !           460: \f5sfmove()\fP returns the number of objects moved.
        !           461: .PP
        !           462: \f5sfprintf(f,format,...)\fP writes out data in
        !           463: a format as defined by the string \f5format\fP.
        !           464: See \fIfprintf()\fP (UNIX User's Manual, Section 3) for details on predefined
        !           465: conversion formats.
        !           466: The standardly supported formats are:
        !           467: \f5n, s, c, %, h, i, d, p, u, o, x, X, g, G, e, E, f,\fP and \f5F\fP.
        !           468: \f5sfprintf()\fP also supports additional formats as described below.
        !           469: .IP
        !           470: The pattern \f5%&\fP indicates that the next argument
        !           471: is a function, say \f5(*extf)()\fP, to interpret patterns not yet defined
        !           472: by \f5sfprintf()\fP.
        !           473: The prototype of \f5(*extf)()\fP is:
        !           474: .nf
        !           475:        \f5int (*extf)(void* value, int fmt, int precis, char** sp);\fP
        !           476: .fi
        !           477: \f5value\fP is the value to be formatted.
        !           478: \f5fmt\fP is the pattern to format the value.
        !           479: \f5precis\fP is the amount of precision required.
        !           480: \f5sp\fP is used to return the address of a string containing the formatted value.
        !           481: If upon returning from \f5(*extf)()\fP, \f5*sp\fP is \f5NULL\fP, the pattern \f5fmt\fP
        !           482: is treated as if it is not matched.
        !           483: Otherwise, the return value of \f5(*extf)()\fP, if nonnegative, is taken as the length
        !           484: of the string returned in \f5sp\fP. If not, the string is considered null-terminated.
        !           485: The string \f5*sp\fP is processed as if the pattern \f5`s'\fP was specified.
        !           486: .IP
        !           487: The pattern \f5%@\fP indicates that the next argument is a function, say \f5(*argf)()\fP,
        !           488: to get arguments. As long as \f5(*argf)()\fP is defined, the argument list is ignored.
        !           489: The prototype of \f5(*argf)()\fP is:
        !           490: .nf
        !           491:        \f5int (*argf)(int fmt, char* val)\fP;
        !           492: .fi
        !           493: \f5fmt\fP is the pattern to be processed.
        !           494: Following are ASCII characters and corresponding types:
        !           495: \f5@\fP for getting a new \f5(*argf)()\fP,
        !           496: \f5&\fP for getting a new \f5(*extf)()\fP,
        !           497: \f51\fP for getting a new format string for stacking,
        !           498: \f52\fP for getting a new argument list for stacking,
        !           499: \f5d\fP for \fIint\fP,
        !           500: \f5D\fP for \fIlong\fP,
        !           501: \f5f\fP for \fIfloat\fP,
        !           502: \f5F\fP for \f5double\fP, and
        !           503: \f5s\fP for \fIchar*\fP.
        !           504: If \f5(*extf)()\fP is defined, and an undefined pattern is encountered,
        !           505: \f5(*argf)()\fP will be called with this pattern.
        !           506: \f5val\fP is an address to store the value to be formatted.
        !           507: The return value of \f5(*argf)()\fP, if negative, stops the processing
        !           508: of the current format (see below).
        !           509: .IP
        !           510: The pattern \f5%:\fP indicates that the next two arguments define
        !           511: a pair of format string and argument list of the type \f5va_list\fP.
        !           512: If the argument getting function \f5(*argf)()\fP is already defined,
        !           513: it is called with the argument \f5fmt\fP being the characters
        !           514: \f51\fP and \fP2\fP for the new format string and argument list respectively.
        !           515: The new pair is stacked on top and processing continue from there.
        !           516: The top pair of format string and argument is popped when the format string
        !           517: is exhausted. When a new pair is pushed, \f5(*argf)()\fP and \f5(*extf)()\fP
        !           518: are inherited. When a pair is popped, these functions will be reset.
        !           519: .PP
        !           520: \f5sfsprintf(s,size,format,...)\fP is similar to \f5sfprintf()\fP
        !           521: but it is used to format
        !           522: the character array \f5s\fP which is of size \f5size\fP.
        !           523: The length of the resulting string can be gotten via \f5sfslen()\fP.
        !           524: .PP
        !           525: \f5sfvprintf(f,format,args)\fP is the primitive underlying \f5sfprintf()\fP
        !           526: and \f5sfsprintf()\fP. It provides a portable variable argument interface.
        !           527: Programs that use \f5sfvprintf()\fP must include either of \f5varargs.h\fP
        !           528: or \f5stdargs.h\fP as appropriate.
        !           529: .PP
        !           530: \f5sfnotice(noticef)\fP sets a function \f5(*noticef)()\fP which will
        !           531: be called whenever a stream is created or closed.
        !           532: \f5(*noticef)()\fP is called with two arguments.
        !           533: The first argument is the stream pointer and
        !           534: the second argument is either \f50\fP or \f5SF_EOF\fP to indicate
        !           535: whether the stream is being opened or being closed.
        !           536: .PP
        !           537: \f5sfset(f,flags,i)\fP sets flags or file descriptor for the stream \f5f\fP.
        !           538: If \f5flags\fP is the value \f5SF_EOF\fP, the file descriptor of the stream
        !           539: is changed to the value in \f5i\fP. In this case, \f5sfset()\fP returns \f5-1\fP
        !           540: on error or \f5i\fP on success.
        !           541: If \f5flags\fP is not \f5SF_EOF\fP, it defines a collection of flags to be
        !           542: turned on or off depending on whether \f5i\fP is non-zero or zero.
        !           543: The flags that can be turned on or off are:
        !           544: \f5SF_READ\fP, \f5SF_WRITE\fP,
        !           545: \f5SF_LINE\fP, \f5SF_KEEPFD\fP, \f5SF_REUSE\fP, \f5SF_MALLOC\fP and \f5SF_SHARE\fP.
        !           546: The flags \f5SF_READ\fP and \f5SF_WRITE\fP can be used in a call to \f5sfset()\fP
        !           547: only if the stream \f5f\fP was opened for both read and write.
        !           548: Turning off one of these flags means that the stream is to be treated as
        !           549: if it was opened with the other flag exclusively (see \f5sfpeek()\fP).
        !           550: In this case, \f5sfset()\fP returns the entire set of flags controlling the stream.
        !           551: Thus, the current set of flags can be found by \f5sfset(f,0,0)\fP.
        !           552: .PP
        !           553: \f5sfsetbuf(f,buf,size)\fP changes the current buffer of the stream \f5f\fP to
        !           554: the new buffer \f5buf\fP. If the stream is a \f5SF_WRITE\fP stream,
        !           555: any data still in the current buffer is thrown away.
        !           556: Thus, if an application desires to preserve such data, it should
        !           557: call \f5sfsync()\fP before trying to switch buffers.
        !           558: If \f5size\fP is positive, \f5buf\fP is taken as a buffer of the given size.
        !           559: If \f5size\fP is zero, the stream will be unbuffered.
        !           560: If \f5size\fP is negative, an internal buffer is allocated.
        !           561: \f5sfsetbuf()\fP returns the address of the old buffer.
        !           562: .PP
        !           563: \f5sffileno(f)\fP returns the file descriptor of the stream \f5f\fP.
        !           564: .PP
        !           565: \f5sfeof(f)\fP tells whether there is any more data in the stream \f5f\fP.
        !           566: .PP
        !           567: \f5sforigin(f)\fP returns the origin location in the stream \f5f\fP (see \f5sfnew()\fP).
        !           568: If this location is \f5-1L\fP, the stream is not seekable.
        !           569: Note that the standard streams \f5sfstdin\fP, \f5sfstdout\fP, and \f5sfstderr\fP,
        !           570: though statically allocated, are not initialized until an operation that may
        !           571: affect its internal structure. Thus, the return value \f50L\fP of \f5sforigin()\fP 
        !           572: on such an initialized stream is not reliable.
        !           573: .PP
        !           574: \f5sferror(f)\fP and \f5sfclearerr(f)\fP returns or clears the error condition
        !           575: of the stream \f5f\fP. Note that the error condition of a stream does not prevent
        !           576: further io operations to be performed on them.
        !           577: .PP
        !           578: \f5sfclrlock(f)\fP clears the lock on a locked stream.
        !           579: Though this is unsafe, it is useful for emergency access
        !           580: to a locked stream or to clear a stream left locked because
        !           581: of non-local jumps (e.g., \f5longjmp()\fP).
        !           582: .PP
        !           583: \f5sfslen()\fP returns the length of the string most recently obtained
        !           584: via a \f5sfgets()\fP, \f5sfsprintf()\fP, \f5sfecvt()\fP or \f5sffcvt()\fP call.
        !           585: .PP
        !           586: \f5sfulen(v)\fP, \f5sfllen(v)\fP and \f5sfdlen(v)\fP
        !           587: return the number of bytes required to code the
        !           588: \fIunsigned long\fP, \fIlong\fP or \fIdouble\fP value \f5v\fP.
        !           589: .PP
        !           590: \f5sfseek(f,addr,offset)\fP sets the next read/write location for the stream \f5f\fP
        !           591: at a new address defined by the combination of \f5addr\fP and \f5offset\fP.
        !           592: If \f5offset\fP is 0, \f5addr\fP is offset from the origin of the stream
        !           593: (see \f5sfnew()\fP).
        !           594: If \f5offset\fP is 1, \f5addr\fP is offset from the current location.
        !           595: Note that if \f5f\fP was opened for appending (\f5SF_APPEND\fP) and the last operation
        !           596: done on it was a write operation, the \fIcurrent location\fP is at the physical
        !           597: end of file.
        !           598: If \f5offset\fP is 2, \f5addr\fP is offset from the \fIphysical\fP end of the stream.
        !           599: In all cases, \f5sfseek()\fP is not allowed to seek backward beyond the stream origin.
        !           600: .PP
        !           601: \f5sftell(f)\fP returns the current location in the stream \f5f\fP relative
        !           602: to the stream origin (see \f5sfnew()\fP).
        !           603: As with \f5sfseek()\fP, if \f5f\fP was opened for appending (\f5SF_APPEND\fP)
        !           604: and the last operation done on it was a write operation,
        !           605: the \fIcurrent location\fP is at the physical end of file.
        !           606: If the stream \f5f\fP is unseekable, \f5sftell\fP returns the number of bytes
        !           607: read from or written to \f5f\fP.
        !           608: .PP
        !           609: \f5sfecvt(v,n,decpt,sign)\fP and
        !           610: \f5sffcvt(v,n,decpt,sign)\fP are functions to convert floating values to ASCII.
        !           611: They corresponds to the standard functions \f5ecvt()\fP and \f5fcvt()\fP.
        !           612: The length of the conversion string most recently done by
        !           613: \f5sfecvt()\fP or \f5sffcvt()\fP can be found by \f5sfslen()\fP.
        !           614: .PP
        !           615: .SH HISTORY AND FUTURE CONSIDERATIONS
        !           616: \fIsfio\fP has similar functionality, but is more general
        !           617: than the \fIstdio\fP package.
        !           618: It grows from our dissatisfaction with the awkwardness, fragility
        !           619: and inefficiency in \fIstdio\fP.
        !           620: An example of \fIstdio\fP awkwardness is that
        !           621: even if a stream was opened for read and write,
        !           622: the application code cannot arbitrarily mix read and write operations. 
        !           623: An earlier attempt was made at rewriting \fIstdio\fP.
        !           624: This failed due to problems that arise when linking with code based on \fIstdio\fP.
        !           625: Changing the name space reduces this type of problems.
        !           626: It also allows us to both stream-line and extend the interface as appropriate.
        !           627: .SH AUTHORS
        !           628: Kiem-Phong Vo (att!ulysses!kpv) and  David G. Korn (att!ulysses!dgk).

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.