da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fp 5 CW
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz.TH SFIO 3 "01 June 2008"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.SH NAME
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\fBsfio\fR \- safe/fast string/file input/output
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.SH SYNOPSIS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.de Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fl
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ne 3
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.TP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin..
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.de Ss
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fl
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ne 3
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.SS "\\$1"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin..
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ta 1.0i 2.0i 3.0i 4.0i 5.0i
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "LIBRARIES"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <sfio.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinlibsfio.a -lsfio
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinlibstdio.a -lstdio
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinlibsfio-mt.a -lsfio-mt
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinlibstdio-mt.a -lstdio-mt
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "DATA TYPES"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinVoid_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfoff_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSflong_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfulong_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfdouble_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfio_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfdisc_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinssize_t (*Sfread_f)(Sfio_t*, Void_t*, size_t, Sfdisc_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinssize_t (*Sfwrite_f)(Sfio_t*, const Void_t*, size_t, Sfdisc_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfoff_t (*Sfseek_f)(Sfio_t*, Sfoff_t, int, Sfdisc_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint (*Sfexcept_f)(Sfio_t*, int, Void_t*, Sfdisc_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSffmt_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint (*Sffmtext_f)(Sfio_t*, Void_t*, Sffmt_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint (*Sffmtevent_f)(Sfio_t*, int, Void_t*, Sffmt_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSFIO_VERSION
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "BIT FLAGS"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_STRING
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_READ
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_WRITE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_APPENDWR (SF_APPEND)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_LINE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_SHARE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_PUBLIC
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_MALLOC
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_STATIC
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_IOCHECK
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_WHOLE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_MTSAFE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_IOINTR
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "OPENING/CLOSING STREAMS"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfio_t* sfnew(Sfio_t* f, Void_t* buf, size_t size, int fd, int flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfio_t* sfopen(Sfio_t* f, const char* string, const char* mode);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfio_t* sfpopen(Sfio_t* f, const char* cmd, const char* mode);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfio_t* sftmp(size_t size);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfclose(Sfio_t* f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "THREAD SAFETY"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfmutex(Sfio_t* f, int type);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSFMTX_LOCK
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSFMTX_TRYLOCK
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSFMTX_UNLOCK
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSFMTX_CLRLOCK
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "INPUT/OUTPUT OPERATIONS"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfgetc(Sfio_t* f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfputc(Sfio_t* f, int c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfnputc(Sfio_t* f, int c, int n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfungetc(Sfio_t* f, int c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfulong_t sfgetm(Sfio_t* f, Sfulong_t max);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfputm(Sfio_t* f, Sfulong_t v, Sfulong_t max);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfulong_t sfgetu(Sfio_t* f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfputu(Sfio_t* f, Sfulong_t v);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSflong_t sfgetl(Sfio_t* f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfputl(Sfio_t* f, Sflong_t v);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfdouble_t sfgetd(Sfio_t* f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfputd(Sfio_t* f, Sfdouble_t v);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinchar* sfgetr(Sfio_t* f, int rsc, int type);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinssize_t sfputr(Sfio_t* f, const char* s, int rsc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfoff_t sfmove(Sfio_t* fr, Sfio_t* fw, Sfoff_t n, int rsc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinssize_t sfread(Sfio_t* f, Void_t* buf, size_t n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinssize_t sfwrite(Sfio_t* f, const Void_t* buf, size_t n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfoff_t sfseek(Sfio_t* f, Sfoff_t offset, int type);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinVoid_t* sfreserve(Sfio_t* f, ssize_t n, int type);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "DATA FORMATTING"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfscanf(Sfio_t* f, const char* format, ...);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfsscanf(const char* s, const char* format, ...);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfvsscanf(const char* s, const char* format, va_list args);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfvscanf(Sfio_t* f, const char* format, va_list args);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfprintf(Sfio_t* f, const char* format, ...);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinchar* sfprints(const char* format, ...);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinchar* sfvprints(const char* format, va_list args);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinssize_t sfaprints(char** sp, const char* format, ...);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinssize_t sfvaprints(char** sp, const char* format, va_list args);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfsprintf(char* s, int n, const char* format, ...);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfvsprintf(char* s, int n, const char* format, va_list args);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfvprintf(Sfio_t* f, const char* format, va_list args);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSffmt_t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSFFMT_LEFT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSFFMT_SIGN
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSFFMT_BLANK
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSFFMT_ZERO
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSFFMT_THOUSAND
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSFFMT_LONG
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSFFMT_LLONG
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSFFMT_SHORT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSFFMT_LDOUBLE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSFFMT_IFLAG
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSFFMT_ALTER
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSFFMT_SKIP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSFFMT_ARGPOS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSFFMT_VALUE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint (*Sffmtext_f)(Sfio_t* f, Void_t* v, Sffmt_t* fe);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint (*Sffmtevent_f)(Sfio_t* f, int type, Void_t* v, Sffmt_t* fe);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid va_copy(va_list to, va_list fr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinlong sffmtversion(Sffmt_t* fe, type);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "BUFFERING, SYNCHRONIZATION"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinVoid_t* sfsetbuf(Sfio_t* f, Void_t* buf, size_t size);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfsync(Sfio_t* f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfpoll(Sfio_t** flist, int n, int timeout);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfio_t* sfpool(Sfio_t* f, Sfio_t* poolf, int mode);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfpurge(Sfio_t* f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "DISCIPLINE, EVENT HANDLING"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfdisc_t* sfdisc(Sfio_t* f, Sfdisc_t* disc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfraise(Sfio_t* f, int type, Void_t* data);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinssize_t sfrd(Sfio_t* f, Void_t* buf, size_t n, Sfdisc_t* disc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinssize_t sfwr(Sfio_t* f, const Void_t* buf, size_t n, Sfdisc_t* disc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfoff_t sfsk(Sfio_t* f, Sfoff_t offset, int type, Sfdisc_t* disc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_NEW
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_READ
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_WRITE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_SEEK
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_CLOSING (SF_CLOSE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_DPUSH
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_DPOP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_DPOLL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_DBUFFER
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_SYNC
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_PURGE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_FINAL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_READY
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_LOCKED
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_ATEXIT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSF_EVENT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "STREAM CONTROL"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfresize(Sfio_t* f, Sfoff_t size);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfset(Sfio_t* f, int flags, int i);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfsetfd(Sfio_t* f, int fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfio_t* sfstack(Sfio_t* base, Sfio_t* top);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfio_t* sfswap(Sfio_t* f1, Sfio_t* f2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "STREAM INFORMATION"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfoff_t sfsize(Sfio_t* f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfoff_t sftell(Sfio_t* f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinssize_t sfvalue(Sfio_t* f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sffileno(Sfio_t* f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfstacked(Sfio_t* f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfeof(Sfio_t* f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sferror(Sfio_t* f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfclrerr(Sfio_t* f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfclrlock(Sfio_t* f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzint sfnotify(void (*notify)(Sfio_t* f, int type, Void_t* data));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzint sfwalk(Sfwalk_f walkf, Void_t* data, int type);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "MISCELLANEOUS FUNCTIONS"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinssize_t sfmaxr(ssize_t maxr, int s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinssize_t sfslen();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfulen(Sfulong_t v);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfllen(Sflong_t v);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfdlen(Sfdouble_t v);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinssize_t sfpkrd(int fd, Void_t* buf, size_t n,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int rsc, long tm, int action);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "FULL STRUCTURE SFIO_T"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <sfio_t.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define SFNEW(buf,size,file,flags,disc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "EXAMPLE DISCIPLINES"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <sfdisc.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfdcdio(Sfio_t* f, size_t bufsize);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfdcdos(Sfio_t* f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfdcfilter(Sfio_t* f, const char* cmd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfdcseekable(Sfio_t* f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfdcslow(Sfio_t* f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfdcsubstream(Sfio_t* f, Sfio_t* parent,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfoff_t offset, Sfoff_t extent);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfdctee(Sfio_t* f, Sfio_t* tee);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfdcunion(Sfio_t* f, Sfio_t** array, int n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfdclzw(Sfio_t* f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sfdcgzip(Sfio_t* f, int flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "STDIO-COMPATIBILITY"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <stdio.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chincc ... -lstdio -lsfio
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chincc ... -lstdio-mt -lsfio-mt
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.SH DESCRIPTION
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfio provides I/O functions to manage buffered streams.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinEach Sfio stream is a \fIfile stream\fP, representing a file (see \f5open(2)\fP),
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinor a \fIstring stream\fP, representing a memory segment.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinBeyond the usual I/O operations on streams,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfio provides I/O disciplines for extended data processing,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstream stacks for recursive stream processing, and
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstream pools for automatic data synchronization.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinApplications can extend the \f5sfprintf()/sfscanf()\fP functions
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinto define their own conversion patterns as well as redefine existing ones.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinA discipline defines analogues of
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe system calls \f5read(2), write(2)\fP and \f5lseek(2)\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSuch system calls or their discipline replacements are used to process stream data.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinHenceforth, ``\fIsystem call\fP'' will refer to either a system call
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinor its discipline replacement.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinA system call is said to cause an exception if its return value is non-positive.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinUnless overridden by exception handlers (see \f5sfdisc()\fP),
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinan interrupted system call (\f5errno == EINTR\fP on UNIX systems)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinwill be automatically reinvoked to continue the ongoing operation.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe buffer of a stream is typically a memory segment allocated via \f5malloc(3)\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinor supplied by the application.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFile streams may also use memory mapping (\f5mmap(2)\fP) if that is more efficient.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinWhen memory mapping is used,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe underlying file should not be truncated while the stream is active.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinMemory mapping can be turned off using \f5sfsetbuf()\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThere are three \fIstandard streams\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfstdin\fP for input (file descriptor \f50\fP on UNIX systems),
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfstdout\fP for normal output (file descriptor \f51\fP), and
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfstderr\fP for error output (file descriptor \f52\fP).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "LIBRARIES"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis version of Sfio can be built and used for both uni-threaded and multi-threaded
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinenvironments. In the former case, streams are not protected from
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsimultaneous accesses by different threads. In the latter case, a stream
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinis typically locked with a mutex during access so that another thread
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintrying to access the same stream will block until the mutex is released.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinA program that does not use multiple threads can link with \fBlibsfio.a\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinwhile a program that uses multiple threads should link with \fBlibsfio-mt.a\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe libraries \fBlibstdio.a\fP and \fBlibstdio-mt.a\fP provide
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chincorresponding Stdio functions to link with code already compiled using the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinnative header \fBstdio.h\fP instead of the one provided by Sfio.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "DATA TYPES"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " Void_t*"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis defines a type suitable to exchange
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindata of unknown types between application and Sfio.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5Void_t\fP is a macro defined as \f5void\fP for ANSI-C and C++ and
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5char\fP for other compilation environments.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " Sfoff_t"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis defines an integral type suitable to address
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe largest possible file extent.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " Sfulong_t, Sflong_t, Sfdouble_t"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThese are respectively the largest
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinunsigned integer, signed integer, and floating point value types on the local platform.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " Sfio_t"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis defines the type of a stream handle.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " Sfdisc_t"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " ssize_t (*Sfread_f)(Sfio_t*, Void_t*, size_t, Sfdisc_t*)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " ssize_t (*Sfwrite_f)(Sfio_t*, const Void_t*, size_t, Sfdisc_t*)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " Sfoff_t (*Sfseek_f)(Sfio_t*, Sfoff_t, int, Sfdisc_t*)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int (*Sfexcept_f)(Sfio_t*, int, Void_t*, Sfdisc_t*)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5Sfdisc_t\fP defines a stream discipline structure.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5Sfread_f\fP, \f5Sfwrite_f\fP and \f5Sfseek_f\fP are the types
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinof discipline functions to replace the system calls:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5read(2)\fP, \f5write(2)\fP and \f5lseek(2)\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5Sfexcept_f\fP is the type of an event-handling function.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSee \f5sfdisc()\fP for more details.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " Sffmt_t"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int (*Sffmtext_f)(Sfio_t*, Void_t*, Sffmt_t*)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int (*Sffmtevent_f)(Sfio_t*, int, Void_t*, Sffmt_t*)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5Sffmt_t\fP defines a formatting environment that can be used
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinto extend scanning and printing in the \f5sfprint()/sfscanf()\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfunctions. \f5Sffmtext_f\fP and \f5Sffmtevent_f\fP define the types
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinof extension functions definable in \f5Sffmt_t\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSee \f5Sffmt_t\fP below for more details.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " SFIO_VERSION"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is a macro value of type \f5long int\fP that defines
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe current version number of Sfio. For example, the Sfio2000's
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinversion number is \f520000515L\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin(which also indicates its latest version date: 05/15/2000).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "BIT FLAGS"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinA number of bit flags control stream operations.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThey are set either at stream initialization or by calling \f5sfset()\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFollowing are the flags:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_STRING\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe stream is memory-based.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_READ\fP, \f5SF_WRITE\fP, \f5SF_APPENDWR\fP (\f5SF_APPEND\fP):
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFlags \f5SF_READ\fP and \f5SF_WRITE\fP indicate readability and writability.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFlag \f5SF_APPENDWR\fP asserts that the stream is a file opened in append mode
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin(see \f5open(2)\fP and \f5fcntl(2)\fP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinso that data is always output at the end of file.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinOn systems without direct support for append mode,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfio uses \f5lseek(2)\fP or its discipline replacement
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinto approximate this behavior.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_LINE\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe stream is line-oriented.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor a \f5SF_WRITE\fP stream,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthis means that buffered data is flushed
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinwhenever a new-line character, \f5\en\fP, is output.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor a \f5SF_READ\fP stream, \f5SF_LINE\fP is only
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsignificant during calls to functions in the \f5sfscanf()\fP family.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_LINE\fP is set on initialization of
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinany stream representing a terminal device.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_SHARE\fP, \f5SF_PUBLIC\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFlag \f5SF_SHARE\fP means that the underlying file descriptor
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinis shared by independent entities (for example, multiple processes).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor a seekable file stream, \f5SF_SHARE\fP means that
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe logical stream and the physical file positions will be made the same
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbefore a system call to perform physical I/O.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThere are different possibilities.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5SF_PUBLIC\fP is not set,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe physical file position is made equal to the logical stream position.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5SF_PUBLIC\fP is set, there are two cases.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf the physical file position has changed from its last known position,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe logical stream position is made equal to the new physical file position.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFinally, if the physical file location remains the same as its last known position,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe physical file position is made the same as the logical stream position.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor an unseekable stream (e.g., pipes or terminal devices), if possible,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_SHARE\fP means that
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe block and record I/O operations (\f5sfread()\fP, \f5sfwrite()\fP, \f5sfmove()\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfgetr()\fP, \f5sfputr()\fP, \f5sfreserve()\fP, \f5sfscanf()\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinand \f5sfvprintf()\fP) will ensure:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin(1) after each writing operation, the stream is synchronized and
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin(2) each reading operation only reads the requested amount.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNote, however, that (2) is not always possible
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinwithout proper OS facilities such as \f5recv(2)\fP or \f5streamio(4)\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinA standard stream that is seekable will be initialized with \f5SF_SHARE|SF_PUBLIC\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_MALLOC\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe stream buffer was obtained via \f5malloc(3)\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinand can be reallocated or freed.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_STATIC\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe stream structure should not be freed when closed (\f5sfclose()\fP).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis flag is used by an applications that allocate their own
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstream structures. Such applications must use the header file \f5sfio_t.h\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chininstead of \f5sfio.h\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_IOCHECK\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf the stream has a discipline exception handler,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinexceptions will be raised in \f5sfsync()\fP, \f5sfpurge()\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinor before a system call \f5read(2)\fP or \f5write(2)\fP (see \f5sfdisc()\fP).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_WHOLE\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis flag guarantees that data written in any single \f5sfwrite()\fP or
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfputr()\fP call will always be output as a whole to the output device.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is useful in certain applications (e.g., networking) where a complex object
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinmust be output without being split in different system calls.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNote that the respective stream still buffers data as much as the buffer can accomodate.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_MTSAFE\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis flag indicates that the respective stream may be accessed by more than one threads.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinA mutex lock will be used to ensure that only one thread at a time can access
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe stream. Note that this flag can only be set at stream opening time
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin(see \f5sfopen()\fP, \f5sfpopen()\fP and \f5sfnew()\fP).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinCertain fast macro functions such as \f5sfgetc()\fP and \f5sfputc()\fP will
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinno longer behave as macros. Thus, an application that requires such fast macro functions
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinshould leave \f5SF_MTSAFE\fP off and performs explicit locking with \f5sfmutex()\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_IOINTR\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis flag indicates that I/O system calls should not be resumed
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinafter being interrupted by signals. It is useful for
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinaborting I/O operations on such interruptions. Note, however,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthan certain operating systems (e.g., BSD Unix systems) may automatically
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinresume interrupted system calls outside the scope of the library. On such systems,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_IOINTR\fP will be ineffective.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "OPENING/CLOSING STREAMS"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " Sfio_t* sfnew(Sfio_t* f, Void_t* buf, size_t size, int fd, int flags)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function creates or renews a stream.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIt returns the new stream on success and \f5NULL\fP on error.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5f\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5f\fP is \f5NULL\fP, a new stream is created.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinOtherwise, \f5f\fP is reused.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn this case, if \f5flags\fP does not have \f5SF_EOF\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5f\fP shall be closed via \f5sfclose()\fP before being reused.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinDuring a stream renewal, buffer, pool and discipline stack are preserved.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNote that, except for \f5SF_STATIC\fP streams,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinrenewing a stream already closed will result in undefined behavior.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5buf\fP, \f5size\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThese determine a buffering scheme.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSee \f5sfsetbuf()\fP for more details.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5fd\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5SF_STRING\fP is specified in \f5flags\fP, this is ignored.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinOtherwise, \f5fd\fP is a file descriptor (e.g., from \f5open(2)\fP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinto use for raw data I/O.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNote that Sfio supports unseekable file descriptors
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinopened for both read and write, e.g., sockets.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5flags\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is composed from \f5SF_EOF\fP and
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbit values defined in the \fBBIT FLAGS\fP section.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNote, in particular, that a multi-threaded application should
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinset the bit \f5SF_MTSAFE\fP to protect the new stream from
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbeing simultaneously accessed by multiple threads.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " Sfio_t* sfopen(Sfio_t* f, const char* string, const char* mode)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5string\fP is \f5NULL\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5f\fP is a file stream and
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5mode\fP does not imply a string stream,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfopen()\fP changes the modes of \f5f\fP according to \f5mode\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn this case, \f5sfopen()\fP returns \f5f\fP on success and \f5NULL\fP on error.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis somewhat unusual usage of \f5sfopen()\fP is good for
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinresetting certain predefined modes in standard streams including
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\fItext/binary\fP and \fIappend\fP that are inherited from some parent process.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNote also that \f5SF_READ\fP and \f5SF_WRITE\fP can only be reset if the stream
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinis not yet initialized.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfopen()\fP is normally used to create a new stream or renew a stream.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn this case, it returns the new stream on success and \f5NULL\fP on error.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinBelow are the meanings of the arguments:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5f\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is treated as in \f5sfnew()\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5string\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is a file name or a string to perform I/O on.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSee above for when this is \f5NULL\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5mode\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is composed from the set of letters \f5{s, r, w, +, a, b, t, x, m, u}\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinWhen conflicting options are present in the same \f5mode\fP string,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe last one will take effect.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5s\fP specifies opening a string stream.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5string\fP can be a null-terminated string or \f5NULL\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSpecifying \f5s\fP alone is equivalent to specifying \f5sr\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5s\fP is not specified, \f5string\fP defines a file name.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5r\fP and \f5w\fP specify read and write modes.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinWrite mode creates and/or truncates the given file to make an empty file.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe \f5+\fP modifier indicates that the stream is opened for both read and write.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5a\fP specifies append mode, i.e., data is always output at end of file.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5b\fP and \f5t\fP specify binary and text modes.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5x\fP specifies exclusive mode, i.e.,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968china file opened for writing should not already exist.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5m\fP specifies that the stream needs to be protected from
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsimultaneous accesses by multiple threads.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis turns on the bit flag \f5SF_MTSAFE\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5u\fP specifies that the stream is guaranteed to be accessed
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinby only one thread at a time. The bit flag \f5SF_MTSAFE\fP is left off.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe absence of option \f5m\fP is the same as the presence of option \f5u\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " Sfio_t* sfpopen(Sfio_t* f, const char* cmd, const char* mode)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function opens a stream that corresponds to the coprocess \f5cmd\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe argument \f5mode\fP should be composed from \f5r\fP, \f5w\fP, and \f5+\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe argument \f5f\fP, if not \f5NULL\fP, is a stream to be renewed (see \f5sfnew()\fP).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfpopen()\fP returns the new stream or \f5NULL\fP on error.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe standard input/output of \f5cmd\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinis connected to the application via a pipe if the stream is opened for writing/reading.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf the stream is opened for both reading and writing,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthere will be two different associated file descriptors, one for each type of I/O
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin(note the effect on \f5sffileno()\fP).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinOn opening a coprocess for writing (i.e., \f5mode\fP contains \f5w\fP or \f5+\fP),
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe signal handler for \f5SIGPIPE\fP in the parent application
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinwill be set to \f5SIG_IGN\fP if it is \f5SIG_DFL\fP at that time.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis protects the parent application from being accidentally killed
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinon writing to a coprocess that closes its reading end.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinApplications that need to detect such write errors should use
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindisciplines and exception handlers (see \f5sfdisc()\fP).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe command \f5cmd\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinis executed by an \fIinterpreter\fP which is either \f5/bin/sh\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinor an executable command defined by the environment variable \f5SHELL\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn either case, the interpreter is invoked with 2 arguments, respectively \f5-c\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinand the given command \f5cmd\fP. When the interpreter is \f5/bin/sh\fP or
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5/bin/ksh\fP, \f5sfpopen()\fP may execute the command \f5cmd\fP itself
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinif there are no shell meta-characters in \f5cmd\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " Sfio_t* sftmp(size_t size)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function creates a stream for temporary data.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIt returns the new stream or \f5NULL\fP on error.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinA stream created by \f5sftmp()\fP can be completely or partially memory-resident.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5size\fP is \f5SF_UNBOUND\fP, the stream is a pure string stream.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5size\fP is zero, the stream is a pure file stream.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinOtherwise, the stream is first created as a string stream but when
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinits buffer grows larger than \f5size\fP or on any attempt to change disciplines,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968china temporary file is created.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinTwo environment variables, \f5TMPPATH\fP and \f5TMPDIR\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindirect where temporary files are created.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5TMPPATH\fP, if defined,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinspecifies a colon-separated set of directories to be
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinused in a round-robin fashion to create files.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5TMPPATH\fP is undefined,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5TMPDIR\fP can be used to specify a single directory to create files.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf neither of \f5TMPPATH\fP and \f5TMPDIR\fP are defined, \f5/tmp\fP is used.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfclose(Sfio_t* f)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function closes the stream \f5f\fP and frees its resources.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_STATIC\fP should be used if the stream space is to be preserved.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5f\fP is the base of a stream stack (see \f5sfstack()\fP),
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinall streams on the stack are closed.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5f\fP is a \f5sfpopen\fP-stream,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfclose()\fP waits until the associated command terminates
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinand returns its exit status.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfclose()\fP returns \f5-1\fP for failure and \f50\fP for success.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_READ|SF_SHARE\fP and \f5SF_WRITE\fP streams
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinare synchronized before closing (see \f5sfsync()\fP).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5f\fP has disciplines,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintheir exception handlers will be called twice.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe first exception handler call has the \f5type\fP argument as one of
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_CLOSING\fP or \f5SF_NEW\fP (see \f5sfdisc()\fP.)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe latter, \f5SF_NEW\fP is used when a stream is being closed via \f5sfnew()\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinso that it can be renewed.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe second call uses \f5type\fP as \f5SF_FINAL\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinand is done after all closing operations have succeeded but before
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe stream itself is deallocated.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn either case, if the exception handler returns a negative value,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfclose()\fP will immediately return this value.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf the exception handler returns a positive value,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfclose()\fP will immediately return a zero value.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "THREAD SAFETY"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe libraries \f5libsfio.a\fP and \f5libstdio.a\fP (providing binary
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chincompatibility to Stdio-based code) only support uni-threaded code.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinMulti-threaded applications should link with
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5libsfio-mt.a\fP and \f5libstdio-mt.a\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinWhen this is done, certain platforms may require additional
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthread libraries for linkage. For example, Linux, Irix and Solaris
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinrequire \f5-lpthread\fP while HPUX requires \f5-lcma\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinAside from linkage differences, the Sfio API remains identical in all cases.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNote that unlike Stdio streams which are in thread-safe mode by default.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfio streams can be opened in either uni-threaded or multi-threaded mode.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinA uni-threaded stream is more efficient than a multi-threaded one.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor example, functions such as \f5sfgetc()\fP and \f5sfputc()\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinremain as macro or inline functions for a uni-threaded stream while
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthey will act as full function calls in a multi-threaded case.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe three standard streams \f5sfstdin/sfstdout/sfstderr\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinare in multi-threaded mode by default
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin(however, see \f5sfopen()\fP for how this may be changed).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinOther Sfio streams are normally opened uni-threaded unless
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe flag \f5SF_MTSAFE\fP or the option \f5m\fP were specified.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinStdio-based code can also make a Stdio stream uni-threaded by
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinusing the option \f5u\fP when opening a file.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "int sfmutex(Sfio_t* f, int type)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function acquires or releases a mutex
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin(mutually exclusive) lock on the stream \f5f\fP.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland MainzIt can be used by a thread to serialize a sequence of I/O operations
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinexecuted together in some critical section.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfmutex()\fP is implicitly used by
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzall Sfio operations on a stream with the flag \f5SF_MTSAFE\fP to
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzprotect it from concurrent accesses via multiple threads.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfmutex()\fP returns \f50\fP on success and some non-zero value on failure.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinEach stream has a lock count which starts at \f50\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinWhen the count is positive, a single thread holds the stream.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinOnly this thread can further lock or unlock the stream.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinA different thread attempting to acquire such a locked stream will suspend
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinuntil the lock count returns to \f50\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinEach successful locking operation increases the lock count
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinwhile each successful unlocking operation decreases it,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthus, allowing nesting of matching lock/unlock operations.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe \f5type\fP argument of \f5sfmutex()\fP takes on the below values:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SFMTX_LOCK\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinLocking a stream if it is unlocked or increasing the lock count of the stream
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzif it is already locked by the same thread. This call will block until it is
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzpossible to lock the stream.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SFMTX_TRYLOCK\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is the non-blocking version of \f5SFMTX_LOCK\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf the stream is already locked by a different thread, \f5sfmutex()\fP will
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinimmediately return with an error status.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SFMTX_UNLOCK\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinDecreasing the lock count and releasing the stream when the lock count reaches 0.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinAn attempt to unlock a stream without a previously successful lock may
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinresult in undefined behavior in certain implementations.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe current Sfio implementation returns an error status.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SFMTX_CLRLOCK\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinResetting the lock count to \f50\fP and releasing the stream.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinAs with \f5SFMTX_LOCK\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinan attempt to clear the lock count without a previously successful lock
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinmay result in undefined behavior.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "INPUT/OUPUT OPERATIONS"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfgetc(Sfio_t* f)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfputc(Sfio_t* f, int c)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThese functions read/write a byte from/to stream \f5f\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfgetc()\fP returns the byte read or \f5-1\fP on error.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfputc()\fP returns \f5c\fP on success and \f5-1\fP on error.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " ssize_t sfnputc(Sfio_t* f, int c, size_t n)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function attempts to write the byte \f5c\fP to \f5f\fP \f5n\fP times.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIt returns the number of bytes actually written or \f5-1\fP on failure.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfungetc(Sfio_t* f, int c)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function pushes the byte \f5c\fP back into \f5f\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5c\fP matches the byte immediately before the current position in buffered data,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe current position is simply backed up (note the effect on \f5sftell()\fP and
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfseek()\fP). There is no theoretical limit on the number of bytes that
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chincan be pushed back into a stream. Pushed back bytes not part of
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbuffered data will be discarded on any operation that implies
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbuffer synchronization.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfungetc()\fP returns \f5c\fP on success and \f5-1\fP on failure.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " Sfulong_t sfgetm(Sfio_t* f, Sfulong_t max)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfputm(Sfio_t* f, Sfulong_t v, Sfulong_t max)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThese functions read and write \f5Sfulong_t\fP values
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinencoded in a portable format given that the values are at most \f5max\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinPortability across a write architecture and a read architecture
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinrequires that the bit order in a byte is the same on both architectures and
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe written value is storable in an \f5Sfulong_t\fP on the read architecture.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfgetm()\fP returns the value read or \f5-1\fP on error.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfputm()\fP returns the number of bytes written or \f5-1\fP on error.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " Sfulong_t sfgetu(Sfio_t* f)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfputu(Sfio_t* f, Sfulong_t v)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThese functions read and write \f5Sfulong_t\fP values
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinin a compact variable-length portable format.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinPortability across a write architecture and a read architecture
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinrequires that the bit order in a byte is the same on both architectures and
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe written value is storable in an \f5Sfulong_t\fP on the read architecture.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfgetu()\fP returns the value read or \f5-1\fP on error.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfputu()\fP returns the number of bytes written or \f5-1\fP on error.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSee also \f5sfulen()\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " Sflong_t sfgetl(Sfio_t* f)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfputl(Sfio_t* f, Sflong_t v)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThese functions are similar to \f5sfgetu()\fP and \f5sfputu()\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbut for reading and writing (signed) \f5Sflong_t\fP values.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSee also \f5sfllen()\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " Sfdouble_t sfgetd(Sfio_t* f)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfputd(Sfio_t* f, Sfdouble_t v)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThese functions read and write \f5Sfdouble_t\fP values.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn this case, portability depends on the input and output architectures
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinhaving the same floating point value representation.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinValues are coded and decoded using \f5ldexp(3)\fP and \f5frexp(3)\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinso they are constrained to the sizes supported by these functions.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSee also \f5sfdlen()\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " char* sfgetr(Sfio_t* f, int rsc, int type)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function reads a record of data ending in the record separator \f5rsc\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinAfter \f5sfgetr()\fP returns, the length of the record even if it is incomplete
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chincan be retrieved with \f5sfvalue()\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfgetr()\fP returns the record on success and \f5NULL\fP on error.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSee also \f5sfmaxr()\fP for limiting the amount of data read to construct a record.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe \f5type\fP argument is composed of some subset of the below bit flags:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_STRING\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinA null byte will replace the record separator to make the record into a C string.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinOtherwise, the record separator is left alone.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_LOCKR\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinUpon successfully obtaining a record \f5r\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe stream will be locked from further access until it is released with
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968china call \f5sfread(f,r,0)\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_LASTR\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis should be used only after a failed \f5sfgetr()\fP to retrieve
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe last incomplete record. In this case, \f5rsc\fP is ignored.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " ssize_t sfputr(Sfio_t* f, const char* s, int rsc)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function writes the null-terminated string \f5s\fP to \f5f\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5rsc\fP is non-negative, \f5(unsigned char)rsc\fP is output after the string.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfputr()\fP returns the number of bytes written or \f5-1\fP on failure.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " Sfoff_t sfmove(Sfio_t* fr, Sfio_t* fw, Sfoff_t n, int rsc)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function moves objects
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfrom input stream \f5fr\fP to output stream \f5fw\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfmove()\fP returns the number of objects moved or \f5-1\fP on failure.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinAn object can be either a byte if the record separator argument
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5rsc\fP is negative or a record of \f5rsc\fP is non-negative.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn the latter case, a record is incomplete if it does not end in \f5rsc\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinGenerally speaking, a stream can have at most one incomplete record.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5n\fP is negative, all complete objects of \f5fr\fP will be moved.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinOtherwise, \f5n\fP indicates the number of objects to move.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf either \f5fr\fP or \f5fw\fP is \f5NULL\fP, it acts
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinas if it is a stream corresponding to \f5/dev/null\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe UNIX device that has no read data and throws away any write data.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor example, the call \f5sfmove(f,(Sfio_t*)0,(Sfoff_t)(-1),'\en')\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chincounts the number of complete lines in stream \f5f\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " ssize_t sfread(Sfio_t* f, Void_t* buf, size_t n)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function reads up to \f5n\fP bytes from \f5f\fP into buffer \f5buf\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIt returns the number of bytes actually read or \f5-1\fP on error.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " ssize_t sfwrite(Sfio_t* f, const Void_t* buf, size_t n)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function writes \f5n\fP bytes from \f5buf\fP to \f5f\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5f\fP is \f5SF_STRING\fP, and the buffer is not large enough,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinan \f5SF_WRITE\fP exception shall be raised.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfwrite()\fP returns the number of bytes written or \f5-1\fP on failure.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " Sfoff_t sfseek(Sfio_t* f, Sfoff_t offset, int type)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function sets a new I/O position for \f5f\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIt returns the new position or \f5-1\fP on failure.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf the stream is a \f5SF_STRING\fP stream and the new
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinaddress is beyond the current buffer extent,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinan \f5SF_SEEK\fP exception will be raised (see \f5sfdisc()\fP).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe new position is determined based on \f5offset\fP and
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5type\fP which is composed from the bit flags:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f50\fP or \f5SEEK_SET\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5offset\fP is the desired position.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f51\fP or \f5SEEK_CUR\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5offset\fP is relative to the current position (see \f5SF_PUBLIC\fP below).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f52\fP or \f5SEEK_END\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5offset\fP is relative to the physical end of file.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_SHARE\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe stream is treated as if it has the control bit \f5SF_SHARE\fP on.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis implies that a system call seek will be done to ensure that the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinlocation seeking to is valid.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_PUBLIC\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe stream is treated as if it has the control bit \f5SF_PUBLIC\fP on.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf the physical file position has changed from its last known location,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe current position is taken as the new physical position.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinOtherwise, the current position is the logical stream position.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " Void_t* sfreserve(Sfio_t* f, ssize_t n, int type)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function reserves a data block from the stream \f5f\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIt returns the reserved data block on success and \f5NULL\fP on failure.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5f\fP is a \f5SF_READ\fP stream, the data block is a segment of input data.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5f\fP is a \f5SF_WRITE\fP stream, the data block is a buffer
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsuitable for writing output data.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor consistency, if \f5f\fP is opened with \f5SF_READ|SF_WRITE\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinit will normally be treated as if it is a \f5SF_READ\fP stream
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin(see \f5sfset()\fP for forcing a particular mode) but the returned
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbuffer can also be written into (more below).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinHowever, it is possible to bias to \f5SF_WRITE\fP when the \f5type\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinargument is non-negative by adding the \f5SF_WRITE\fP bit \f5type\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn any case, a reserved data block is guaranteed to be valid only until
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968china future access to the stream \f5f\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinWhen \f5f\fP is \f5SF_READ\fP, \f5SF_SHARE\fP and unseekable,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfreserve()\fP will attempt to peek at input data without
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinconsuming it. This enables separate processes to share in reading
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chininput from unseekable file descriptors (e.g., pipes or devices).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinHowever, this use of \f5sfreserve()\fP may fail
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinon certain platforms that do not properly support
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinpeeking on unseekable file descriptors.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinAfter a \f5sfreserve()\fP call, whether or not it succeeds,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfvalue(f)\fP gives the size of the available data block.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinAny partially reserved data block after a failed \f5sfreserve()\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chincall can be obtained in another \f5sfreserve()\fP call with the argument
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5type\fP being \f5SF_LASTR\fP. The second argument \f5n\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinto \f5sfreserve()\fP will be ignored in this case.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinA \f5sfreserve()\fP call is successful if it can obtain a data block
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinof size at least the absolute value of \f5n\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor a \f5SF_READ\fP atream, the argument \f5n\fP is treated as follows:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5n < 0\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfreserve()\fP attempts to get \fIat least\fP \f5|n|\fP bytes
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chininto the buffer.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5n == 0\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf the argument \f5type\fP is \f50\fP,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin\f5sfreserve()\fP attempts to get \fIat least\fP \f51\fP byte into the buffer
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinbut does not consume it (as consistent with \f5n == 0\fP).
7c2fbfb345896881c631598ee3852ce9ce33fb07April ChinIf \f5type != 0\fP, no attempt will be made to read data into the buffer.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor example, the call \f5sfreserve(f, 0, -1)\fP only returns the buffer status,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chini.e., size of existing buffered data and pointer to such data, if any.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe call \f5sfreserve(f, 0, SF_LOCKR)\fP is similar but also locks the stream.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5n > 0\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfreserve()\fP will use attempt to get \fIat most\fP \f5n\fP bytes into
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe buffer. Further, if \f5type == \f5SF_LOCKR\fP (see below), read attempts
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinend on a positive amount.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor a successful reservation, the argument \f5type\fP dictates treatment
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinas follows:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5type == SF_LASTR\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinAfter a \f5sfreserve()\fP call with \f5type != SF_LOCKR\fP fails,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthere may be some left over data not accessible via conventional Sfio calls.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinImmediately after such a failed call,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinanother call to \f5sfreserve\fP with \f5type == SF_LASTR\fP will return any left over
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindata and also advance the stream I/O position by the amount of returned data.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5type < 0\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5n > 0\fP, the stream I/O position is advanced by \f5n\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5n < 0\fP, the stream I/O position is advanced by the amount
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinof available data.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor example, a successful \f5sfreserve(f, -1, -1)\fP call will return a
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbuffer of data and simultanously advance the stream I/O position by the amount
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinindicated by \f5sfvalue(f)\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5type == SF_LOCKR\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe stream I/O position remains unchanged.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn addition, \f5f\fP will be locked from further access.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinAs appropriate to the stream type (\f5SF_READ\fP, \f5SF_WRITE\fP or both),
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5f\fP can be unlocked later
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinwith one of \f5sfread(f,rsrv,size)\fP or \f5sfwrite(f,rsrv,size)\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinwhere \f5rsrv\fP is the reserved data block and \f5size\fP is the amount of
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindata to be consumed. For example, if \f5f\fP is a locked \f5SF_READ\fP stream,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe call \f5sfread(f,rsrv,1)\fP will reopen the stream and simultaneously
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinadvance the stream I/O position by \f51\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFinally, a stream opened for both reading and writing
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chincan release the lock with either call (with associated operational semantics!)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor example, the below code reads 10 bytes of data from a stream
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinopened with both \f5SF_READ\fP and \f5SF_WRITE\fP, modifies the data in place,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthen rewrites the new data back to the stream:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rsrv = sfreserve(f, 10, 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(i = 0; i < 10; ++i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rsrv[i] = toupper(rsrv[i]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(f, rsrv, 10);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ne 6
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "DATA FORMATTING"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinData printing and scanning are done via the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfprintf()\fP and \f5sfscanf()\fP family of functions.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThese functions are similar to their
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinANSI-C \f5fprintf()\fP and \f5fscanf()\fP counterparts.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinHowever, the Sfio versions have been extended for both portability and generality.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn particular, a notion of a formatting environment stack is introduced.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinEach formatting element on the stack
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindefines a separate \fIformatting pair\fP of a format specification string,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5char* format\fP (the usual second argument in the formatting
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfunctions), and an argument list, \f5va_list args\fP (the third argument
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinin functions \f5sfvprintf()\fP and \f5sfvscanf()\fP).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinA formatting environment element may also specify extension functions
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinto obtain or assign arguments and to provide new semantics for pattern processing.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinTo simplify the description below, whenever we talk
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinabout an argument list, unless noted otherwise,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinit is understood that this means either the true
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinargument list when there is no extension function or the action to be taken
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinby such a function in processing arguments.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe manipulation of the formatting environment stack is done
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvia the pattern \f5!\fP discussed below.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "%! and Sffmt_t"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe pattern \f5%!\fP manipulates the formatting environment stack to
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin(1) change the top environment to a new environment,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin(2) stack a new environment on top of the current top,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinor (3) pop the top environment.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe bottom of the environment stack always contains a virtual environment with the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinoriginal formatting pair and without any extension functions.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe top environment of a stack, say \f5fe\fP, is automatically popped whenever
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinits format string is completely processed.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn this case, its event-handling function (if any) is called
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinas \f5(*eventf)(f,SF_FINAL,NIL(Void_t*),fe)\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe top environment
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chincan also be popped by giving an argument \f5NULL\fP to \f5%!\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinor by returning a negative value in an extension function.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn these cases, the event-handling function is called
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinas \f5(*eventf)(f,SF_DPOP,form,fe)\fP where \f5form\fP is the remainder
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinof the format string. A negative return value from the event handling function
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinwill prevent the environment from being popped.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinA formatting environment is a structure of type \f5Sffmt_t\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinwhich contains the following elements:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sffmtext_f extf; /* extension processor */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sffmtevent_f eventf; /* event handler */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* form; /* format string to stack */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin va_list args; /* corresponding arg list */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int fmt; /* pattern being processed */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ssize_t size; /* object size */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int flags; /* formatting control flags */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int width; /* width of field */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int precis; /* precision required */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int base; /* conversion base */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* t_str; /* extfdata string */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n_str; /* length of t_str */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe first four elements of \f5Sffmt_t\fP must be defined by the application
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbefore the structure is passed to a formatting function.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe two function fields should not be changed during processing.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinOther elements of \f5Sffmt_t\fP are set by the respective formatting function
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbefore it calls the extension function \f5Sffmt_t.extf\fP and, subsequently,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chincan be modified by this function to redirect formatting or scanning.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor example, consider a call from a \f5sfprintf()\fP function to process an
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinunknown pattern \f5%t\fP (which we may take to mean ``time'') based on a
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinformatting environment \f5fe\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5fe->extf\fP may reset \f5fe->fmt\fP to `\f5d\fP' upon returing
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinto cause \f5sfprintf()\fP to process the value being formatted as an integer.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinBelow are the fields of \f5Sffmt_t\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5extf\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5extf\fP is a function to extend scanning and formatting patterns.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIts usage is discussed below.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5eventf\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is a function to process events as discussed earlier.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5form\fP and \f5args\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is the formatting pair of a specification string and corresponding argument list.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinWhen an environment \f5fe\fP is being inserted into the stack,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinif \f5fe->form\fP is \f5NULL\fP, the top environment is changed to \f5fe\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinand its associated extension functions
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbut processing of the current formatting pair continues.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinOn the other hand, if \f5fe->form\fP is not \f5NULL\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe new environment is pushed onto the stack
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinso that pattern processing will start with the new formatting pair as well as
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinany associated extension functions.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinDuring processing, whenever \f5extf\fP is called,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5form\fP and \f5args\fP will be set to the current values of
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe formatting pair in use.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5fmt\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is set to the pattern being processed or one of '.', 'I', '('.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5size\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is the size of the object being processed.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5flags\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is a collection of bits defining the formatting flags specified for the pattern.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe bits are:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SFFMT_LEFT\fP: Flag \f5-\fP in \f5sfprintf()\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SFFMT_SIGN\fP: Flag \f5+\fP in \f5sfprintf()\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SFFMT_BLANK\fP: Flag \fIspace\fP in \f5sfprintf()\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SFFMT_ZERO\fP: Flag \f50\fP in \f5sfprintf()\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SFFMT_THOUSAND\fP: Flag \f5'\fP in \f5sfprintf()\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SFFMT_LONG\fP: Flag \f5l\fP in \f5sfprintf()\fP and \f5sfscanf()\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SFFMT_LLONG\fP: Flag \f5ll\fP in \f5sfprintf()\fP and \f5sfscanf()\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SFFMT_SHORT\fP: Flag \f5h\fP in \f5sfprintf()\fP and \f5sfscanf()\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SFFMT_LDOUBLE\fP: Flag \f5L\fP in \f5sfprintf()\fP and \f5sfscanf()\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SFFMT_IFLAG\fP: flag \f5I\fP in \f5sfprintf()\fP and \f5sfscanf()\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SFFMT_ALTER\fP: Flag \f5#\fP in \f5sfprintf()\fP and \f5sfscanf()\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SFFMT_SKIP\fP: Flag \f5*\fP in \f5sfscanf()\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SFFMT_ARGPOS\fP: This indicates argument processing for \f5pos$\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SFFMT_VALUE\fP: This is set by \f5fe->extf\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinto indicate that it is returning a value to be formatted or
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe address of an object to be assigned.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5width\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is the field width.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5precis\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is the precision.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5base\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is the conversion base.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5t_str\fP and \f5n_str\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is the type string and its size.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int (*Sffmtext_f)(Sfio_t* f, Void_t* v, Sffmt_t* fe)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is the type of the extension function \f5fe->extf\fP to process
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinpatterns and arguments.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinArguments are always processed in order and
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5fe->extf\fP is called exactly once per argument.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNote that, when \f5pos$\fP (below) is not used anywhere in a format string,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chineach argument is used exactly once per a corresponding pattern.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn that case, \f5fe->extf\fP is called
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinas soon as the pattern is recognized and before any scanning or formatting.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinOn the other hand, when \f5pos$\fP is used in a format string,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinan argument may be used multiple times.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn this case, all arguments shall be processed in order
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinby calling \f5fe->extf\fP exactly once per argument before any pattern processing.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis case is signified by the flag \f5SFFMT_ARGPOS\fP in \f5fe->flags\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn addition to the predefined formatting patterns and other application-defined
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinpatterns, \f5fe->extf\fP may be called with \f5fe->fmt\fP being one
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinof `\f5(\fP' (left parenthesis), `\f5.\fP' (dot), and `\f5I\fP'.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe left parenthesis requests a string to be used as the \f5extfdata\fP string discussed below.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn this case, upon returning, \f5fe->extf\fP should set the \f5fe->size\fP field
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinto be the length of the string or a negative value to indicate a null-terminated string.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe `\f5I\fP' requests an integer to define the object size.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe dot requests an integer for width, precision, base, or a separator.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn this case, the \f5fe->size\fP field will indicate how many dots have appeared
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinin the pattern specification. Note that, if the actual conversion pattern is 'c' or 's',
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe value \f5*form\fP will be one of these characters.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5f\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is the input/output stream in the calling formatting function.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinDuring a call to \f5fe->extf\fP, the stream shall be unlocked
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinso that \f5fe->extf\fP can read from or write to it as appropriate.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5v\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor both \f5sfscanf()\fP and \f5sfprintf()\fP functions,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5v\fP points to a location suitable for storing any scalars or pointers.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinOn return, \f5fe->extf\fP treats \f5v\fP as discussed below.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5fe\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is the current formatting environment.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe return value \f5rv\fP of \f5fe->extf\fP directs further processing.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThere are two cases.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinWhen \f5pos$\fP is present, a negative return value means to ignore \f5fe\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinin further argument processing while a non-negative return value is treated
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinas the case \f5rv == 0\fP below.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinWhen \f5pos$\fP is not present, \f5fe->extf\fP is called per argument
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinimmediately before pattern processing and its return values are treated
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinas below:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5rv < 0:\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe environment stack is immediately popped.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5rv == 0:\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe extension function has not consumed (in a scanning case) or
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinoutput (in a printing case) data out of or into the given stream \f5f\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe fields \f5fmt\fP, \f5flags\fP, \f5size\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5width\fP, \f5precis\fP and \f5base\fP of \f5fe\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinshall direct further processing.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor \f5sfprintf()\fP functions, if \f5fe->flags\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinhas the bit \f5SFFMT_VALUE\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5fe->extf\fP should have set \f5*v\fP to the value to be processed;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinotherwise, a value should be obtained from the argument list.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinLikewise, for \f5sfscanf()\fP functions,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SFFMT_VALUE\fP means that
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5*v\fP should have a suitable address; otherwise,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinan address to assign value should be obtained from the argument list.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinWhen \f5pos$\fP is present,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinif \f5fe->extf\fP changes \f5fe->fmt\fP, this pattern shall be used regardless of
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe pattern defined in the format string. On the other hand, if \f5fe->fmt\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinis unchanged by \f5fe->extf\fP, the pattern in the format string is used.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn any case, the effective pattern should be one of the standardly defined pattern.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinOtherwise, it shall be treated as unmatched.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5rv > 0:\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe extension function has accessed the stream \f5f\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinto the extent of \f5rv\fP bytes.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinProcessing of the current pattern ceases except that,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfor scanning functions, if \f5fe->flags\fP does not contain
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe bit \f5SFFMT_SKIP\fP, the assignment count shall increase by 1.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "void va_copy(va_list to, va_list fr)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis macro function portably copies the argument list \f5fr\fP to
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe argument list \f5to\fP. It should be used to set the field \f5Sffmt_t.args\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "long sffmtversion(Sffmt_t* fe, int type)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis macro function initializes
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe formatting environment \f5fe\fP with a version number if \f5type\fP is
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinnon-zero. Otherwise, it returns the current value of the version number of \f5fe\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is useful for applications to find out
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinwhen the format of the structure \f5Sffmt_t\fP changes.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNote that the version number corresponds to the Sfio version number
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinwhich is defined in the macro value \f5SFIO_VERSION\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfprintf(Sfio_t* f, const char* format, ...);"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " char* sfprints(const char* format, ...);"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " char* sfvprints(const char* format, va_list args);"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " ssize_t sfaprints(char** sp, const char* format, ...);"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " ssize_t sfvaprints(char** sp, const char* format, va_list args);"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfsprintf(char* s, int n, const char* format, ...)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfvsprintf(char* s, int n, const char* format, va_list args);"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfvprintf(Sfio_t* f, const char* format, va_list args);"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThese functions format output data.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfprintf()\fP and \f5sfvprintf()\fP write to output stream \f5f\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfsprintf()\fP and \f5sfvsprintf()\fP write to buffer \f5s\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinwhich is of size \f5n\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfprints()\fP and \f5sfvprints()\fP construct data in some Sfio-defined buffer.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfaprints()\fP and \f5sfvaprints()\fP are similar to \f5sfprints()\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinand \f5sfvprints()\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbut they return a string constructed via \f5malloc()\fP in \f5*sp\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinand expect this string to be freed by the caller when no longer needed.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfvprintf()\fP is the underlying primitive for the other functions.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinExcept for \f5sfprints()\fP and \f5sfvprints()\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinwhich return a null-terminated string or \f5NULL\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinother functions return the number of output bytes or \f5-1\fP on failure.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe length of string constructed by \f5sfprints()\fP, \f5sfsprintf()\fP, or
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfvsprintf()\fP can be retrieved by \f5sfslen()\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe standard patterns are:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5n, s, c, %, h, i, d, p, u, o, x, X, g, G, e, E, f\fP and \f5!\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinExcept for \f5!\fP which shall be described below,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsee the ANSI-C specification of \f5fprintf(3)\fP for details on the other patterns.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinLet \f5z\fP be some pattern type. A formatting pattern is defined as below:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin %[pos$][flag][width][.precision[.base]][(extfdata)]z
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5pos$\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinA pattern can specify which argument in the argument list to use.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is done via \f5pos$\fP where \f5pos\fP is the argument position.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinArguments are numbered so that the first argument after \f5format\fP is at position 1.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5pos\fP is not specified, the argument following the most recently used one
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinwill be used.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe pattern \f5%!\fP (see below) cannot be used subsequent to a usage of \f5pos$\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinDoing so may cause unexpected behaviors.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5flag\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe flag characters are
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5h\fP, \f5hh\fP, \f5l\fP, \f5ll\fP, \f5L\fP, \f5I\fP, \f5j\fP, \f5t\fP, \f5z\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5\-\fP, \f5+\fP, \fIspace\fP, \f50\fP, \f5'\fP and \f5#\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFlag \f5I\fP defines the size or type of the object being formatted.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThere are two cases: (1) \f5I\fP by itself and (2) \f5I\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfollowed by either a decimal number or `*'.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn the first case, for integer and floating point patterns,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe object type is taken to be the largest appropriate type
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin(i.e., one of \f5Sflong_t\fP, \f5Sfulong_t\fP or \f5Sfdouble_t\fP).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor conversion specifiers \f5s\fP and \f5c\fP, the flag is ignored.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn the second case, a given decimal value would define a size while
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin`*' would cause the size to be obtained from the argument list.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThen, if the conversion specifier is \f5s\fP, this size defines the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinlength of the string or strings being formatted (see the discussion of \f5base\fP below).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor integer and floating point patterns,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe size is used to select a type from one of the below lists as
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinindicated by the conversion specifier:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sflong_t, long, int, short
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfulong_t, unsigned long, unsigned int, unsigned short
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfdouble_t, double, float
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe selection algorithm always matches types from left to right in any given list.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinAlthough selection is generally based on sizes in bytes,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfor compatibility with Microsoft-C, the size 64
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinis matched with an appropriate type with the same number of bits, if any.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf the given size does not match any of the listed types,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinit shall match one of \f5int\fP, \f5unsigned int\fP, and \f5double\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinas defined by the formatting pattern.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinBelow are a few examples of using the \f5I\fP flag.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe first example prints an \f5Sflong_t\fP integer.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis example is actually not portable and
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinonly works on platforms where \f5sizeof(Sflong_t)\fP is 8.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe second example shows how to that portably.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe third example specifies printing a string of length 16.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis length shall be used regardless of whether or not the given string
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinis shorter or longer than 16.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe last example shows the use of the pattern \f5%n\fP to assign the amount
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinof data already output into a \f5short\fP integer \f5n_output\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstdout,"%I8d", Sflong_obj);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstdout,"%I*d", sizeof(Sflong_obj), Sflong_obj);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstdout,"%I*s", 16, s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstdout,"%d%I*n", 1001, sizeof(short), &n_output);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFlags \f5h\fP, \f5l\fP, and \f5L\fP are the ANSI-C conventions to
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinselect the types of input objects.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor example, \f5%hd\fP indicates a \f5short int\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinwhile \f5%ld\fP indicates a \f5long int\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFlag \f5hh\fP addresses the byte value types, i.e., \f5char\fP and \f5unsigned char\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFlags \f5z\fP, \f5t\fP and \f5j\fP address respectively
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe types \f5size_t\fP, \f5ptrdiff_t\fP and \f5Sflong_t\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFlags \f5ll\fP and \f5L\fP address respectively
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe largest integer and floating value types, i.e.,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5Sfulong_t\fP, \f5Sflong_t\fP, and \f5Sfdouble_t\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFlag \f5-\fP left-justifies data within the field (otherwise, right-justification).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFlag \f5+\fP means that a signed conversion will always begin with a plus or minus sign.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFlag \fIspace\fP is ignored if \f5+\fP is specified; otherwise,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinit means that if the first character of a signed conversion
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinis not a sign or if the result is empty, a space will be prepended.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFlag \f50\fP means padding with zeros on the left.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFlag \f5'\fP outputs thousands-separator used by the current locale.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5setlocale(3)\fP should have been used to set the desired locale.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFlag \f5#\fP indicates an alternative format processing.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor \f5%o\fP, the first digit is always a zero.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor \f5%x\fP and \f5%X\fP, a non-zero result will have a prefix
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f50x\fP or \f50X\fP. For \f5%e\fP, \f5%E\fP, \f5%f\fP, \f5%g\fP, and \f5%G\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe result always contains a decimal point. For \f5%g\fP and \f5%G\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintrailing zeros will not be removed. For \f5%d\fP, \f5%i\fP and \f5%u\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe form is \fIbase#number\fP where \fIbase\fP is the conversion base
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinand \fInumber\fP is represented by digits for this \fIbase\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor example, a base \f52\fP conversion with \f5%#..2d\fP for \f510\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinis \f52#1010\fP instead of \f51010\fP as printed with \f5%..2d\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFinally, for \f5%c\fP, bytes will be printed in the C format.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor example, when the ASCII character set is used,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe byte value 10 will be printed as \f5\\n\fP while 255 is printed
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinas \f5\\377\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5width\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis defines the width of the printing field. A value to be printed will
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbe justified and padded if necessary to fill out the field width.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5precis\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinAfter a first dot appears, an integral value defines a precision.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor floating point value patterns, precision is the number of precision digits.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor \f5%c\fP, precision defines the number of times to repeat the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chincharacter being formatted.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor \f5%s\fP, precision defines the maximum number of characters to output.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5base\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is defined after exactly two dots have appeared.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor \f5%i\fP, \f5%d\fP, and \f5%u\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5base\fP should be an integer value in the inclusive range \f5[2,64]\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinand defines a conversion base.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5base\fP is not in this range, it is defined to be \f510\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe digits to represent numbers are:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin 01234567890
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin abcdefghijklmnopqrstuvwxyz
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ABCDEFGHIJKLMNOPQRSTUVWXYZ @_
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor \f5%s\fP and \f5%c\fP, \f5base\fP defines a separator.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThen, for \f5%s\fP, the input argument is taken to be a NULL-terminated array of strings
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinwhile, for \f5%c\fP, this is a null-terminated array of characters.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe strings or characters will be formatted one of a time based
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinon the usual width and precision rules.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinAfter each formatted string or character, except for the last one,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe separator \f5base\fP is output if it is a non-zero.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThere are further restrictions on the syntax of \f5%s\fP and \f5%c\fP when
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968china separator is defined.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinBelow are the legitimate sequences for \f5%s\fP and \f5%c\fP after the second dot:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5 s c\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5 *s *c\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5 \fP\fIz\fP\f5s \fP\fIz\fP\f5c\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn the first case, no separator is defined so \f5base\fP is set to zero.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn the second case, \f5base\fP is obtained from the argument list.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn the third case, the character \fIz\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinmust be non-alphanumeric and \f5base\fP will be set to this character.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe below example shows both the call and the result
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinof printing a \f5NULL\fP-terminated array
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinof three strings \f5apple\fP, \f5orange\fP, and \f5grape\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstdout,"|%8..:s|",list);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin | apple: orange: grape|
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5(extfdata)\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis defines a string \f5extfdata\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinto be passed to the extension function \f5Sffmt_t.extf\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinParentheses shall be balanced.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5extfdata\fP is \f5*\fP, the string is obtained from the argument list.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfscanf(Sfio_t* f, const char* format, ...)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfsscanf(const char* s, const char* format, ...)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfvsscanf(const char* s, const char* format, va_list args)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfvscanf(Sfio_t* f, const char* format, va_list args)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThese functions scan data items.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfscanf()\fP scans from the input stream \f5f\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinwhile \f5sfsscanf()\fP and \f5sfvsscanf()\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinscan from the null-terminated string \f5s\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfvscanf()\fP is the underlying primitive that performs the actual scanning.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinItem types are determined from patterns in string \f5format\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThese functions return
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe number of items successfully scanned or \f5-1\fP on error.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinA white space character (blank, tab, or new-line) in \f5format\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinnormally matches a maximal sequence of input white space characters.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinHowever, if the input stream is in \f5SF_LINE\fP mode (see \f5sfset()\fP),
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968china new-line character only matches white spaces up to an input new-line character.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is useful to avoid blocking when scanning typed inputs.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe standard scan patterns are:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5i, d, u, o, x, X, p, n, f, e, E, g, G, c, %, s, []\fP and \f5!\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinExcept for \f5!\fP which shall be described below,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsee the ANSI-C specification of \f5fscanf(3)\fP for details on other patterns.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinLet \f5z\fP be some pattern type. A formatting pattern is specified as below:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin %[*][pos$][width][.width.base][(extfdata)][flag]z
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5pos$\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinA pattern can specify which argument in the argument list to use.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is done via \f5pos$\fP where \f5pos\fP is the argument position.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinArguments are numbered so that the first argument after \f5format\fP is at position 1.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5pos\fP is not specified, the argument following the most recently used one
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinwill be used.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe pattern \f5%!\fP (see below) cannot be used subsequent to a usage of \f5pos$\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5*:\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis discards the corresponding scanned item.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5width\fP and \f5base\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5width\fP defines the maximum number of bytes to scan
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinand \f5base\fP defines the base of an integral value being scanned.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe `.' (dot) notation also allows specifying a `*' (star) to obtain
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe value from the argument list. The below example specifies scanning
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin4 bytes to obtain the value of an integer in base 10. At the end of scanning,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe variable \f5v\fP should have the value \f51234\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsscanf("12345678","%.*.*d", 4, 10, &v);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5(extfdata)\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis defines a string \f5extfdata\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinto be passed to the extension function \f5Sffmt_t.extf\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinParentheses shall be balanced.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5extfdata\fP is \f5*\fP, the string is obtained from the argument list.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5flag:\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is \f5#\fP, \f5I\fP, or some sequence of \f5h\fP, \f5l\fP, and \f5L\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFlag \f5#\fP is significant for pattern \f5%i\fP and \f5%[\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor \f5%i\fP, it means that the \f5#\fP symbol does not have its usual
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinmeaning in an input sequence \f5base#value\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor example, the scanning result of \f5%#i\fP on input \f52#1001\fP is \f52\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinand the next \f5sfgetc()\fP call will return \f5#\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor \f5%[\fP, if the next character in the input stream does not match
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe given scan set of characters, \f5#\fP causes a match to a null string
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chininstead of a failure.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFlag \f5I\fP defines the size or type of the object being formatted.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThere are two cases: (1) \f5I\fP by itself and (2) \f5I\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfollowed by either a decimal number or `*'.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn the first case, for integer and floating point patterns,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe object type is taken to be the largest appropriate type
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin(i.e., one of \f5Sflong_t\fP, \f5Sfulong_t\fP or \f5Sfdouble_t\fP).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor string patterns such as \f5%s\fP, the flag is ignored.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn the second case, a given decimal value would define a size while
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin`*' would cause the size to be obtained from the argument list.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor string patterns such as \f5%s\fP or \f5%[\fP, this size defines the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinlength of the buffer to store scanned data.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSpecifying a buffer size only limits the amount of data copied into the buffer.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinScanned data beyond the buffer limit will be discarded.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor integer and floating point patterns,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe size is used to select a type from one of the below lists as
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinindicated by the conversion specifier:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sflong_t, long, int, short
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfulong_t, unsigned long, unsigned int, unsigned short
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfdouble_t, double, float
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe selection algorithm always matches types from left to right in any given list.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinAlthough selection is generally based on sizes in bytes,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfor compatibility with Microsoft-C, the size 64
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinis matched with an appropriate type with the same number of bits, if any.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf the given size does not match any of the listed types,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinit shall match one of \f5int\fP, \f5unsigned int\fP, and \f5double\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinas indicated by the formatting pattern.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinBelow are examples of using the \f5I\fP flag.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe first example scans a 64-bit integer.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe second scans some floating point value
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinwhose size is explicitly computed and given.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe last example scans a string into a buffer with the given size 128.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNote that if the scanned string is longer than 127, only the first 127
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbytes shall be copied into the buffer. The rest of the scanned data
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinshall be discarded.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfscanf(sfstdin,"%I64d", &int64_obj);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfscanf(sfstdin,"%I*f", sizeof(float_obj), &float_obj);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfscanf(sfstdin,"%I*s", 128, buffer);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFlags \f5h\fP, \f5l\fP, and \f5L\fP are the ANSI-C conventions
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfor indicating the type of a scanned element.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor example, \f5%hd\fP means scanning a \f5short int\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe flags \f5ll\fP and \f5L\fP mean respectively scanning an
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chininteger or a floating point value with largest size
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin(i.e, \f5Sflong_t\fP or \f5Sfdouble_t\fP).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe \f5%i\fP, \f5%d\fP and \f5%u\fP patterns scan numbers in bases
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfrom \f52\fP to \f564\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5%i\fP scans integral values in self-describing formats.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinExcept for octal, decimal and hexadecimal numbers with the usual formats,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinnumbers in general bases are assumed to be of the form: \fIbase#value\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinwhere \fIbase\fP is a number in base 10 and \fIvalue\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinis a number in the given base.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor example, \f52#1001\fP is the binary representation of the decimal value \f59\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \fIbase\fP is \f536\fP or less,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe digits for \fIvalue\fP can be any combination of \f5[0-9], [a-z], [A-Z]\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinwhere upper and lower case digits are not distinguishable.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \fIbase\fP is larger than \f536\fP, the set of digits is:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin 0123456789
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin abcdefghijklmnopqrstuvwxyz
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ABCDEFGHIJKLMNOPQRSTUVWXYZ @_
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "BUFFERING, SYNCHRONIZATION"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " Void_t* sfsetbuf(Sfio_t* f, Void_t* buf, size_t size)"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland MainzThis function changes the buffering scheme for the stream \f5f\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe stream will be synchronized before any buffer modification.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf a new buffer is successfully set and the old buffer has not been freed,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfsetbuf()\fP returns the old buffer. Otherwise, it returns \f5NULL\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinAfter a \f5sfsetbuf()\fP call,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfvalue()\fP returns the size of the returned buffer.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfio attempts to read data in blocks likely to be serviced fast by the file system.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis means block sizes being multiples of a suitable alignment value
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin(e.g., 512, 1024 or 8192). By default, the alignment value
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinis computed via some internal mechanism depending on the local platform but
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinit can also be explicitly set via the call \f5sfsetbuf(f, (Void_t*)f, size)\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn invocations of \f5sfsetbuf()\fP other than the above case,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe \f5size\fP argument is treated as follows:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5size == SF_UNBOUND\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfio will pick a suitable buffer size.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5buf\fP is \f5NULL\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfio will also pick a suitable buffering scheme (such as memory mapping.)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5buf\fP is not \f5NULL\fP, its actual value is ignored
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbut the buffer will be allocated via \f5malloc(3)\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis can be used to avoid memory mapping.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5size > 0\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is the suggested size to use for buffering or memory mapping.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5buf\fP is \f5NULL\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfio will pick a suitable buffering scheme as discussed above.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5buf\fP is not \f5NULL\fP, then \f5buf\fP and \f5size\fP determine
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968china buffer of the given size.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5size == 0\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5buf\fP is \f5NULL\fP, the stream will be unbuffered.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5buf\fP is not \f5NULL\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfsetbuf()\fP simply returns the stream buffer.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn this case, no attempt will be made to synchronize the stream.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfsync(Sfio_t* f)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function synchronizes the logical and physical views of stream \f5f\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIt returns a negative value for failure and \f50\fP for success.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor a \f5SF_WRITE\fP stream, synchronization means to write out any buffered data.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor a seekable \f5SF_READ\fP file stream,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe physical file position is aligned with the logical stream position and,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinif \f5SF_SHARE\fP is on, buffered data is discarded.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5f\fP is \f5NULL\fP, all streams are synchronized.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5f\fP is the base of a stream stack (see \f5sfstack()\fP),
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinall stacked streams are synchronized.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNote that a stacked stream can only be synchronized this way.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5f\fP is in a pool (see \f5sfpool()\fP) but not being the head,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe pool head is synchronized.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5f\fP has flag \f5SF_IOCHECK\fP, the \f5SF_SYNC\fP event is raised
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbefore and after synchronization. See \f5sfdisc()\fP for details.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfpoll(Sfio_t** flist, int n, int timeout)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function polls a set of streams to see if I/O operations
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chincan be performed on them without blocking.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is useful for multiplexing I/O over a set of streams.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf a stream has a discipline, the exception function may be called
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbefore and after the stream is polled (see \f5sfdisc()\fP for details).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinAfter a successful \f5sfpoll()\fP call,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfor each ready stream \f5f\fP, \f5sfvalue(f)\fP returns
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968china bit combination of \f5SF_READ\fP and \f5SF_WRITE\fP to tell which I/O
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinmode is available. If \f5SF_READ\fP is available, an attempt to read
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968china byte will not block. If \f5SF_WRITE\fP is available,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinan attempt to flush will not block.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfpoll()\fP returns the number of ready streams or \f5-1\fP on failure.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5flist\fP and \f5n\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5flist\fP is an array of \f5n\fP streams to be polled.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinUpon return, ready streams are moved to the front
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinof \f5flist\fP in the same relative order.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5timeout\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis defines an elapse time in milliseconds
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinto wait to see if any stream is ready for I/O.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5timeout\fP is negative, \f5sfpoll()\fP will block until some stream become ready.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNote that \f5SF_STRING\fP and normal file streams never block
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinand are always ready for I/O.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf a stream with discipline is being polled and
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinits readiness is as yet undetermined (e.g., empty buffer,)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe discipline exception function will be called with \f5SF_DPOLL\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbefore querying the operating system.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " Sfio_t* sfpool(Sfio_t* f, Sfio_t* poolf, int mode)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function manipulates pools of streams.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn a pool, only one stream is at the head and can have buffered data.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinAll other streams in the pool will be synchronized.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinA stream becomes head when it is used for some I/O operation.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfpool()\fP returns \f5NULL\fP on failure.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5f\fP and \f5poolf\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5f\fP is \f5NULL\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfpool()\fP simply returns the head of the pool containing \f5poolf\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5f\fP is not \f5NULL\fP and \f5poolf\fP is \f5NULL\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5f\fP is deleted from its pool.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn this case, if no other stream from the same pool can become head,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfpool()\fP will return \f5NULL\fP; otherwise, it returns some stream
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfrom the remainder of the pool.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf both \f5f\fP and \f5poolf\fP are not \f5NULL\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5f\fP is moved from its current pool (if any)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chininto the same pool with \f5poolf\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn this case, \f5poolf\fP is returned.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5mode\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5poolf\fP is already in a pool, \f5mode\fP is ignored.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinOtherwise, \f5mode\fP should be \f50\fP or \f5SF_SHARE\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinA \f5SF_SHARE\fP pool contains streams with \f5SF_WRITE\fP mode.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn addition, on change to a new head stream,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbuffered write data of the current head
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinis transferred to the new head.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfpurge(Sfio_t* f)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function discards all buffered data
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinunless \f5f\fP is a \f5SF_STRING\fP stream.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNote that if \f5f\fP is a \f5SF_READ\fP stream based on an unseekable device,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinpurged data will not be recoverable.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5f\fP is a \f5sfpopen\fP-stream opened for both read and write,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindata of both the read and write pipe ends will be purged
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin(see \f5sfset()\fP to selectively turn off read or write mode
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinif one set of data is to be preserved.)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinAfter purging, if \f5f\fP has flag \f5SF_IOCHECK\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe event \f5SF_PURGE\fP is raised.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfpurge()\fP returns \f5-1\fP for failure and \f50\fP for success.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "DISCIPLINE, EVENT-HANDLING"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinA file stream uses the system calls \f5read(2)\fP, \f5write(2)\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinand \f5lseek(2)\fP to read, write and position in the underlying file.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinDisciplines enable application-defined I/O methods including exception handling and
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindata pre/post-processing.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " Sfdisc_t* sfdisc(Sfio_t* f, Sfdisc_t* disc)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinEach stream has a discipline stack whose bottom is a virtual discipline
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinrepresenting the actual system calls.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfdisc()\fP manipulates the discipline stack of stream \f5f\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5f\fP will be synchronized before any discipline stack manipulation.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinAfter a successful discipline stack manipulation,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe stream I/O position (see \f5sfseek()\fP and \f5sftell()\fP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinand extent (see \f5sfsize()\fP) are updated
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinto reflect that defined by the top discipline.
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin\f5sfdisc()\fP returns \f5NULL\fP on failure.
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April ChinIf the value of \f5disc\fP is identical to the value of \f5f\fP,
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinthen the top discipline on the discipline
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstack is returned without any further action.
7c2fbfb345896881c631598ee3852ce9ce33fb07April ChinAn application can then use this feature of \f5sfdisc()\fP
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinand the field \f5disc\fP (below) of the discipline structure
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinto traverse the entire discipline stack of a stream \f5f\fP as follows:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin.nf
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin.ft 5
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(disc = sfdisc(f, (Sfdisc_t*)f); disc; disc = disc->disc)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin.ft 1
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin.fi
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5disc\fP is \f5SF_POPDISC\fP or \f5(Sfdisc_t*)0\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe top element of the stack, if any, is popped and its address is returned.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinOtherwise, \f5disc\fP is pushed onto the discipline stack.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn this case, if successful, \f5sfdisc()\fP returns
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe discipline that was pushed down.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April ChinNote that a discipline can be used on only one stream at a time.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinAn application should take care to allocate different discipline
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstructures for use with different streams.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinA discipline structure is of the type \f5Sfdisc_t\fP which
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chincontains the following public fields:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfread_f readf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfwrite_f writef;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfseek_f seekf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfexcept_f exceptf;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Sfdisc_t* disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe first three fields of \f5Sfdisc_t\fP specify alternative I/O functions.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf any of them is \f5NULL\fP, it is inherited
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfrom a discipline pushed earlier on the stack.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNote that a file stream always
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinhas \f5read(2)\fP, \f5write(2)\fP, \f5lseek(2)\fP and \f5NIL(Sfexcept_f)\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinas the \fIlogical bottom discipline\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinArguments to I/O discipline functions
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinhave the same meaning as that of the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfunctions \f5sfrd()\fP, \f5sfwr()\fP and \f5sfsk()\fP described below.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe exception function, \f5(*exceptf)()\fP announces exceptional events during
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinI/O operations.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIt is called as \f5(*exceptf)(Sfio_t* f, int type, Void_t* value, Sfdisc_t* disc)\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinUnless noted otherwise, the return value of \f5(*exceptf)()\fP is used as follows:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5<0\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe on-going operation shall terminate.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5>0\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf the event was raised due to an I/O error,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe error has been repaired and the on-going operation shall continue normally.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor some events, e.g., \f5SF_DPOLL\fP, the return value may also have
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinadditional meanings.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5=0\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe on-going operation performs default actions with respect to the raised event.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor example, on a reading error or reaching end of file, the top stream of a stack
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinwill be popped and closed and the on-going operation continue with the new top
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstream.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe argument \f5type\fP of \f5(*exceptf)()\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinidentifies the particular exceptional event:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_LOCKED\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe stream cannot be accessed.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNote that this lock state is not related to the mutex lock
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthat protects a stream from multiple accesses by different threads
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin(see section THREAD SAFETY). Rather, the stream was frozen by
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chincertain operations such as \f5sfreserve()\fP or \f5sfstack()\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThus, a stream can be in this state even if the application is uni-threaded.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_READ\fP, \f5SF_WRITE\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThese events are raised around reading and writing operations.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5SF_IOCHECK\fP is on, \f5SF_READ\fP and \f5SF_WRITE\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinare raised immediately before \f5read(2) and write(2)\fP calls.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn this case, \f5*((ssize_t*)value)\fP is the amount of data to be processed.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe return value of \f5(*exceptf)()\fP, if negative,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinindicates that the stream is not ready for I/O
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinand the calling operation will abort with failure.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf it is positive, the stream is ready for I/O
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbut the amount should be restricted to the amount specified by this value.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf the return value is zero, the I/O operation is carried out normally.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_READ\fP and \f5SF_WRITE\fP are also raised on operation failures.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn such a case, \f5*((ssize_t*)value)\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinis the return value from the failed operation.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_SEEK\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis event is raised when a seek operation fails.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_NEW\fP, \f5SF_CLOSING\fP (\f5SF_CLOSE\fP), \f5SF_FINAL\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThese events are raised during a stream closing.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_NEW\fP is raised for a stream about to be closed to be renewed (see \f5sfnew()\fP).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_CLOSING\fP is raised for a stream about to be closed.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_FINAL\fP is raised after a stream has been closed and before
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinits space is to be destroyed (see \f5sfclose()\fP).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor these events, a non-zero return value from \f5(*exceptf)()\fP causes
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfclose()\fP to return immediately with the same value.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_DPUSH\fP, \f5SF_DPOP\fP, \f5SF_DBUFFER\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinEvents \f5SF_DPUSH\fP and \f5SF_DPOP\fP are raised when a
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindiscipline is about to be pushed or popped.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5(Sfdisc_t*)value\fP is the to-be top discipline, if any.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinA stream buffer is always synchronized before pushing or popping a discipline.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf this synchronization fails, \f5SF_DBUFFER\fP will be raised with
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin\f5*((size_t*)value)\fP being the amount of data still in the buffer.
7c2fbfb345896881c631598ee3852ce9ce33fb07April ChinIf the return value of \f5exceptf\fP is non-negative,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe push or pop operation will continue normally;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinotherwise, \f5sfdisc()\fP returns failure.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_DPOLL\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis event is raised by
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfpoll()\fP to see if the stream is ready for I/O.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5*((int*)value)\fP indicates a time-out interval to wait.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinA negative return value from the exception function means blocking.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinA zero return value means that \f5sfpoll()\fP should
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinquery the underlying file descriptor.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinA positive return value means non-blocking. In addition,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthis value will be a bit combination of \f5SF_READ\fP and \f5SF_WRITE\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinto indicate what I/O modes are ready.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_READY\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis event is raised by \f5sfpoll()\fP for each ready stream.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe third argument to the event handler is an integer composed with
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe two bits \f5SF_READ\fP and \f5SF_WRITE\fP to indicate which
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinI/O modes are ready.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_SYNC\fP, \f5SF_PURGE\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5SF_IOCHECK\fP is set,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthese events are raised respectively for a \f5sfsync()\fP or \f5sfpurge()\fP call.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn each case, the respective event is raised once before the appropriate
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinoperation (synchronization or purging) with \f5((int)value)\fP being \f51\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinand once after with \f5((int)value)\fP being \f50\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNote that \f5sfsync()\fP is called for each
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_WRITE\fP or \f5SF_SHARE|SF_READ\fP stream on closing.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_ATEXIT\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis event is raised for each open stream before the process exits.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfraise(Sfio_t* f, int type, Void_t* data)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5f\fP is non-\f5NULL\fP, \f5sfraise()\fP calls all exception handlers
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinof \f5f\fP with the event \f5type\fP and associated \f5data\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf an exception handler returns a non-zero value,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfraise()\fP immediate returns the same value.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinApplication-defined events should start from the value \f5SF_EVENT\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinso as to avoid confusion with system-defined events,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfraise()\fP returns \f50\fP on success and \f5-1\fP on failure.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5f\fP is \f5NULL\fP, \f5sfraise()\fP iterates over all streams
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinand raise events as described above. In this case,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfraise()\fP returns \f50\fP on success and a negative value
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinon failure. The absolute value of the return value tells how many
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstreams failed on raising the given event.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " ssize_t sfrd(Sfio_t* f, Void_t* buf, size_t n, Sfdisc_t* disc)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " ssize_t sfwr(Sfio_t* f, const Void_t* buf, size_t n, Sfdisc_t* disc)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " Sfoff_t sfsk(Sfio_t* f, Sfoff_t offset, int type, Sfdisc_t* disc)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThese functions provides safe methods for a discipline I/O function to invoke
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinearlier discipline I/O functions and to properly handle exceptions.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThey should not be used in any other context.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfrd()\fP and \f5sfwr()\fP return the number of bytes read or written.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfsk()\fP returns the new seek position.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinOn error, all three functions return a negative value which should be \f5-1\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinor the value returned by the exception handler.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "STREAM CONTROL"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfresize(Sfio_t* f, Sfoff_t size)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function resizes the stream \f5f\P so that its extent is \f5size\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf the stream corresponds to a file, the file size is set to \f5size\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvia the system call \f5ftruncate()\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinWhen a stream is made larger, the new data space is filled with zero's.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfresize()\fP returns \f50\fP on success and a negative value on failure.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfset(Sfio_t* f, int flags, int set)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function sets control flags for the stream \f5f\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIt returns the previous set of flags or \f50\fP on error.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSettable flags are:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_READ\fP, \f5SF_WRITE\fP, \f5SF_IOCHECK\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_LINE\fP, \f5SF_SHARE\fP, \f5SF_PUBLIC\fP, \f5SF_MALLOC\fP and
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_STATIC\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNote that \f5SF_READ\fP and \f5SF_WRITE\fP can be turned on or off only
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinif the stream was opened as \f5SF_READ|SF_WRITE\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinTurning off one of them means that the stream is to be treated exclusively
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinin the other mode. It is not possible to turn off both.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf legal, an attempt to turn on either \f5SF_READ\fP or \f5SF_WRITE\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinwill cause the stream to be in the given I/O mode.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5set == 0:\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5flags\fP is zero, the current set of flags is simply returned.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNote that when a stream is first opened, not
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinall of its flags are initialized yet (more below). If \f5flags\fP is
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinnon-zero, an attempt is made to turn off the specified flags.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5set != 0:\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5flags\fP is zero, the stream is initialized if not yet done so.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThen the current set of flags is returned.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5flags\fP is non-zero, an attempt is made to turn on the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinspecified flags.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfsetfd(Sfio_t* f, int fd)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function changes the file descriptor of \f5f\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinBefore a change is realized,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5(*notify)(f,SF_SETFD,newfd)\fP (see \f5sfnotify()\fP) is called.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfsetfd()\fP returns \f5-1\fP on failure and the new file descriptor on success.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5fd >= 0\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf the current file descriptor is non-negative,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinit will be changed using \f5dup(3)\fP to a value larger or equal to \f5fd\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinUpon a successful change, the previous file descriptor will be closed.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf the current file descriptor is negative, it will be set to \f5fd\fP and
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe stream will be reinitialized.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5fd < 0\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe stream is synchronized (see \f5sfsync()\fP) and its
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfile descriptor will be set to this value.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThen, except for \f5sfclose()\fP, the stream will be inaccessible
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinuntil a future \f5sfsetfd()\fP call resets the file descriptor to a non-negative value.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThus, \f5sfsetfd(f,-1)\fP can be used to avoid closing the file descriptor
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinof \f5f\fP when \f5f\fP is closed.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " Sfio_t* sfstack(Sfio_t* base, Sfio_t* top)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function stacks or unstacks stream.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinEvery stream stack is identified by a base stream
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvia which all I/O operations are performed.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinHowever, an I/O operation always takes effect on the top stream.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf the top stream reaches the end of file or
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinhas an unrecoverable error condition,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinit is automatically popped and closed
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin(see also \f5sfdisc()\fP for alternative handling of these conditions).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5base\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is the base stream of the stack.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf it is \f5NULL\fP, \f5sfstack()\fP does nothing and returns \f5top\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5top\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf this is \f5SF_POPSTACK\fP or \f5(Sfio_t*)0\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe stack is popped and \f5sfstack()\fP returns the popped stream.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinOtherwise, \f5top\fP is pushed on top of the stack identified by \f5base\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinand \f5sfstack()\fP returns the \f5base\fP stream.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " Sfio_t* sfswap(Sfio_t* f1, Sfio_t* f2)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function swaps contents of \f5f1\fP and \f5f2\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis fails if either stream is in a stream stack but not being a base stream.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5f2\fP is \f5NULL\fP, a new stream is constructed as a duplicate of \f5f1\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfswap()\fP returns \f5f2\fP or \f5f1\fP duplicate on success and
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5NULL\fP on failure.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "STREAM INFORMATION"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " Sfoff_t sfsize(Sfio_t* f)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function returns the size of stream \f5f\fP (see \f5sfnew()\fP).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5f\fP is not seekable or if its size is not determinable,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfsize()\fP returns \f5-1\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " Sfoff_t sftell(Sfio_t* f)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function returns the current I/O position in stream \f5f\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNote that if \f5f\fP is \f5SF_APPEND\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinand a writing operation was just performed,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe current I/O position is at the physical end of file.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5f\fP is unseekable, \f5sftell\fP returns the number of bytes
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinread from or written to \f5f\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSee also \f5sfungetc()\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " ssize_t sfvalue(Sfio_t* f)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function returns the string or buffer length
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfor \f5sfreserve()\fP, \f5sfsetbuf()\fP, and \f5sfgetr()\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sffileno(Sfio_t* f)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function returns the file descriptor of stream \f5f\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfstacked(Sfio_t* f)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function returns a non-zero value
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinif stream \f5f\fP has been stacked.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfeof(Sfio_t* f)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sferror(Sfio_t* f)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfclrerr(Sfio_t* f)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfeof()\fP tells whether or not the stream has an end-of-file condition.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sferror()\fP tells whether or not the stream has an error condition.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfclrerr()\fP clears both end-of-file and error conditions.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe end-of-file and error conditions are also cleared on an I/O operation.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfclrlock(Sfio_t* f)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function restores the stream back to a normal state.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis means clearing locks and possibly throwing away unprocessed data.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinAs such, this operation is unsafe and should be used with care.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor example, it may be used before a long jump (\f5longjmp(3)\fP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinout of some discipline I/O function to restore the internal stream states.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfclrlock()\fP returns the current set of flags.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz.Ss " int sfnotify((void(*)notify)(Sfio_t*, int, void*) )"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis sets a function \f5(*notify)()\fP to be called
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzas \f5(*notify)(f, type, data)\fP on various stream events.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland MainzArguments \f5type\fP and \f5data\fP indicate the reason for the call and accompanying data:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_NEW\fP:
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz\f5f\fP is being opened and \f5data\fP is the underlying file descriptor.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_CLOSING\fP (\f5SF_CLOSE\fP):
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz\f5f\fP is the stream being closed and \f5data\fP is the underlying file descriptor.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_SETFD\fP:
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland MainzThe file descriptor of \f5f\fP is being changed to the one
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzdefined by \f5data\fP (see \f5sfsetfd()\fP.)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_READ\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinAn attempt to change \f5f\fP to read mode failed.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz\f5data\fP is the file descriptor of the stream.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5SF_WRITE\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinAn attempt to change \f5f\fP to write mode failed.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz\f5data\fP is the file descriptor of the stream.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz.Tp
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz\f5SF_MTACCESS\fP:
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland MainzWhen a notifying function was registered (see \f5sfnotify()\fP),
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzevery Sfio call on a stream with flag \f5SF_MTSAFE\fP will
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzinvoke the notifying function
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzonce on entry after the stream is locked
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzas \f5(*notify)(f, SF_MTACCESS, Sfio_t** fp), and
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzonce on return before unlocking as
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzas \f5(*notify)(f, SF_MTACCESS, (Sfio_t**)0).
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland MainzIn the call entry case,
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzthe notification function could use the argument \f5fp\fP
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzto set a stream that would be used for performing the actual I/O operation.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland MainzIn this way, certain global streams such as the standard streams \f5sfstdin\fP,
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz\f5sfstdout\fP and \f5sfstderr\fP could be made to act differently when used
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzin different streams.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz.Ss " int sfwalk(Sfwalk_f walkf, Void_t* data, int type)"
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland MainzThis function invokes \f5(*walkf)(f, data)\fP on every open stream \f5f\fP
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzwhose flags as defined by \f5sfset()\fP contains all bit flags given in \f5type\fP.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland MainzOn such a call, if the return value is negative, \f5sfwalk()\fP will terminate.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz\f5sfwalk()\fP returns 0 if no stream was processed.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland MainzOtherwise, it returns the return value from the last invocation of \f5walkf()\fP.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland MainzAs an example, the call \f5sfwalk(walkf, data, SF_READ)\fP will iterate over all streams
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzopened for reading. Similarly, \f5sfwalk(walkf, data, SF_READ|SF_WRITE)\fP
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainziterates over all streams opened for both reading and writing.
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland MainzLastly, \f5sfwalk(walkf, data, 0)\fP iterates over all streams.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "MISCELLANEOUS FUNCTIONS"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " ssize_t sfmaxr(ssize_t maxr, int set)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinCertain records may require too much memory for storage, thus, causing
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinundesirable side effects. Therefore, the library normally bounds the amount
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinof memory used by \f5sfgetr()\fP. A different memory bound
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chincan be set via \f5sfmaxr()\fP. While a positive \f5maxr\fP hints to \f5sfgetr()\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinto use only about that much memory to construct a record, a non-positive bound
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinallows \f5sfgetr()\fP to use as much memory as necessary.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfmaxr()\fP sets the value only if \f5set\fP is non-zero.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIt returns the value before setting or the current value if not setting.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " ssize_t sfslen()"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function returns the length of a string just constructed
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinby \f5sfsprintf()\fP or \f5sfprints()\fP. See also \f5sfvalue()\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfulen(Sfulong_t v)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfllen(Sflong_t v)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " int sfdlen(Sfdouble_t v)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThese functions return respectively the number of bytes required to code the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5Sfulong_t\fP, \f5Sflong_t\fP or \f5Sfdouble_t\fP value \f5v\fP by \f5sfputu()\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5sfputl()\fP or \f5sfputd()\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " ssize_t sfpkrd(int fd, char* buf, size_t n, int rsc, long tm, int action)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis function acts directly on the file descriptor \f5fd\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIt does a combination of peeking on incoming data and a time-out read.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinUpon success, it returns the number of bytes received.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinA return value of \f50\fP means that the end-of-file condition has been detected.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinA negative value represents an error.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5buf\fP, \f5n\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThese define a buffer and its size to read data into.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5rsc\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5>=0\fP, this defines a record separator.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf the last returned byte is not the record separator, then
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe read data did not contain a complete record. Otherwise,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinit contains one or more records.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSee also \f5action\fP below.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5tm\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5>=0\fP, this defines a time interval in milliseconds to wait for incoming data.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5action\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5action > 0\fP, \f5sfpkrd()\fP will peek on incoming data but
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinwill not read past it. Therefore, a future \f5sfpkrd()\fP or \f5read(2)\fP will see
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe same data again.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5action <= 0\fP, \f5sfpkrd()\fP will not peek and there are two cases.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5rsc < 0\fP, an attempt is made to read \f5n\fP bytes.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIf \f5rsc >= 0\fP, an attempt is made to read one record.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "FULL STRUCTURE SFIO_T"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " #include <sfio_t.h>"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinMost applications based on Sfio only need to include
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe header file \f5sfio.h\fP which defines an abbreviated \f5Sfio_t\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstructure without certain fields private to Sfio.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinHowever, there are times (e.g., debugging)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinwhen an application may require more details about the full \f5Sfio_t\fP structure.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIn such cases, the header file \f5sfio_t.h\fP can be used in place of \f5sfio.h\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNote that an application doing this will become sensitive to changes
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinin the internal architecture of Sfio.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss " #define SFNEW(buf,size,file,flags,disc)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis macro function is defined in \f5sfio_t.h\fP for
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinuse in static initialization of an \f5Sfio_t\fP structure.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIt requires five arguments:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5buf, size\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThese define a buffer and its size.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5file\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis defines the underlying file descriptor if any.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5flags\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is composed from bit flags described above.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Tp
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5disc\fP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis defines a discipline if any.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "EXAMPLE DISCIPLINES"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe below functions create disciplines and insert them into
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe given streams \f5f\fP. These functions return \f50\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinon success and \f5-1\fP on failure.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "int sfdcdio(Sfio_t* f, size_t bufsize)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis creates a discipline that uses the direct IO feature
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinavailable on file systems such as SGI's XFS to speed up IO.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe argument \f5bufsize\fP suggests a buffer size to use for data transfer.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "int sfdcdos(Sfio_t* f)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis creates a discipline to read DOS text files.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinIt basically transforms pairs of \er\en to \en.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "int sfdcfilter(Sfio_t* f, const char* cmd)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis creates a discipline that sends data from \f5f\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinto the given command \f5cmd\fP to process, then reads back the processed data.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "int sfdcseekable(Sfio_t* f)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis creates a discipline that makes an unseekable reading stream seekable.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "int sfdcslow(Sfio_t* f)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis creates a discipline that makes all Sfio operations return immediately
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinon interrupts. This is useful for dealing with slow devices.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "int sfdcsubstream(Sfio_t* f, Sfio_t* parent, Sfoff_t offset, Sfoff_t extent)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis creates a discipline that makes \f5f\fP acts as if it
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chincorresponds exactly to the subsection of \f5parent\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstarting at \f5offset\fP with size \f5extent\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "int sfdctee(Sfio_t* f, Sfio_t* tee)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis creates a discipline that copies to the stream \f5tee\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinany data written to \f5f\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "int sfdcunion(Sfio_t* f, Sfio_t** array, int n)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis creates a discipline that makes \f5f\fP act as if it is
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe concatenation of the \f5n\fP streams given in \f5array\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "int sfdclzw(Sfio_t* f)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis creates a discipline that would decompress data in \f5f\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe stream \f5f\fP should have data from a source compressed by
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe Unix \fBcompress\fP program.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "int sfdcgzip(Sfio_t* f, int opt)"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis creates a discipline for reading/writing data compressed by zlib.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe argument \f5opt\fP defines the optimization level.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "STDIO-COMPATIBILITY"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfio provides compatibility functions for all various popular
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinStdio implementations at source and binary level.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe source Stdio-compatibility interface
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinprovides the header file \f5stdio.h\fP that defines
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968china set of macros or inlined functions to map Stdio calls to Sfio ones.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis mapping may benignly extend or change the meaning of certain
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinoriginal Stdio operations. For example, the Sfio's version of
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin\f5popen()\fP allows a coprocess to be opened for both reading and writing
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinunlike the original call which only allows a coprocess to be opened for a single mode.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSimilarly, the Sfio's \f5fopen()\fP call can be used to create
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstring streams in addition to file streams.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe standard streams \f5stdin\fP, \f5stdout\fP and \f5stderr\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinare mapped via \f5#define\fP to \f5sfstdin\fP, \f5sfstdout\fP and \f5sfstderr\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe latter are typically declared of the type \f5Sfio_t*\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinCertain older Stdio applications require these to be declared
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinas addresses of structures so that static initializations of
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe sort ``\f5FILE*\ f\ =\ stdin;\fP'' would work.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSuch applications should use the compile time flag \f5SF_FILE_STRUCT\fP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinto achieve the desired effect.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe binary Stdio-compatibility libraries, \f5libstdio.a\fP and \f5libstdio-mt.a\fP,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinprovide complete implementations of Stdio functions suitable
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfor linking applications already compiled with native header \f5stdio.h\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThese functions are also slightly altered or extended
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinas discussed above.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinBelow are the supported Stdio functions:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.nf
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 5
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFILE* fopen(const char* file, const char* mode);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFILE* freopen(const char* file, const char* mode, FILE* stream);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFILE* fdopen(int filedesc, const char* mode);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFILE* popen(const char* command, const char* mode);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFILE* tmpfile();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint fclose(FILE* stream);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint pclose(FILE* stream);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid flockfile(FILE* stream)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint ftrylockfile(FILE* stream)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid funlockfile(FILE* stream)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid setbuf(FILE* stream, char* buf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint setvbuf(FILE* stream, char* buf, int mode, size_t size);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid setbuffer(FILE* stream, char* buf, size_t size);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint setlinebuf(FILE* stream);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint fflush(FILE* stream);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint fpurge(FILE* stream);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint fseek(FILE* stream, long offset, int whence);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid rewind(FILE* stream);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint fgetpos(FILE* stream, fpos_t* pos);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint fsetpos(FILE* stream, fpos_t* pos);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinlong ftell(FILE* stream);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint getc(FILE* stream);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint fgetc(FILE* stream);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint getchar(void);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint ungetc(int c, FILE* stream);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint getw(FILE* stream);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinchar* gets(char* s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinchar* fgets(char* s, int n, FILE* stream);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsize_t fread(Void_t* ptr, size_t size, size_t nelt, FILE* stream);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint putc(int c, FILE* stream);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint fputc(int c, FILE* stream);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint putchar(int c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint putw(int w, FILE* stream);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint puts(const char* s, FILE* stream);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint fputs(const char* s, FILE* stream);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsize_t fwrite(const Void_t* ptr, size_t size, size_t nelt, FILE* stream);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint fscanf(FILE* stream, const char* format, ...);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint vfscanf(FILE* stream, const char* format, va_list args);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint _doscan(FILE* stream, const char* format, va_list args);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint scanf(const char* format, ...);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint vscanf(const char* format, va_list args);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sscanf(const char* s, const char* format, ...);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint vsscanf(const char* s, const char* format, va_list args);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint fprintf(FILE* stream, const char* format, ...);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint vfprintf(FILE* stream, const char* format, va_list args);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint _doprnt(FILE* stream, const char* format, va_list args);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint printf(const char* format, ...);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint vprintf(const char* format, va_list args);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sprintf(const char* s, const char* format, ...);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint snprintf(const char* s, int n, const char* format, ...);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint vsprintf(const char* s, const char* format, va_list args);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint vsnprintf(const char* s, int n, const char* format, va_list args);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint feof(FILE* stream);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint ferror(FILE* stream);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint clearerr(FILE* stream);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.ft 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.Ss "RECENT CHANGES"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinA few exception types have been added. In particular, exception handlers shall
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinbe raised with \f5SF_LOCKED\fP on accessing a stream frozen either by
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinan ongoing operation or a previous operation (e.g., \f5sfgetr()\fP).
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinBefore a process exits, the event \f5SF_ATEXIT\fP is raised for each open stream.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinA number of disciplines were added for various processing functions.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinOf interests are disciplines to use the direct I/O feature on IRIX6.2,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinread DOS text files, and decompress files compressed by Unix \fIcompress\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinVarious new stream and function flags have been added. For example,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe third argument of \f5sfgetr()\fP is now a set of bit flags and not
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinjust a three-value object. However, the old semantics of this argument
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinof \f5sfgetr()\fP is still supported.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe \f5sfopen()\fP call has been extended so that sfopen(f,NULL,mode) can be
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinused to changed the mode of a file stream before any I/O operations.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThis is most useful for changing the modes of the standard streams.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe buffering strategy has been significantly enhanced for streams
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthat perform many seek operations. Also, the handling of stream and
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfile positions have been better clarified so that applications that
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinshare file descriptors across streams and/or processes can be sure that
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinthe file states will be consistent.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe strategy for mapping between Sfio and Stdio streams in the binary
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chincompatibility package has been significantly enhanced for efficiency.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinFor most platforms, the mapping is now constant time per look-up.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe \f5SF_BUFCONST\fP flag was deleted. This is largely unused anyway.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe library can be built for thread-safety. This is based largely on
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinPosix pthread mutexes except for on UWIN where native Windows APIs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinare used.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe functions \f5sfgetm()\fP and \f5sfputm()\fP were added to encode
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinunsigned integer values with known ranges.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe flag \f5SF_APPEND\fP is identical to \f5SF_APPENDWR\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinHowever it conflicts with a different token of the same name
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindefined in the system header \f5stat.h\fP of BSDI Unix systems.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinOn such systems, we shall not define \f5SF_APPEND\fP and this
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsymbol may be removed in a future release.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSimilarly, the exception \f5SF_CLOSE\fP is identical to \f5SF_CLOSING\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinHowever it conflicts with a different token of the same name
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindefined in the system header \f5socket.h\fP of AIX Unix systems.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinOn such systems, we shall not define \f5SF_CLOSE\fP and this
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsymbol may be removed in a future release.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe printing and scanning functions were extended to handle multibyte characters
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinand to conform to the C99 standard.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe function \f5sfpoll()\fP was rehauled to make it useful
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfor writing servers that must commnunicate with multiple streams
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinwithout blocking.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.PP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinThe formatting pattern \f5%c\fP for \f5sf*printf\fP was extended
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinto allow the flag \f5#\fP to print unprintable character values
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinusing the C convention. For example, \f5%#c\fP prints the octal value 012
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinas \f5\\n\fP.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.SH AUTHORS
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinKiem-Phong Vo, kpv@research.att.com,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.br
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinDavid G. Korn, dgk@research.att.com, and
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin.br
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinGlenn S. Fowler, gsf@research.att.com.