scs@avarice.pika.mit.edu (Steve Summit) (02/11/90)
This posting contains an essentially complete, "nearly" public domain reimplementation of the "standard I/O" package. ("`Nearly' public domain" means that there are the usual few restrictions; see the copyright notices and COPYING file for details.) This is the third and last part. Part 1 (which was Message-ID <1990Feb10.235159.4522@athena.mit.edu>) contained a more descriptive cover letter. Steve Summit scs@adam.mit.edu scs@hstbme.mit.edu (temporary) ------8<--------8<--------8<----stdio3.shar----8<--------8<------ overwritecheck=yes verbose=yes while true; do case $1 in -f) overwritecheck=no shift;; -q) verbose=no shift;; -v) verbose=yes shift;; -*) echo "shar: unknown option $1" 1>&2 shift;; *) break;; esac done case $verbose in yes) echo "extracting Copyright";; esac sed 's/^X//' > Copyright <<\EOF XThe source and documentation contained here is XCopyright 1987, 1988, and 1989 by Steve Summit. XAll Rights Reserved. XNoncommercial redistribution is permitted as long Xas these notices are retained. XAny modifications should be marked as such. XAny commercial, for-profit use will require Xprior permission from the author. EOF chmod 664 Copyright shouldbe=319 size=`wc -c < Copyright` if test $size -ne $shouldbe; then echo "shar: $0: error extracting Copyright ($size != $shouldbe)" 1>&2 fi if test $overwritecheck = no -o ! -f fputs.c; then case $verbose in yes) echo "extracting fputs.c";; esac sed 's/^X//' > fputs.c <<\EOF X#include <stdio.h> X Xfputs(s, fp) Xregister char *s; Xregister FILE *fp; X{ Xregister int r = 0; X X#ifdef FASTNBF X Xif(fp->_flag & _IONBF) X { X char *base = s; X X while(*s != '\0') X s++; X X return _fwrite(fp, base, s - base); X } X X#endif X Xwhile(*s != '\0') X r = putc(*s++, fp); X Xreturn r; X} EOF chmod 644 fputs.c shouldbe=281 size=`wc -c < fputs.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting fputs.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file fputs.c" 1>&2; fi if test $overwritecheck = no -o ! -f fread.c; then case $verbose in yes) echo "extracting fread.c";; esac sed 's/^X//' > fread.c <<\EOF X#include <stdio.h> X Xfread(s, size, n, fp) Xregister char *s; Xunsigned int size; Xint n; Xregister FILE *fp; X{ Xregister int nchars = size * n; Xregister int c; Xint r = 0; X X#ifdef READWRITE X Xif((fp->_flag & _IORW) && (fp->_flag & (_IOREAD | _IOWRT)) == 0) X fp->_flag |= _IOREAD; X X#endif X Xif(!(fp->_flag & _IOREAD)) X return EOF; X X#ifdef FASTNBF X Xif(fp->_flag & _IONBF) X { X if(fp->_cnt > 0) X { X *s++ = *fp->_ptr++; X fp->_cnt--; X s++; X nchars--; X r++; X } X X if(nchars > 0) X { X int r2; X X r2 = _fread(fp, s, nchars); X X if(r2 > 0) X r += r2; X } X } Xelse X#endif X X#ifdef FASTFRDWR X Xwhile(nchars > 0) X { X register int thistime; X X if(fp->_cnt > 0) X { X /* first finish emptying buffer */ X X thistime = fp->_cnt; X if(thistime > nchars) X thistime = nchars; X X memcpy(s, fp->_ptr, thistime); X X fp->_ptr += thistime; X fp->_cnt -= thistime; X s += thistime; X nchars -= thistime; X r += thistime; X } X X while(nchars >= fp->_bufsiz) X { X int r2; X X r2 = _fread(fp, s, fp->_bufsiz); X X if(r2 <= 0) X break; X X s += r2; X nchars -= r2; X r += r2; X } X X if(fp->_flag & _IOEOF) X break; X X /* finally, fill stdio buffer... */ X X if(nchars > 0) X { X if((c = _filbuf(fp)) == EOF) X break; X X *s++ = c; X nchars--; X r++; X } X X /* next time around loop will transfer remaining */ X } X X#else X Xwhile(nchars-- > 0) X { X if((c = _filbuf(fp)) == EOF) X break; X X *s++ = c; X r++; X } X X#endif X Xreturn r / size; X} EOF chmod 644 fread.c shouldbe=1392 size=`wc -c < fread.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting fread.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file fread.c" 1>&2; fi if test $overwritecheck = no -o ! -f freopen.c; then case $verbose in yes) echo "extracting freopen.c";; esac sed 's/^X//' > freopen.c <<\EOF X#include <stdio.h> X#include "funcs.h" X XFILE * Xfreopen(filename, mode, fp) Xchar *filename; Xchar *mode; Xregister FILE *fp; X{ Xint fd; Xint flag; X Xif(*mode == 'r') X { X if((fd = (*_openfunc)(filename, 0)) < 0) X return NULL; X flag = _IOREAD; X } Xelse { X if(*mode == 'w' || (fd = (*_openfunc)(filename, 1) < 0)) X fd = (*_creatfunc)(filename, 0666); X X if(fd < 0) X return NULL; X X if(*mode == 'a') X (*_seekfunc)(fd, 0L, 2); X X flag = _IOWRT; X } X X/* gotta effectively fclose, no? */ X X_initfile(fp); X Xfp->_file = fd; Xfp->_flag |= flag; Xif((fp->_filename = (*_mallocfunc)(strlen(filename) + 1)) != NULL) X strcpy(fp->_filename, filename); X Xreturn fp; X} EOF chmod 644 freopen.c shouldbe=640 size=`wc -c < freopen.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting freopen.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file freopen.c" 1>&2; fi if test $overwritecheck = no -o ! -f fscanf.c; then case $verbose in yes) echo "extracting fscanf.c";; esac sed 's/^X//' > fscanf.c <<\EOF X#include <stdio.h> X#include <stdarg.h> X X/* VARARGS2 */ X Xfscanf(fp, fmt) XFILE *fp; Xchar *fmt; X{ Xregister va_list argp; Xint r; X Xva_start(argp, fmt); Xr = _doscan(fp, fmt, argp); Xva_end(argp); Xreturn r; X} EOF chmod 644 fscanf.c shouldbe=201 size=`wc -c < fscanf.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting fscanf.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file fscanf.c" 1>&2; fi if test $overwritecheck = no -o ! -f fseek.c; then case $verbose in yes) echo "extracting fseek.c";; esac sed 's/^X//' > fseek.c <<\EOF X#include <stdio.h> X Xfseek(fp, offset, whence) XFILE *fp; Xlong int offset; Xint whence; X{ Xfp->_flag &= ~_IOEOF; X X/* X * A questionable optimization: simply relocate _ptr in buffer, if possible. X * Problems are with ungetc: X * 1. if _ptr ends up smack dab at _base, there's no place to ungetc X * 2. an ungetc'd character could possibly (?) be written back out X * to the file (horrifying thought) X * 3. fseek is supposed to undo the effects of an ungetc X */ X Xif(whence == SEEK_CUR && fp->_base != NULL && (fp->_flag & _IOREAD)) X { X if((offset > 0 && fp->_cnt - offset >= 0) || X fp->_ptr - fp->_base >= -offset) X { X fp->_ptr += offset; X fp->_cnt -= offset; X#ifdef READWRITE X fp->_flag &= ~_IOWRT; X#endif X return 0; X } X } X Xif(fp->_flag & _IOWRT) X fflush(fp); X Xif(fp->_seekfunc == NULL) X return EOF; X Xif(whence == SEEK_CUR && fp->_base != NULL) X { X if(fp->_flag & _IOREAD) X offset -= fp->_cnt; X else if(fp->_flag & _IOWRT) X offset += fp->_ptr - fp->_base; X } X X#ifdef READWRITE X Xif(fp->_flag & _IORW) X fp->_flag &= ~(_IOREAD | _IOWRT); X X#endif X X#ifdef _IOFPTR Xif(fp->_flag & _IOFPTR) X (*fp->_seekfunc)(fp->_fptr, offset, whence); Xelse X#endif X (*fp->_seekfunc)(fp->_file, offset, whence); X X#ifdef notyet X Xif(r == -1) X { X fp->_flag |= _IOERR; X if(fp->_errfunc != NULL) X (*fp->_errfunc)(fp->_filename, 's', fp); X } X X#endif X Xif(fp->_base == NULL) X return 0; X Xfp->_ptr = fp->_base; /* worry that there's now no room for ungetc */ X X/* X * Is this the right way to do this? Or should it always be set X * to 0? A putc in _IORW mode will cause a flush, even though X * there oughta be room. (_flsbuf will notice _ptr == _base, X * though, and not write anything.) Of course, in _IORW mode, X * we don't know whether a putc or getc will happen next. X */ X Xif(fp->_flag & _IOWRT) X fp->_cnt = fp->_bufsiz; Xelse fp->_cnt = 0; X Xreturn 0; X} EOF chmod 644 fseek.c shouldbe=1836 size=`wc -c < fseek.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting fseek.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file fseek.c" 1>&2; fi if test $overwritecheck = no -o ! -f ftell.c; then case $verbose in yes) echo "extracting ftell.c";; esac sed 's/^X//' > ftell.c <<\EOF X#include <stdio.h> X Xlong int Xftell(fp) XFILE *fp; X{ Xlong int baseoffset; X Xif(fp->_seekfunc == NULL) X baseoffset = 0; Xelse { X#ifdef _IOFPTR X if(fp->_flag & _IOFPTR) X baseoffset = (*fp->_seekfunc)(fp->_fptr, 0L, 1); X else X#endif X baseoffset = (*fp->_seekfunc)(fp->_file, 0L, 1); X } X Xif(fp->_base == NULL) X return baseoffset; X Xif(fp->_flag & _IOREAD) X return baseoffset - fp->_cnt; Xelse return baseoffset + (fp->_ptr - fp->_base); X} EOF chmod 644 ftell.c shouldbe=431 size=`wc -c < ftell.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting ftell.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file ftell.c" 1>&2; fi if test $overwritecheck = no -o ! -f funcs.c; then case $verbose in yes) echo "extracting funcs.c";; esac sed 's/^X//' > funcs.c <<\EOF X#include "funcs.h" X Xextern int OPENFUNC(); X#ifndef THREEARGOPEN Xextern int CREATFUNC(); X#endif Xextern int READFUNC(); Xextern int WRITEFUNC(); Xextern long int SEEKFUNC(); Xextern int CLOSEFUNC(); X Xextern char *MALLOC(); Xextern FREE(); X Xint (*_openfunc)() = OPENFUNC; X#ifndef THREEARGOPEN Xint (*_creatfunc)() = CREATFUNC; X#endif Xint (*_readfunc)() = READFUNC; Xint (*_writefunc)() = WRITEFUNC; Xlong int (*_seekfunc)() = SEEKFUNC; Xint (*_closefunc)() = CLOSEFUNC; X Xchar *(*_mallocfunc)() = MALLOC; Xint (*_freefunc)() = FREE; EOF chmod 644 funcs.c shouldbe=520 size=`wc -c < funcs.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting funcs.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file funcs.c" 1>&2; fi if test $overwritecheck = no -o ! -f funcs.h; then case $verbose in yes) echo "extracting funcs.h";; esac sed 's/^X//' > funcs.h <<\EOF X#ifndef FUNCS_H X#define FUNCS_H X X/* X * Linkage to underlying I/O (and memory allocation) functions. X * Simple changes here allow, for example, renaming read() et X * al to __read() etc. for strict ANSI environmentally-conscious X * compliance. X */ X X#define OPENFUNC open X#ifndef THREEARGOPEN X#define CREATFUNC creat X#endif X#define READFUNC read X#define WRITEFUNC write X#define SEEKFUNC lseek X#define CLOSEFUNC close X X#define FSTAT fstat X#define ISATTY isatty X X#define MALLOC malloc X#define REALLOC realloc X#define FREE free X X#ifdef __STDC__ X#ifndef SAFEREALLOC X#define SAFEREALLOC /* #define SAFEREALLOC only if realloc handles */ X#endif /* a NULL argument correctly */ X#endif X Xextern int (*_openfunc)(); X#ifndef THREEARGOPEN Xextern int (*_creatfunc)(); X#endif Xextern int (*_readfunc)(); Xextern int (*_writefunc)(); Xextern long int (*_seekfunc)(); Xextern int (*_closefunc)(); X Xextern char *(*_mallocfunc)(); Xextern int (*_freefunc)(); Xextern char *(*_reallocfunc)(); X X#endif EOF chmod 644 funcs.h shouldbe=979 size=`wc -c < funcs.h` if test $size -ne $shouldbe; then echo "shar: $0: error extracting funcs.h ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file funcs.h" 1>&2; fi if test $overwritecheck = no -o ! -f funcs2.c; then case $verbose in yes) echo "extracting funcs2.c";; esac sed 's/^X//' > funcs2.c <<\EOF X#include "funcs.h" X X/* in a separate file so only loaded if needed */ X Xextern char *REALLOC(); X Xchar *(*_reallocfunc)() = REALLOC; EOF chmod 644 funcs2.c shouldbe=131 size=`wc -c < funcs2.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting funcs2.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file funcs2.c" 1>&2; fi if test $overwritecheck = no -o ! -f fwrite.c; then case $verbose in yes) echo "extracting fwrite.c";; esac sed 's/^X//' > fwrite.c <<\EOF X#include <stdio.h> X Xfwrite(s, size, n, fp) Xregister char *s; Xunsigned int size; Xint n; Xregister FILE *fp; X{ Xregister int nchars = size * n; Xint r = 0; X X#ifdef READWRITE X Xif((fp->_flag & _IORW) && (fp->_flag & (_IOREAD | _IOWRT)) == 0) X fp->_flag |= _IOWRT; X X#endif X Xif(!(fp->_flag & _IOWRT)) X return EOF; X X#ifdef FASTFRDWR X Xif(fp->_base == NULL) X _getbuf(fp); X X#endif X X#ifdef FASTNBF X Xif(fp->_flag & _IONBF) X { X fflush(fp); X X r = _fwrite(fp, s, nchars); X X if(r < 0) /* if(r != nchars) ? */ X return EOF; X } Xelse X#endif X X#ifdef FASTFRDWR X Xwhile(nchars > 0) X { X register int thistime; X X if(fp->_cnt > 0 && fp->_cnt < fp->_bufsiz || nchars < fp->_bufsiz) X { X /* copy to buffer */ X X thistime = fp->_cnt; X if(thistime > nchars) X thistime = nchars; X X memcpy(fp->_ptr, s, thistime); X X fp->_ptr += thistime; X fp->_cnt -= thistime; X s += thistime; X nchars -= thistime; X r += thistime; X } X X if(nchars <= 0) X break; X X fflush(fp); X X if(nchars >= fp->_bufsiz) X { X int r2; X X /* now transfer directly from user's buffer */ X X while(nchars >= fp->_bufsiz) X { X thistime = fp->_bufsiz; X X r2 = _fwrite(fp, s, thistime); X X if(r2 < 0) /* if(r2 != nchars) ? */ X break; X X s += r2; X nchars -= r2; X r += r2; X } X } X X /* if chars left over, next trip around loop will finish */ X } X X#else X Xwhile(nchars-- > 0) X { X if(putc(*s++, fp) == EOF) X break; X r++; X } X X#endif X Xreturn r / size; X} EOF chmod 644 fwrite.c shouldbe=1397 size=`wc -c < fwrite.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting fwrite.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file fwrite.c" 1>&2; fi if test $overwritecheck = no -o ! -f getbuf.c; then case $verbose in yes) echo "extracting getbuf.c";; esac sed 's/^X//' > getbuf.c <<\EOF X/* called by _filbuf and _flsbuf to get initial buffer */ X X#include <stdio.h> X#ifdef bsd4_2 X#include <sys/types.h> X#include <sys/stat.h> X#endif X#include "funcs.h" X X_getbuf(fp) Xregister FILE *fp; X{ Xint bufsiz; X#ifdef bsd4_2 Xstruct stat stbuf; X#endif X Xif(fp->_base != NULL) X return; X Xif(!(fp->_flag & _IONBF)) X { X bufsiz = BUFSIZ; X X if(fp->_readfunc == _readfunc || fp->_writefunc == _writefunc) X { X if(fp == stdout && ISATTY(fileno(stdout))) X fp->_flag |= _IOLBF; X X#ifdef bsd4_2 X if(FSTAT(fp->_file, &stbuf) >= 0 && stbuf.st_blksize != 0) X bufsiz = stbuf.st_blksize; X#endif X } X X if((fp->_base = (*_mallocfunc)(bufsiz)) != NULL) X { X fp->_flag |= _IOMYBUF; X } X else { X fp->_flag &= ~_IOLBF; X fp->_flag |= _IONBF; X } X } X Xfp->_cnt = fp->_bufsiz = bufsiz; X Xif(fp->_flag & _IONBF) X { X fp->_base = &fp->_tinybuf; X fp->_bufsiz = 1; X fp->_cnt = 0; /* all putc's call _flsbuf */ X } X Xfp->_ptr = fp->_base; X X#ifndef PUTCLBUF X Xif(fp->_flag & _IOLBF) X fp->_cnt = 0; /* all putc's call _flsbuf */ X X#endif X} EOF chmod 644 getbuf.c shouldbe=1007 size=`wc -c < getbuf.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting getbuf.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file getbuf.c" 1>&2; fi if test $overwritecheck = no -o ! -f gets.c; then case $verbose in yes) echo "extracting gets.c";; esac sed 's/^X//' > gets.c <<\EOF X#include <stdio.h> X Xchar * Xgets(s) Xchar *s; X{ Xregister char *p = s; Xregister int c; X Xwhile((c = getchar()) != '\n' && c != EOF) X *p++ = c; X X*p = '\0'; X Xreturn s; X} EOF chmod 644 gets.c shouldbe=164 size=`wc -c < gets.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting gets.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file gets.c" 1>&2; fi if test $overwritecheck = no -o ! -f getw.c; then case $verbose in yes) echo "extracting getw.c";; esac sed 's/^X//' > getw.c <<\EOF X#include <stdio.h> X Xgetw(fp) Xregister FILE *fp; X{ Xint ret = 0; Xint c; Xint i; X X/* X * Could presumably use sizeof(int) instead of 2, X * but I think getw reads 2 bytes even on 32-bit machines. X */ X X/* Assumes little-endian ints, I think */ X Xfor(i = 0; i < 2; i++) X { X if((c = getc(fp)) == EOF) /* what about any bytes read during */ X return EOF; /* prior trip(s) through loop? */ X X ((char *)&ret)[i] = c; X } X Xreturn ret; X} EOF chmod 644 getw.c shouldbe=424 size=`wc -c < getw.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting getw.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file getw.c" 1>&2; fi if test $overwritecheck = no -o ! -f iob.c; then case $verbose in yes) echo "extracting iob.c";; esac sed 's/^X//' > iob.c <<\EOF X#include <stdio.h> X#include "funcs.h" X Xextern int READFUNC(); Xextern int WRITEFUNC(); Xextern long SEEKFUNC(); Xextern int CLOSEFUNC(); Xextern int _errfunc(); X XFILE _iob[_NFILE] = /* _NFILE just for compatibility */ X { X {NULL, 0, NULL, 0, _IOREAD | _IOFBF | _IOSTFN, 0, NULL, 0, X "standard input", NULL, NULL, X READFUNC, WRITEFUNC, SEEKFUNC, CLOSEFUNC, _errfunc, NULL}, X {NULL, 0, NULL, 0, _IOWRT | _IOFBF | _IOSTFN, 1, NULL, 0, X "standard output", NULL, NULL, X READFUNC, WRITEFUNC, SEEKFUNC, CLOSEFUNC, _errfunc, NULL}, X {NULL, 0, NULL, 0, _IOWRT | _IONBF | _IOSTFN, 2, NULL, 0, X "standard error", NULL, NULL, X READFUNC, WRITEFUNC, SEEKFUNC, CLOSEFUNC, _errfunc, NULL} X }; X XFILE *_lastiob = &_iob[sizeof(_iob) / sizeof(*_iob)]; EOF chmod 644 iob.c shouldbe=734 size=`wc -c < iob.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting iob.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file iob.c" 1>&2; fi if test $overwritecheck = no -o ! -f memcpy.c; then case $verbose in yes) echo "extracting memcpy.c";; esac sed 's/^X//' > memcpy.c <<\EOF Xmemcpy(dest, src, len) Xregister char *dest, *src; Xregister int len; X{ Xif(src < dest) X { X src += len; X dest += len; X while(len-- > 0) X *--dest = *--src; X } Xelse while(len-- > 0) X *dest++ = *src++; X} EOF chmod 664 memcpy.c shouldbe=200 size=`wc -c < memcpy.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting memcpy.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file memcpy.c" 1>&2; fi if test $overwritecheck = no -o ! -f popen.c; then case $verbose in yes) echo "extracting popen.c";; esac sed 's/^X//' > popen.c <<\EOF X#include <stdio.h> X#include "funcs.h" X X#define SHELL "/bin/sh" X Xstruct popencontext X { X FILE *pc_fp; X int pc_pid; X int pc_state; X int pc_status; X }; X X/* values for pc_state: */ X X#define PC_UNUSED 0 X#define PC_RUNNING 1 X#define PC_EXITED 2 X Xextern char *(*_reallocfunc)(); X X/* X * Could perhaps use _fptr to point to the popen context, X * rather than this slightly cumbersome separate cache, X * but I'd like not to tie this version of popen to a X * particular stdio implementation. X */ X Xstatic struct popencontext *pcps = NULL; Xstatic int npcps = 0; X Xstatic struct popencontext * Xgetpcp() X{ Xregister struct popencontext *pcp; Xstruct popencontext *newpcps; X Xfor(pcp = pcps; pcp < &pcps[npcps]; pcp++) X { X if(pcp->pc_status == PC_UNUSED) X return pcp; X } X Xnpcps++; X X#ifndef SAFEREALLOC Xif(pcps == NULL) X newpcps = (struct popencontext *) X (*_mallocfunc)(npcps * sizeof(struct popencontext)); Xelse X#endif X newpcps = (struct popencontext *)(*_reallocfunc)((char *)pcps, X npcps * sizeof(struct popencontext)); X Xif(newpcps == NULL) X return NULL; X Xpcps = newpcps; X Xreturn &pcps[npcps - 1]; X} X XFILE * Xpopen(command, mode) Xchar *command; Xchar *mode; X{ Xint pipefds[2]; Xstruct popencontext *pcp; Xint pid; Xint thisend; X Xif((pcp = getpcp()) == NULL) X return NULL; X Xif(pipe(pipefds) < 0) X return NULL; X Xif((pid = fork()) < 0) X { X (void)close(pipefds[0]); X (void)close(pipefds[1]); X return NULL; X } X X/* X * Uncouth algorithm below lets common code for closing and X * dup'ing pipe be shared between parent and child. "thisend" X * is the end we're interested in (read from/write to); the X * other end gets closed (in our process). "thisend" is X * obviously opposite in parent and child. X * X * Less than perfectly conceptually type-correct; assumes X * 0 == standard input == index of read end of pipe X * 1 == standard output == index of write end of pipe X */ X Xthisend = (*mode == 'r') ? 0 : 1; X Xif(pid == 0) X thisend = 1 - thisend; X X(void)close(pipefds[1 - thisend]); X Xif(pid == 0) X { X /* X * On the off-chance that 0 or 1 had been closed (i.e. X * available) before the pipe, they might now be correct, X * and closing/dup'ing them would be wrong. X */ X X if(pipefds[thisend] != thisend) X dup2(pipefds[thisend], thisend); X X /* should it use getenv("SHELL")? Probably not. */ X execl(SHELL, "sh", "-c", command, (char *)NULL); X X /* X * It is said that stdio should be avoided in a child after a X * failed exec, as should exit. I'm not sure why, but it can't hurt. X */ X X perror(SHELL); X _exit(1); X } X X/* else parent */ X Xpcp->pc_pid = pid; Xpcp->pc_state = PC_RUNNING; Xif((pcp->pc_fp = fdopen(pipefds[thisend], mode)) == NULL) X { X (void)close(pipefds[thisend]); X /* what to do with the child? */ X /* maybe should have fdopened before fork */ X return NULL; X } X Xreturn pcp->pc_fp; X} X Xstatic struct popencontext * Xfindpcp(fp) XFILE *fp; X{ Xregister struct popencontext *pcp; X Xfor(pcp = pcps; pcp < &pcps[npcps]; pcp++) X { X if(pcp->pc_fp == fp) X return pcp; X } X Xreturn NULL; X} X Xpclose(fp) XFILE *fp; X{ Xstruct popencontext *pcp; X Xfclose(fp); X Xif((pcp = findpcp(fp)) == NULL) X { X /* complain anout popen botch? */ X return -1; X } X Xif(pcp->pc_state == PC_RUNNING) X { X int status; X int w; X X while((w = wait(&status)) >= 0) X { X if(w == pcp->pc_pid) X { X pcp->pc_status = status; X break; X } X else { X struct popencontext *pcp2; X X for(pcp2 = pcps; pcp2 < &pcps[npcps]; pcp2++) X { X if(pcp2->pc_pid == w) X { X pcp2->pc_status = status; X pcp2->pc_state = PC_EXITED; X break; X } X } X } X } X } X Xpcp->pc_state = PC_UNUSED; /* so getpcp will find it */ Xpcp->pc_pid = -1; /* so wait loop won't find it */ Xpcp->pc_fp = NULL; /* so findpcp won't find it */ X Xreturn pcp->pc_status; X} EOF chmod 644 popen.c shouldbe=3704 size=`wc -c < popen.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting popen.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file popen.c" 1>&2; fi if test $overwritecheck = no -o ! -f printf.c; then case $verbose in yes) echo "extracting printf.c";; esac sed 's/^X//' > printf.c <<\EOF X#include <stdio.h> X#include <stdarg.h> X X/* VARARGS1 */ X Xprintf(fmt) Xchar *fmt; X{ Xregister va_list argp; Xint r; X Xva_start(argp, fmt); Xr = _doprnt(fmt, argp, stdout); Xva_end(argp); Xreturn r; X} EOF chmod 644 printf.c shouldbe=191 size=`wc -c < printf.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting printf.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file printf.c" 1>&2; fi if test $overwritecheck = no -o ! -f printf.h; then case $verbose in yes) echo "extracting printf.h";; esac sed 's/^X//' > printf.h <<\EOF X#ifndef PRINTF_H X#define PRINTF_H X X#define PRF_LONG 01 X#define PRF_NUMSGN 010 X#define PRF_LADJUST 020 X#define PRF_ZEROPAD 040 X#define PRF_CAPITAL 01000 X X#endif EOF chmod 644 printf.h shouldbe=160 size=`wc -c < printf.h` if test $size -ne $shouldbe; then echo "shar: $0: error extracting printf.h ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file printf.h" 1>&2; fi if test $overwritecheck = no -o ! -f putpad.c; then case $verbose in yes) echo "extracting putpad.c";; esac sed 's/^X//' > putpad.c <<\EOF X#include <stdio.h> X#include "printf.h" X X/* X * There was a routine by this name in the 4.1bsd stdio. X * It probably did the same thing. X * This routine should therefore take the same arguments and X * behave the same way, if possible, except that at the moment X * I can't locate a copy of the old Berkeley stdio. X */ X Xputpad(fd, string, width, padc, flags) XFILE *fd; Xchar *string; Xint width; Xint padc; Xint flags; X{ Xint len = strlen(string); Xint i; Xint retval = 0; Xint padlen; X Xpadlen = width - len; Xif(padlen < 0) X padlen = 0; X Xif(padlen > 0 && !(flags & PRF_LADJUST)) X { X for(i = 0; i < padlen; i++) X putc(padc, fd); X retval += padlen; X } X Xfputs(string, fd); Xretval += len; X Xif(padlen > 0 && (flags & PRF_LADJUST)) X { X for(i = 0; i < padlen; i++) X putc(padc, fd); X retval += padlen; X } X Xreturn retval; X} EOF chmod 644 putpad.c shouldbe=810 size=`wc -c < putpad.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting putpad.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file putpad.c" 1>&2; fi if test $overwritecheck = no -o ! -f puts.c; then case $verbose in yes) echo "extracting puts.c";; esac sed 's/^X//' > puts.c <<\EOF X#include <stdio.h> X Xputs(s) Xregister char *s; X{ X#ifdef FASTNBF Xif(stdout->_flag & _IONBF) X { X char *base = s; X while(*s != '\0') X s++; X _fwrite(stdout, base, s - base); X } Xelse X#endif Xwhile(*s != '\0') X putchar(*s++); X Xreturn putchar('\n'); X} EOF chmod 644 puts.c shouldbe=244 size=`wc -c < puts.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting puts.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file puts.c" 1>&2; fi if test $overwritecheck = no -o ! -f putw.c; then case $verbose in yes) echo "extracting putw.c";; esac sed 's/^X//' > putw.c <<\EOF X#include <stdio.h> X Xputw(w, fp) Xint w; Xregister FILE *fp; X{ Xint i; X X/* X * Could presumably use sizeof(int) instead of 2, X * but I think putw writes 2 bytes even on 32-bit machines. X */ X X/* Assumes little-endian ints, I think */ X Xfor(i = 0; i < 2; i++) X putc(((char *)&w)[i], fp); X Xreturn w; X} EOF chmod 644 putw.c shouldbe=295 size=`wc -c < putw.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting putw.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file putw.c" 1>&2; fi if test $overwritecheck = no -o ! -f rewind.c; then case $verbose in yes) echo "extracting rewind.c";; esac sed 's/^X//' > rewind.c <<\EOF X#include <stdio.h> X Xrewind(fp) XFILE *fp; X{ Xfseek(fp, 0L, SEEK_SET); X X/* X * The standard implementation inexplicably clears _IOERR, which X * contradicts the assertion of ferror(3S) that "unless cleared by X * clearerr, the error indication lasts until the stream is closed." X * H & S agree; K & R 2nd Ed. document an implicit clearerr. X */ X} EOF chmod 644 rewind.c shouldbe=344 size=`wc -c < rewind.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting rewind.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file rewind.c" 1>&2; fi if test $overwritecheck = no -o ! -f saprintf.c; then case $verbose in yes) echo "extracting saprintf.c";; esac sed 's/^X//' > saprintf.c <<\EOF X/* X * char *saprintf(fmt, args) X * X * Like sprintf, but malloc's its own buffer. X * Returns pointer to malloc'ed memory just big enough to hold X * formatted string. X * Caller must free this memory if/when no longer needed. X */ X X#include <stdio.h> X#include <stdarg.h> X Xextern char *_safinish(); X Xchar * Xsaprintf(fmt) Xchar *fmt; X{ Xva_list argp; XFILE f; X X_initsafile(&f); X Xva_start(argp, fmt); X X_doprnt(fmt, argp, &f); X Xva_end(argp); X Xputc('\0', &f); X Xreturn _safinish(&f); X} EOF chmod 644 saprintf.c shouldbe=478 size=`wc -c < saprintf.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting saprintf.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file saprintf.c" 1>&2; fi if test $overwritecheck = no -o ! -f scanf.c; then case $verbose in yes) echo "extracting scanf.c";; esac sed 's/^X//' > scanf.c <<\EOF X#include <stdio.h> X#include <stdarg.h> X X/* VARARGS1 */ X Xscanf(fmt) Xchar *fmt; X{ Xregister va_list argp; Xint r; X Xva_start(argp, fmt); Xr = _doscan(stdin, fmt, argp); Xva_end(argp); Xreturn r; X} EOF chmod 644 scanf.c shouldbe=189 size=`wc -c < scanf.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting scanf.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file scanf.c" 1>&2; fi if test $overwritecheck = no -o ! -f scanfiles.c; then case $verbose in yes) echo "extracting scanfiles.c";; esac sed 's/^X//' > scanfiles.c <<\EOF X#include <stdio.h> X Xextern FILE *_lastiob; Xextern FILE *_ioblist; X X_scanfiles(func) Xint (*func)(); X{ Xregister FILE *fp; X Xfor(fp = _iob; fp < _lastiob; fp++) X if(fp->_flag != 0) X (*func)(fp); X Xfor(fp = _ioblist; fp != NULL; fp = fp->_next) X (*func)(fp); X} EOF chmod 644 scanfiles.c shouldbe=256 size=`wc -c < scanfiles.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting scanfiles.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file scanfiles.c" 1>&2; fi if test $overwritecheck = no -o ! -f setbuf.c; then case $verbose in yes) echo "extracting setbuf.c";; esac sed 's/^X//' > setbuf.c <<\EOF X#include <stdio.h> X Xextern int (*_freefunc)(); X Xsetbuf(fp, buf) XFILE *fp; Xchar *buf; X{ Xif(fp->_flag & _IOMYBUF) X (*_freefunc)(fp->_base); X Xfp->_flag &= ~(_IOMYBUF | _IONBF); X Xif(buf == NULL) X { X fp->_base = fp->_ptr = &fp->_tinybuf; X fp->_cnt = fp->_bufsiz = 1; X fp->_flag |= _IONBF; X } Xelse { X fp->_base = fp->_ptr = buf; X fp->_bufsiz = BUFSIZ; X X /* X * The same issue arises here as in fseek. X * Don't worry about it much, since nobody ever said X * setbuf was supposed to work after a read or write X * (i.e. when _base non-NULL). X */ X X if(fp->_flag & _IOWRT) X fp->_cnt = fp->_bufsiz; X else fp->_cnt = 0; X } X} EOF chmod 644 setbuf.c shouldbe=620 size=`wc -c < setbuf.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting setbuf.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file setbuf.c" 1>&2; fi if test $overwritecheck = no -o ! -f setbuffer.c; then case $verbose in yes) echo "extracting setbuffer.c";; esac sed 's/^X//' > setbuffer.c <<\EOF X#include <stdio.h> X Xsetbuffer(fp, buf, size) XFILE *fp; Xchar *buf; Xint size; X{ Xreturn setvbuf(fp, buf, buf != NULL || size != 0 ? _IOFBF : _IONBF, size); X} EOF chmod 644 setbuffer.c shouldbe=155 size=`wc -c < setbuffer.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting setbuffer.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file setbuffer.c" 1>&2; fi if test $overwritecheck = no -o ! -f seterrfn.c; then case $verbose in yes) echo "extracting seterrfn.c";; esac sed 's/^X//' > seterrfn.c <<\EOF X#include <stdio.h> X Xextern int (*_deflterrfunc)(); X Xfseterrfunc(fp, errfunc) XFILE *fp; Xint (*errfunc)(); X{ Xif(fp == NULL) X _deflterrfunc = errfunc; Xelse fp->_errfunc = errfunc; X} EOF chmod 644 seterrfn.c shouldbe=179 size=`wc -c < seterrfn.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting seterrfn.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file seterrfn.c" 1>&2; fi if test $overwritecheck = no -o ! -f setfuncs.c; then case $verbose in yes) echo "extracting setfuncs.c";; esac sed 's/^X//' > setfuncs.c <<\EOF X#include <stdio.h> X#include "funcs.h" X Xfsetfuncs(fp, readfunc, writefunc, seekfunc, closefunc) XFILE *fp; Xint (*readfunc)(), (*writefunc)(); Xlong int (*seekfunc)(); Xint (*closefunc)(); X{ Xif(fp == NULL) X { X _readfunc = readfunc; X _writefunc = writefunc; X _seekfunc = seekfunc; X _closefunc = closefunc; X } Xelse { X fp->_readfunc = readfunc; X fp->_writefunc = writefunc; X fp->_seekfunc = seekfunc; X fp->_closefunc = closefunc; X } X} EOF chmod 644 setfuncs.c shouldbe=427 size=`wc -c < setfuncs.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting setfuncs.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file setfuncs.c" 1>&2; fi if test $overwritecheck = no -o ! -f setlinebuf.c; then case $verbose in yes) echo "extracting setlinebuf.c";; esac sed 's/^X//' > setlinebuf.c <<\EOF X#include <stdio.h> X Xsetlinebuf(fp) Xregister FILE *fp; X{ Xif(fp->_base == NULL) X setvbuf(fp, (char *)NULL, _IOLBF, BUFSIZ); Xelse if(!(fp->_flag & _IONBF)) X fp->_flag |= _IOLBF; X} EOF chmod 644 setlinebuf.c shouldbe=177 size=`wc -c < setlinebuf.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting setlinebuf.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file setlinebuf.c" 1>&2; fi if test $overwritecheck = no -o ! -f setvbuf.c; then case $verbose in yes) echo "extracting setvbuf.c";; esac sed 's/^X//' > setvbuf.c <<\EOF X#include <stdio.h> X#include "funcs.h" X Xsetvbuf(fp, buf, type, size) Xregister FILE *fp; Xchar *buf; Xint type; Xint size; X{ Xif((type == _IOFBF || type == _IOLBF) && buf == NULL) X { X if(size == 0) X size = BUFSIZ; /* fstat? */ X#ifdef SETBUFANYTIME X if(fp->_flag & _IOMYBUF) X buf = (*_reallocfunc)(fp->_base, size); X else X#endif X buf = (*_mallocfunc)(size); X X if(buf == NULL) X { X if(fp->_errfunc != NULL) X (*fp->_errfunc)(fp->_filename, 'm', fp); /* ? */ X return EOF; X } X X type |= _IOMYBUF; X } X X/* X * #ifdef SETBUFANYTIME (nowhere near finished) still needs to: X * copy if going from user buf to _IOMYBUF X * flush if buf gets smaller (or _IONBF) X * skip following free if reallocating _IOMYBUF X * preserve _ptr and _cnt if partially-full buffer X */ X Xif(fp->_base != NULL && (fp->_flag & _IOMYBUF)) X (*_freefunc)(fp->_base); X Xfp->_flag &= ~(_IOFBF | _IONBF | _IOLBF | _IOMYBUF); X X Xif(type & _IONBF) X { X buf = &fp->_tinybuf; X size = 1; X } X Xfp->_base = fp->_ptr = buf; Xfp->_bufsiz = size; X Xif((fp->_flag & (_IOREAD X#ifdef READWRITE X | _IORW X#endif X )) || (type & (_IONBF X#ifndef PUTCLBUF X | _IOLBF X#endif X ))) X fp->_cnt = 0; Xelse fp->_cnt = size; X Xfp->_flag |= type; X Xreturn 0; X} EOF chmod 644 setvbuf.c shouldbe=1210 size=`wc -c < setvbuf.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting setvbuf.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file setvbuf.c" 1>&2; fi if test $overwritecheck = no -o ! -f snprintf.c; then case $verbose in yes) echo "extracting snprintf.c";; esac sed 's/^X//' > snprintf.c <<\EOF X#include <stdio.h> X#include <stdarg.h> X Xsnprintf(s, n, fmt) Xchar *s; Xint n; Xchar *fmt; X{ Xva_list argp; XFILE f; Xint r; X X_initsfile(&f); X Xf._base = f._ptr = s; Xf._cnt = n - 1; /* leave room for \0 */ Xf._flag |= _IOWRT; X Xva_start(argp, fmt); X Xr = _doprnt(fmt, argp, &f); X Xva_end(argp); X X*f._ptr++ = '\0'; X Xreturn r; X} EOF chmod 644 snprintf.c shouldbe=317 size=`wc -c < snprintf.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting snprintf.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file snprintf.c" 1>&2; fi if test $overwritecheck = no -o ! -f sprintf.c; then case $verbose in yes) echo "extracting sprintf.c";; esac sed 's/^X//' > sprintf.c <<\EOF X#include <stdio.h> X#include <stdarg.h> X X/* VARARGS2 */ X Xsprintf(s, fmt) Xchar *s; Xchar *fmt; X{ Xva_list argp; XFILE f; Xint r; X X_initsfile(&f); X Xf._base = f._ptr = s; Xf._cnt = 32767; /* oughta be INT_MAX or something */ Xf._flag |= _IOWRT; X Xva_start(argp, fmt); X Xr = _doprnt(fmt, argp, &f); X Xva_end(argp); X Xputc('\0', &f); X Xreturn r; X} EOF chmod 644 sprintf.c shouldbe=334 size=`wc -c < sprintf.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting sprintf.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file sprintf.c" 1>&2; fi if test $overwritecheck = no -o ! -f sscanf.c; then case $verbose in yes) echo "extracting sscanf.c";; esac sed 's/^X//' > sscanf.c <<\EOF X#include <stdio.h> X#include <stdarg.h> X X/* VARARGS2 */ X Xsscanf(s, fmt) Xchar *s; Xchar *fmt; X{ XFILE f; Xregister va_list argp; Xint r; X X_initsfile(&f); /* might force loading of sprintf.o */ X Xf._base = f._ptr = s; Xf._cnt = f._bufsiz = strlen(s); Xf._flag |= _IOREAD; X Xva_start(argp, fmt); X Xr = _doscan(&f, fmt, argp); X Xva_end(argp); X Xreturn r; X} EOF chmod 644 sscanf.c shouldbe=342 size=`wc -c < sscanf.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting sscanf.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file sscanf.c" 1>&2; fi if test $overwritecheck = no -o ! -f straopen.c; then case $verbose in yes) echo "extracting straopen.c";; esac sed 's/^X//' > straopen.c <<\EOF X#include <stdio.h> X Xextern FILE *_getfile(); Xextern char *_safinish(); X XFILE * Xstraopen() X{ Xregister FILE *fp; X Xif((fp = _getfile()) == NULL) X return NULL; X X_initsafile(fp); X Xreturn fp; X} X Xchar * Xstraptr(fp) Xregister FILE *fp; X{ Xif(!(fp->_flag & _IOSTRG)) /* imperfect */ X return NULL; X Xputc('\0', fp); X Xfp->_ptr--; /* so \0 will be overwritten next time */ Xfp->_cnt++; X Xreturn fp->_ptr; X} X Xchar * Xstraclose(fp) Xregister FILE *fp; X{ Xchar *ret; X Xif(!(fp->_flag & _IOSTRG)) /* imperfect */ X return NULL; X Xputc('\0', fp); X Xret = _safinish(fp); X Xfp->_base = NULL; /* just in case _freefile ever feels like freeing */ X X_freefile(fp); X Xreturn ret; X} EOF chmod 664 straopen.c shouldbe=644 size=`wc -c < straopen.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting straopen.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file straopen.c" 1>&2; fi if test $overwritecheck = no -o ! -f strautil.c; then case $verbose in yes) echo "extracting strautil.c";; esac sed 's/^X//' > strautil.c <<\EOF X#include <stdio.h> X#include "funcs.h" X X_saflsbuf(c, fp) Xchar c; Xregister FILE *fp; X{ Xint chunk = 10; /* make it global so tunable? */ Xint newsize; Xchar *newbase; X Xnewsize = fp->_bufsiz + chunk; X X#ifndef SAFEREALLOC Xif(fp->_base == NULL) X newbase = (*_mallocfunc)(newsize); Xelse X#endif X newbase = (*_reallocfunc)(fp->_base, newsize); X Xif(newbase == NULL) X { X if(fp->_errfunc != NULL) X (*fp->_errfunc)(fp->_filename, 'm', fp); /* ? */ X return EOF; X } X X/* relocate _ptr in case _base moved */ X Xfp->_ptr = newbase + (fp->_ptr - fp->_base); X Xfp->_base = newbase; Xfp->_bufsiz = newsize; X Xfp->_cnt += chunk - 1; /* -1 because we're about to put a char */ X X/* could/should use putc(), but paranoid about looping */ X Xreturn *fp->_ptr++ = c; /* mask & 0377? */ X} X X_initsafile(fp) Xregister FILE *fp; X{ X_initsfile(fp); X Xfp->_base = fp->_ptr = NULL; Xfp->_cnt = fp->_bufsiz = 0; Xfp->_flag |= _IOWRT; Xfp->_flsbuf = _saflsbuf; X} X Xchar * X_safinish(fp) Xregister FILE *fp; X{ Xreturn (*_reallocfunc)(fp->_base, fp->_bufsiz - fp->_cnt); X} EOF chmod 664 strautil.c shouldbe=1022 size=`wc -c < strautil.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting strautil.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file strautil.c" 1>&2; fi if test $overwritecheck = no -o ! -f strnopen.c; then case $verbose in yes) echo "extracting strnopen.c";; esac sed 's/^X//' > strnopen.c <<\EOF X#include <stdio.h> X Xextern FILE *_getfile(); X XFILE * Xstrnopen(str, n, mode) Xchar *str; Xint n; Xchar *mode; X{ Xregister FILE *fp; X Xif((fp = _getfile()) == NULL) X return NULL; X X_initfile(fp); X Xfp->_base = fp->_ptr = str; Xfp->_cnt = n; X Xif(*mode == 'r') X { X fp->_flag |= _IOREAD; X } Xelse if(*mode == 'w' || *mode == 'a') X { X fp->_flag |= _IOWRT; X if(*mode == 'a') X { X int len; X X /* X * Ambiguity: n is size of buffer, not length X * of existing string. X */ X X len = strlen(str); X if(len > n) X len = n; X X fp->_ptr += len; X fp->_cnt -= len; X } X } Xelse { X _freefile(fp); X return NULL; X } X Xreturn fp; X} EOF chmod 644 strnopen.c shouldbe=609 size=`wc -c < strnopen.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting strnopen.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file strnopen.c" 1>&2; fi if test $overwritecheck = no -o ! -f stropen.c; then case $verbose in yes) echo "extracting stropen.c";; esac sed 's/^X//' > stropen.c <<\EOF X#include <stdio.h> X Xextern FILE *_getfile(); X XFILE * Xstropen(str, mode) Xchar *str; Xchar *mode; X{ Xregister FILE *fp; X Xif((fp = _getfile()) == NULL) X return NULL; X X_initsfile(fp); X Xfp->_base = fp->_ptr = str; X Xif(*mode == 'r') X { X fp->_cnt = strlen(str); X fp->_flag |= _IOREAD; X } Xelse if(*mode == 'w' || *mode == 'a') X { X fp->_cnt = 32767; /* oughta be INT_MAX or something */ X fp->_flag |= _IOWRT; X if(*mode == 'a') X fp->_ptr += strlen(str); X } Xelse { X _freefile(fp); X return NULL; X } X Xreturn fp; X} EOF chmod 644 stropen.c shouldbe=501 size=`wc -c < stropen.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting stropen.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file stropen.c" 1>&2; fi if test $overwritecheck = no -o ! -f strutil.c; then case $verbose in yes) echo "extracting strutil.c";; esac sed 's/^X//' > strutil.c <<\EOF X#include <stdio.h> X X_initsfile(fp) Xregister FILE *fp; X{ X_initfile(fp); X Xfp->_flag = _IOSTRG; X X/* _IOSTRG should keep I/O functions from getting called, but just in case: */ X Xfp->_readfunc = fp->_writefunc = NULL; Xfp->_seekfunc = NULL; Xfp->_closefunc = NULL; X Xfp->_file = -1; X} EOF chmod 664 strutil.c shouldbe=277 size=`wc -c < strutil.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting strutil.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file strutil.c" 1>&2; fi if test $overwritecheck = no -o ! -f ungetc.c; then case $verbose in yes) echo "extracting ungetc.c";; esac sed 's/^X//' > ungetc.c <<\EOF X#include <stdio.h> X Xungetc(c, fp) Xint c; XFILE *fp; X{ Xif(c == EOF || !(fp->_flag & _IOREAD)) X return EOF; X Xif(fp->_base == NULL) X { X /* X * Could call _getbuf, but the doc sez you've gotta have read X * at least one character, which will have taken care of it. X */ X X return EOF; X } X Xif(fp->_cnt < 0) /* should never happen, given paranoid _filbuf */ X return EOF; X Xif(fp->_ptr > fp->_base) X { X fp->_ptr--; X if(*fp->_ptr != c) X *fp->_ptr = c; X fp->_cnt++; X fp->_flag &= ~_IOEOF; X return c; X } X X/* X * This case (_ptr == _base) should only be reached if an ungetc X * is attempted immediately after an f*open or fseek, which is X * not required to work. X */ X Xreturn EOF; X} EOF chmod 644 ungetc.c shouldbe=673 size=`wc -c < ungetc.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting ungetc.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file ungetc.c" 1>&2; fi if test $overwritecheck = no -o ! -f vfprintf.c; then case $verbose in yes) echo "extracting vfprintf.c";; esac sed 's/^X//' > vfprintf.c <<\EOF X#include <stdio.h> X#include <stdarg.h> X Xvfprintf(fd, fmt, argp) XFILE *fd; Xchar *fmt; Xva_list argp; X{ Xreturn _doprnt(fmt, argp, fd); X} EOF chmod 644 vfprintf.c shouldbe=134 size=`wc -c < vfprintf.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting vfprintf.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file vfprintf.c" 1>&2; fi if test $overwritecheck = no -o ! -f vfscanf.c; then case $verbose in yes) echo "extracting vfscanf.c";; esac sed 's/^X//' > vfscanf.c <<\EOF X#include <stdio.h> X#include <stdarg.h> X Xvfscanf(fp, fmt, argp) XFILE *fp; Xchar *fmt; Xva_list argp; X{ Xreturn _doscan(fp, fmt, argp); X} EOF chmod 664 vfscanf.c shouldbe=133 size=`wc -c < vfscanf.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting vfscanf.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file vfscanf.c" 1>&2; fi if test $overwritecheck = no -o ! -f vprintf.c; then case $verbose in yes) echo "extracting vprintf.c";; esac sed 's/^X//' > vprintf.c <<\EOF X#include <stdio.h> X#include <stdarg.h> X Xvprintf(fmt, argp) Xchar *fmt; Xva_list argp; X{ Xreturn _doprnt(fmt, argp, stdout); X} EOF chmod 644 vprintf.c shouldbe=123 size=`wc -c < vprintf.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting vprintf.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file vprintf.c" 1>&2; fi if test $overwritecheck = no -o ! -f vsaprintf.c; then case $verbose in yes) echo "extracting vsaprintf.c";; esac sed 's/^X//' > vsaprintf.c <<\EOF X/* X * char *vsaprintf(fmt, va_list) X * X * Like vsprintf, but malloc's its own buffer. X * Returns pointer to malloc'ed memory just big enough to hold X * formatted string. X * Caller must free this memory if/when no longer needed. X */ X X#include <stdio.h> X#include <stdarg.h> X Xextern char *(*_reallocfunc)(); X Xextern int _saflsbuf(); X Xchar * Xvsaprintf(fmt, argp) Xchar *fmt; Xva_list argp; X{ XFILE f; X X_initsfile(&f); X Xf._base = f._ptr = NULL; Xf._cnt = f._bufsiz = 0; Xf._flag |= _IOWRT; Xf._flsbuf = _saflsbuf; X X_doprnt(fmt, argp, &f); X Xputc('\0', &f); X Xreturn (*_reallocfunc)(f._base, f._bufsiz - f._cnt); X} EOF chmod 644 vsaprintf.c shouldbe=606 size=`wc -c < vsaprintf.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting vsaprintf.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file vsaprintf.c" 1>&2; fi if test $overwritecheck = no -o ! -f vscanf.c; then case $verbose in yes) echo "extracting vscanf.c";; esac sed 's/^X//' > vscanf.c <<\EOF X#include <stdio.h> X#include <stdarg.h> X Xvscanf(fmt, argp) Xchar *fmt; Xva_list argp; X{ Xreturn _doscan(stdin, fmt, argp); X} EOF chmod 664 vscanf.c shouldbe=121 size=`wc -c < vscanf.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting vscanf.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file vscanf.c" 1>&2; fi if test $overwritecheck = no -o ! -f vsprintf.c; then case $verbose in yes) echo "extracting vsprintf.c";; esac sed 's/^X//' > vsprintf.c <<\EOF X#include <stdio.h> X#include <stdarg.h> X Xvsprintf(s, fmt, argp) Xchar *s; Xchar *fmt; Xva_list argp; X{ XFILE f; Xint r; X Xf._base = f._ptr = s; Xf._cnt = 32767; /* oughta be INT_MAX or something */ Xf._flag = _IOWRT | _IOSTRG; X X/* _IOSTRG should keep _writefunc from getting called, but just in case: */ X Xf._writefunc = NULL; Xf._file = -1; X Xr = _doprnt(fmt, argp, &f); X Xputc('\0', &f); X Xreturn r; X} EOF chmod 644 vsprintf.c shouldbe=393 size=`wc -c < vsprintf.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting vsprintf.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file vsprintf.c" 1>&2; fi if test $overwritecheck = no -o ! -f vsscanf.c; then case $verbose in yes) echo "extracting vsscanf.c";; esac sed 's/^X//' > vsscanf.c <<\EOF X#include <stdio.h> X#include <stdarg.h> X Xvsscanf(s, fmt, argp) Xchar *s; Xchar *fmt; Xva_list argp; X{ XFILE f; X Xf._base = f._ptr = s; Xf._cnt = f._bufsiz = strlen(s); Xf._flag |= _IOREAD | _IOSTRG; X X/* _IOSTRG should keep _writefunc from getting called, but just in case: */ X Xf._readfunc = NULL; Xf._file = -1; X Xreturn _doscan(&f, fmt, argp); X} EOF chmod 664 vsscanf.c shouldbe=337 size=`wc -c < vsscanf.c` if test $size -ne $shouldbe; then echo "shar: $0: error extracting vsscanf.c ($size != $shouldbe)" 1>&2 fi else echo "shar: $0: will not overwrite existing file vsscanf.c" 1>&2; fi exit