[comp.os.minix] Another new stdio

nfs@notecnirp.Princeton.EDU (Norbert Schlenker) (09/30/89)

Here is my stdio package, in a number of pieces.  The package is split up
as follows:

  Part 0:  Release notes
  Part 1:  An install script, 2 makefiles, and a CRC list
  Part 2:  New and replacement include files
  Part 3:  The stdio routines
  Part 4:  A few other routines that I'm throwing in

Now for the notes:

Part 0
------
  1. Find some disk space to work in (500K should do nicely - if you're
     using 360K floppies only, you will have to do some juggling).
  2. Make yourself a nice new directory with some name you like.  Cd to
     it and make a subdirectory named "sys".  Then feed parts 1 through 4
     into /bin/sh, which extracts a bundle of files.

Part 1
------
  1. You'd better make sure everything unpacked alright.  Type
     "make crclist" and compare crclist with the unpacked CRCLIST.

  2. Edit "Install" and change the shell variables at the front to reflect
     your configuration.  Note that MAKEDIR should be the directory
     you have unbundled things into, and that TMPDIR should be another
     directory entirely.  DO NOT MAKE THESE TWO THE SAME!

  3. Change the CFLAGS variable in accordance with the notes just above
     its definition.  A few extra notes:
      -	If you have installed Simon Poole's FS patches, then write()
	automatically writes at end of file when a file is opened for
	append.  Otherwise, you need a kludge that (sort of) simulates
	this.  To get it, the symbol _V7 must be defined.
      - The machine definition (i8088/ATARI_ST) is needed for stdarg.h
	and the files that use it.  Since I do not have access to an
	Atari, I tested the Atari code on a Sun 3, where it seems to
	work fine.  Please tell me if it doesn't.  If you are running
	on a machine that is neither of these, edit stdarg.h to reflect
	how your machine handles the stack for procedure calls and define
	this symbol appropriately.  If you are using another machine,
	I'd like to know what definitions you use; please email me.
      - Define NDEBUG if you want very little error checking in the
	stdio routines.  Without this definition, more error checking
	is done than with the old stdio.  With it, almost none is done.
      - Define _SAFEMACRO if you want a little extra speed out of 
	the stdio and ctype routines.  This is perhaps not worthwhile.

  4. Edit "Makefile.libc".  I use this makefile to build my libc.a.  I
     think it's pretty logically laid out, and I have run into few
     ordering problems since I made it up.  (I also suggest that something
     like this be supplied with distributions from now on.)  If you have
     local modules that need to be added, do so in an appropriate place.

  5. Ensure you have sufficient permissions to update the directories
     holding the standard headers and the library.  Root is good (I
     promise, there's no "cd /;rm -rf *" in the script).  I use a
     special id with fewer privileges.

  6. Feed Install to /bin/sh.  It will make copies of your old headers
     and library, install the new headers, make the new library routines,
     create a new library and install it.

  7. You'd better save the source files in an archive somewhere.  Since
     this is too variable, I figured you could do it manually.  Make
     sure you save the file "stdiolib.h" with the stdio library sources.
     "lib.h" is the standard Minix issue - it's there for completeness.

  8. You are ready to roll.  Recompile your old sources ... I think 
     you'll find this new stdio rather faster than the standard one.
     On my machine, it is competitive with Earl Chew's package (a little
     faster here, a little slower there).

  9. Send me bug reports.

Part 2
------
This is a completely new set of standard headers.  I have copies of 
the December 1988 draft ANSI C standard and POSIX, and have tried to
be as faithful to both as possible.  In particular:

  - The headers include prototypes for all required functions.  An
    additional header, <prototype.h>, is used to get rid of the
    prototypes for nonconforming compilers (i.e. ACK and ilk).
  - Strictly conforming ANSI compilers will have a fit about "const"
    when compiling some code (GNU just gives warnings).  Rather than
    copy const strings to non-const ones, which is what causes the
    most problems in the stdio package, I would elect to simply
    #define const to be the null string (even for __STDC__).
  - ANSI is pretty strict about name space pollution (if it doesn't
    start with an underscore and ANSI doesn't mention it, you can't
    have it).  I think I've done pretty well in this regard, but
    there are exceptions (particuarly <signal.h> and <time.h>).
  - Various headers that should be included are not.  I have not
    supplied <float.h>, <locale.h>, or <math.h>.  I look forward to
    having them.
  - Copyright acknowledgements: <errno.h> is pretty much like the original;
    <dirent.h> and <sys/dirent.h> are minor variations on Doug Gwyn's.
  - Quite a few things are left undone, especially for POSIX.
    Grep for "PENDING" in the headers.

Part 3
------
The stdio part of the library is completely rewritten.  Where that 
intersects with other parts of the library, I have modified small
pieces of old code.

Stdio is ANSI compatible (I hope).  It includes the two POSIX extensions,
fdopen() and fileno().  There are functions behind all macros; if
you want them, you can simply #undef the macro name.  FILEs are statically
allocated; buffers are dynamically allocated.  Further details include:

  - All error checking of arguments has been moved into _io_assert macros.
    By default, this macro returns the standard error value defined at
    the start of each function.  If you want extra debugging, change
    the definition of _io_assert in "stdiolib.h" to squawk.  Compiling
    with -DNDEBUG gets rid of all the error checking (if you want a
    faster library and you know your code is OK).  I have two copies of
    libc.a, one with no debugging and one with debugging (which I named
    libdbg.a).  I added support for -g in cc.c to link with libdbg.a.
  - fopen(), freopen(), fdopen() support update modes (r+,w+,a+).  Until
    the kernel supports append mode properly, files opened a/a+ work
    almost correctly.  The exception is on files with shared filp entries
    (fork() side effect), where problems may arise.
  - remove() added
  - rename() added (Freeman Pascal's version)
  - tmpfile() and tmpnam() added.  Files opened by tmpfile() are 
    automatically deleted at close() or exit().
  - fflush() works as POSIX demands.  fflush(NULL) flushes all streams.
  - setvbuf() added.  Per ANSI, setbuf() now has slightly different
    semantics:  if given a NULL buffer pointer, it makes the stream _IONBF.
  - printf() family supports all ANSI types except floating point (I'll
    get around to it).  That includes %n.
  - scanf() family supports all ANSI types except floating point (including %n).
  - getc() and putc() are now unsafe macros.  They're fast!
  - fgetc() and fputc() can be macros if you #define _SAFEMACRO when 
    compiling source.  Note that the library had better have been compiled
    similarly.
  - gets() has different semantics: a string ending in EOF with no NL
    will be returned; EOF will be returned on the next gets().
  - ungetc() works once on unbuffered files
  - fread()/fwrite() are much faster than the standard issue; fread()
    with small objects is much faster than Earl Chew's.
  - fseek() no longer clears the error indicator
  - fgetpos() and fsetpos() are included
  - fseek() / fsetpos() / rewind() all allow switching of update mode
    streams from read to write and vice versa.  Compiled with -DNDEBUG,
    the code will not verify that these switches occur at appropriate
    times.  Without it, errors are returned if you switch without one
    of these being called.
  - perror() is pretty much standard Minix 1.3
  - cleanup.c is replaced by _cleanup.c
  - atexit() is copyright Frank Wortner
  - exit() is slightly changed
  - streams attached to tty's are automatically line buffered (_IOLBF).
    This means that stdout, in particular, may work more slowly than
    in the standard package.  ANSI requires this to be done, so I did
    it.  If you take a big performance hit and are willing to lose a
    buffer full of your output, use setvbuf() to get full buffering
    (_IOFBF).  Note that this holds for all interactive output streams.
  - stdout on a tty is flushed if any unbuffered or line buffered
    stream is read.  In particular, you will see all of your stdout
    output before reading from stdin occurs.  Note that this is not
    true for other output streams (ANSI says this may be done, but it's
    not required - the performance loss is substantial).

Part 4
------
There is a slightly modified version of ctype.c, which matches <ctype.h>.

I have included rewritten versions of printk() and prints().  printk()
is an exact duplicate of printf(), save for NO floating point support,
and the fact that it uses the kernel's putc() for output.  It includes
_doprnt.c, which means that changes in the standard formatted output
routines should be reflected in printk() as well.  prints() is a cut-down
version of printf() that only handles %c and %s, BUT (like the old one)
it doesn't justify correctly, and it isn't synchronized with any stream.
It does save space if you don't need numeric formatting (~1K).

Included are ANSI conforming div(), ldiv(), strtol(), and strtoul().
strtol() includes replacements for atoi() and atol(), since they are
so similar to strtol().

Also included are POSIX compliant versions of cuserid(), getlogin(),
getgrent(), and getpwent().  The first two are pretty much the same
as Terrence Holm's versions; the second two are adaptations of 
the originals by Patrick van Kleef.  getgrent() needs more work to
be really POSIX compliant.

The commands [chgrp, chown, id, login, ls, passwd, stat, su, uudecode, whoami]
depend on either <grp.h> or <pwd.h> and should probably be recompiled.
The existing versions will continue to work as currently linked.

nfs@notecnirp.Princeton.EDU (Norbert Schlenker) (09/30/89)

echo x - Install
sed '/^X/s///' > Install << '/'
X#!/bin/sh
X# Run with appropriate permissions.
X# Assumes entire package is unpacked in ${MAKEDIR}.
X# Before running, modify the following to reflect what you want.
X
X# Should be an absolute directory with sufficient size to hold the
X# packaged source and the accompanying object files.
XMAKEDIR=/usr/nfs/lib
X
X# Should be an absolute directory with sufficient size to hold all
X# !!!EXISTING!!! library objects.  Must be different than MAKEDIR.
XTMPDIR=/usr/nfs/tmp
X
X# Should be the existing location of standard headers.
XINCLUDE=/usr/include
X
X# Should be the existing location of the C library.
XLIB=/usr/lib
X
X# Should be the C library name.
XLIBC=libc.a
X
X# Old include files will have this suffix added to their names.
X# Old library will be moved to its existing name plus this suffix.
XSUFFIX=.orig
X
X# Change to reflect what you want.
X# -LIB -D_MINIX should always be there (for the ACK compiler).
X# -D_V7		is required if you don't have Simon Poole's FS patches.
X# -Di8088/-DATARI_ST must be specified to describe the target machine.
X# -DNDEBUG	if you want no debugging in the library routines.
X# -D_SAFEMACRO	if you want a few extra ctype/stdio macros for speed.
X
XCFLAGS='-LIB -D_MINIX -D_V7 -Di8088 -DNDEBUG -D_SAFEMACRO'
X
Xif test ${TMPDIR} = ${MAKEDIR}
Xthen
Xecho Please change either TMPDIR or MAKEDIR.
Xexit
Xfi
X
X# Save old library routines.
Xecho Saving old library ${LIBC} as ${LIB}/${LIBC}${SUFFIX}
Xif mv ${LIB}/${LIBC} ${LIB}/${LIBC}${SUFFIX}
Xthen echo
Xelse echo "Couldn't save original ${LIBC}"
Xexit
Xfi
X
X# Extract existing routines.
Xecho Extracting existing library routines.
Xcd ${TMPDIR}
Xar x ${LIB}/${LIBC}${SUFFIX}
X
X# Install new include files.
Xecho "Installing new headers in ${INCLUDE}; old ones saved with suffix ${SUFFIX}"
Xcd ${MAKEDIR}
Xmv stdiolib.h stdiolib.H	# Don't install these two in ${INCLUDE}
Xmv lib.h lib.H
Xfor i in *.h
Xdo if test -f ${INCLUDE}/${i}
Xthen mv ${INCLUDE}/${i} ${INCLUDE}/${i}${SUFFIX}
Xfi
Xdone
Xmv *.h ${INCLUDE}
Xmv stdiolib.H stdiolib.h
Xmv lib.H lib.h
Xcd sys
Xfor i in *.h
Xdo if test -f ${INCLUDE}/${i}
Xthen mv ${INCLUDE}/sys/${i} ${INCLUDE}/sys/${i}${SUFFIX}
Xfi
Xdone
Xmv *.h ${INCLUDE}/sys
X
X# Make new library routines.
Xecho Making new library routines.
Xcd ${MAKEDIR}
Xif make CFLAGS="${CFLAGS}" objects
Xthen echo  Make complete.
Xelse echo  Make aborted.
Xexit
Xfi
X
X# Install new library routines.
Xecho Installing new routines in ${LIB}/${LIBC}.
Xcd ${MAKEDIR}
Xfor i in *.s
Xdo rm -f ${TMPDIR}/${i}; mv ${i} ${TMPDIR}
Xdone
Xcd ${TMPDIR}		# Remove some extra hangers on.
Xrm -f atoi.s atol.s cleanup.s doprintf.s fprintf.s printdat.s puts.s vsprintf.s
Xmake -f ${MAKEDIR}/Makefile.libc TARGET=${LIBC}
Xmv ${LIBC} ${LIB}
X
X# Clean up.
Xrm .Made
Xrm -f [a-e]*.s
Xrm -f [f-j]*.s
Xrm -f [k-o]*.s
Xrm -f [p-t]*.s
Xrm -f [u-z]*.s
Xecho Installation complete.
Xecho
Xecho All the new sources can be found in ${MAKEDIR} - save them in an
Xecho appropriate location.  Be sure to save "lib.h" and "stdiolib.h".
/
echo x - Makefile
sed '/^X/s///' > Makefile << '/'
XCFLAGS = -LIB -D_MINIX -D_V7 -Di8088 -DNDEBUG -D_SAFEMACRO
X
XSTDIO = _bufproc.s _cleanup.s _doprnt.s _doscan.s _filbuf.s _flsbuf.s	\
X	_flspbuf.s _iobdata.s _iobproc.s _ioinit.s _valmode.s		\
X	atexit.s exit.s fclose.s fdopen.s fflush.s			\
X	fgetc.s fgets.s fopen.s fputc.s fputs.s fread.s			\
X	freopen.s fseek.s ftell.s fwrite.s gets.s perror.s		\
X	printf.s remove.s rename.s scanf.s setvbuf.s			\
X	sprintf.s sscanf.s stdio_misc.s tmpfile.s tmpnam.s ungetc.s
X
XSTDLIB = div.s ldiv.s strtol.s strtoul.s
X
XCTYPE = ctype.s
X
XOTHERS = printk.s prints.s cuserid.s getlogin.s getgrent.s getpwent.s
X
Xobjects: $(STDIO) $(STDLIB) $(CTYPE) $(OTHERS)
X
Xcrclist:
X	crc I* M*   >crclist
X	crc *.h     >>crclist
X	crc sys/*.h >>crclist
X	crc *.c     >>crclist
/
echo x - Makefile.libc
sed '/^X/s///' > Makefile.libc << '/'
XCURSES = curses.s termcap.s
X
XMISCELLANEOUS = getpass.s lock.s popen.s putenv.s getopt.s stderr.s \
X	itoa.s ffs.s swab.s stb.s getutil.s portio.s
X
XANSI_UNISTD = ctermid.s cuserid.s execlp.s getcwd.s getlogin.s \
X	getgrent.s getpwent.s ttyname.s
X
XIOCTL = gtty.s stty.s ioctl.s
X
XAMOEBA = uniqport.s amoeba.s
X
XTIME = ctime.s 
X
XSTRERROR = strerror.s
X
XSTDIO = fclose.s fdopen.s fopen.s freopen.s tmpfile.s _valmode.s \
X	scanf.s sscanf.s _doscan.s \
X	fgets.s fread.s gets.s fgetc.s ungetc.s _filbuf.s \
X	printf.s sprintf.s _doprnt.s \
X	fputs.s fwrite.s fputc.s _flsbuf.s \
X	fseek.s ftell.s perror.s setvbuf.s stdio_misc.s tmpnam.s \
X	_ioinit.s _cleanup.s fflush.s _flspbuf.s \
X	_bufproc.s _iobproc.s _iobdata.s \
X	remove.s rename.s
X
XNOT_STDIO = mktemp.s printk.s prints.s
X
XSTDLIB = abort.s abs.s atexit.s bsearch.s div.s getenv.s ldiv.s \
X	malloc.s qsort.s rand.s strtol.s strtoul.s system.s \
X	lrand.s lsearch.s
X
XCTYPE = ctype.s 
X
XDIRENT = opendir.s closedir.s telldir.s rewinddir.s seekdir.s readdir.s \
X	getdents.s
X
XSETJMP = setjmp.s
X
XREGEXP = regexp.s regsub.s
X
XSTRING_BSD = bcmp.s bcopy.s bzero.s
XSTRING_SYSV = index.s rindex.s
XSTRING = $(STRING_BSD) $(STRING_SYSV) \
X	memccpy.s memchr.s memcmp.s memcpy.s memset.s \
X	strstr.s strcat.s strchr.s strcmp.s strcpy.s strcspn.s strlen.s \
X	strncat.s strncmp.s strncpy.s strpbrk.s strrchr.s strspn.s strtok.s
X
XCRYPT = crypt.s
X
XCLEAN_UNISTD = isatty.s sleep.s
X
XUNIX =	access.s alarm.s chdir.s chmod.s chown.s chroot.s close.s creat.s \
X	dup.s dup2.s exec.s fork.s fstat.s getegid.s geteuid.s getgid.s \
X	getuid.s kill.s link.s lseek.s brk.s brk2.s brksize.s mknod.s \
X	getpid.s getppid.s mount.s open.s pause.s pipe.s read.s setgid.s \
X	setuid.s signal.s catchsig.s stat.s stime.s sync.s time.s times.s \
X	umask.s umount.s unlink.s utime.s wait.s write.s 
X
XMINIX_INTERFACE = syslib.s call.s message.s sendrec.s
X
XCOMPILER_INTERNAL = \
X	adi.s and.s blm.s cii.s cmi4.s cms.s cmu4.s com.s csa2.s csb2.s \
X	cuu.s _dup.s dvi4.s dvu4.s exg.s fakfp.s gto.s iaar.s ilar.s \
X	inn.s ior.s isar.s lar2.s loi.s mli4.s mon.s nop.s rck.s \
X	rmi4.s rmu4.s sar2.s sbi.s set.s sti.s strhp.s xor.s \
X	ret6.s ret8.s lfr6.s lfr8.s retarea.s return.s
X
XCOMPILER_TRAP = error.s unknown.s fat.s trp.s vars.s
X
XEXIT = stop.s exit.s  
X
Xlibc.a: .Made
X	-mv libc.a libc.a.orig
X	ar q libc.a $(CURSES)
X	ar q libc.a $(MISCELLANEOUS)
X	ar q libc.a $(ANSI_UNISTD)
X	ar q libc.a $(IOCTL)
X	ar q libc.a $(AMOEBA)
X	ar q libc.a $(TIME)
X	ar q libc.a $(STRERROR)
X	ar q libc.a $(STDIO)
X	ar q libc.a $(NOT_STDIO)
X	ar q libc.a $(STDLIB)
X	ar q libc.a $(CTYPE)
X	ar q libc.a $(DIRENT)
X	ar q libc.a $(SETJMP)
X	ar q libc.a $(REGEXP)
X	ar q libc.a $(STRING)
X	ar q libc.a $(CRYPT)
X	ar q libc.a $(CLEAN_UNISTD)
X	ar q libc.a $(UNIX)
X	ar q libc.a $(MINIX_INTERFACE)
X	ar q libc.a $(COMPILER_INTERNAL)
X	ar q libc.a $(COMPILER_TRAP)
X	ar q libc.a $(EXIT)
X	touch .Made
X
X.Made:	$(CURSES)
X.Made:	$(MISCELLANEOUS)
X.Made:	$(ANSI_UNISTD)
X.Made:	$(IOCTL)
X.Made:	$(AMOEBA)
X.Made:	$(TIME)
X.Made:	$(STRERROR)
X.Made:	$(STDIO)
X.Made:	$(NOT_STDIO)
X.Made:	$(STDLIB)
X.Made:	$(CTYPE)
X.Made:	$(DIRENT)
X.Made:	$(SETJMP)
X.Made:	$(REGEXP)
X.Made:	$(STRING)
X.Made:	$(CRYPT)
X.Made:	$(UNIX)
X.Made:	$(MINIX_INTERFACE)
X.Made:	$(COMPILER_INTERNAL)
X.Made:	$(COMPILER_TRAP)
X.Made:	$(EXIT)
/
echo x - CRCLIST
sed '/^X/s///' > CRCLIST << '/'
X42976   2909 Install
X29509    736 Makefile
X49536   3238 Makefile.libc
X36390    306 assert.h
X04501   1827 ctype.h
X16607    894 dirent.h
X61144   1267 errno.h
X23155   1390 fcntl.h
X59055    478 grp.h
X36738    293 lib.h
X56982   1251 limits.h
X36832    166 prototype.h
X18121    553 pwd.h
X18182    721 setjmp.h
X23686   2249 signal.h
X46349   1465 stdarg.h
X46642    579 stddef.h
X41917   6158 stdio.h
X42306   1348 stdiolib.h
X34643   2233 stdlib.h
X31036   2807 string.h
X25499   3361 termios.h
X10320   1246 time.h
X05318   3507 unistd.h
X17559    389 utime.h
X47700   1421 sys/dirent.h
X23639   2125 sys/stat.h
X45063    429 sys/times.h
X03055    707 sys/types.h
X63086    483 sys/utsname.h
X56375    887 sys/wait.h
X44639   1012 _bufproc.c
X09696    202 _cleanup.c
X33452   9856 _doprnt.c
X52978   8006 _doscan.c
X53014   1148 _filbuf.c
X01268   1447 _flsbuf.c
X17271    728 _flspbuf.c
X00706    538 _iobdata.c
X38693   1043 _iobproc.c
X36193   1515 _ioinit.c
X09043    983 _valmode.c
X64177   1126 atexit.c
X20154   2579 ctype.c
X16928    348 cuserid.c
X22853    167 div.c
X07059    334 exit.c
X24358    525 fclose.c
X17370   1056 fdopen.c
X36047   1371 fflush.c
X41316    625 fgetc.c
X00549    681 fgets.c
X39208   1593 fopen.c
X17604    847 fputc.c
X34903    625 fputs.c
X33170   2925 fread.c
X63326   1735 freopen.c
X52582   1164 fseek.c
X00763    963 ftell.c
X36592   3251 fwrite.c
X18799   1882 getgrent.c
X61455    286 getlogin.c
X12848   1852 getpwent.c
X63222    424 gets.c
X08852    180 ldiv.c
X06090   1546 perror.c
X48671   1415 printf.c
X25746    120 printk.c
X01820   1420 prints.c
X35554    262 remove.c
X32949   1739 rename.c
X56330    939 scanf.c
X01335   1251 setvbuf.c
X60329   1091 sprintf.c
X50293    437 sscanf.c
X03709    763 stdio_misc.c
X34867   1609 strtol.c
X63398   1466 strtoul.c
X17346   1152 tmpfile.c
X49999    993 tmpnam.c
X30591    815 ungetc.c
/

nfs@notecnirp.Princeton.EDU (Norbert Schlenker) (09/30/89)

echo x - assert.h
sed '/^X/s///' > assert.h << '/'
X#ifndef __ASSERT_H
X#define __ASSERT_H
X
X/* --- Macros --- */
X#ifndef NDEBUG
X#define assert(p)							\
X  if(!(p)) {								\
X	fprintf(stderr, "False assertion at line %d in file \"%s\"\n",	\
X		 __LINE__, __FILE__);					\
X	exit(1);							\
X  }
X#else
X#define assert(p)
X#endif
X
X#endif /* !defined __ASSERT_H */
/
echo x - ctype.h
sed '/^X/s///' > ctype.h << '/'
X#ifndef __CTYPE_H
X#define __CTYPE_H
X
X/* --- Inclusions --- */
X#include "prototype.h"
X
X/* --- Constants --- */
X#define	_CT_U	0x01
X#define	_CT_L	0x02
X#define	_CT_N	0x04
X#define	_CT_S	0x08
X#define _CT_P	0x10
X#define _CT_C	0x20
X#define _CT_X	0x40
X#define _CT_SP	0x80
X
X/* --- Prototypes --- */
Xint isalnum	_PROTO((int c));
Xint isalpha	_PROTO((int c));
Xint isascii	_PROTO((int c));
Xint iscntrl	_PROTO((int c));
Xint isdigit	_PROTO((int c));
Xint isgraph	_PROTO((int c));
Xint islower	_PROTO((int c));
Xint isprint	_PROTO((int c));
Xint ispunct	_PROTO((int c));
Xint isspace	_PROTO((int c));
Xint isupper	_PROTO((int c));
Xint isxdigit	_PROTO((int c));
Xint toascii	_PROTO((int c));
Xint _tolower	_PROTO((int c));
Xint _toupper	_PROTO((int c));
Xint tolower	_PROTO((int c));
Xint toupper	_PROTO((int c));
X
X/* --- Storage --- */
Xextern char _ctype[];
X#ifdef _SAFEMACRO
Xextern int _ct_c;
X#endif
X
X/* --- Macros --- */
X#define isalnum(c)	((_ctype+1)[c] & (_CT_U|_CT_L|_CT_N))
X#define	isalpha(c)	((_ctype+1)[c] & (_CT_U|_CT_L))
X#define isascii(c)	((unsigned)(c) <= 0x7f)
X#define iscntrl(c)	((_ctype+1)[c] & (_CT_C))
X#define	isdigit(c)	((_ctype+1)[c] & (_CT_N))
X#define isgraph(c)	((_ctype+1)[c] & (_CT_U|_CT_L|_CT_N|_CT_P))
X#define	islower(c)	((_ctype+1)[c] & (_CT_L))
X#define isprint(c)	((_ctype+1)[c] & (_CT_U|_CT_L|_CT_N|_CT_P|_CT_SP))
X#define ispunct(c)	((_ctype+1)[c] & (_CT_P))
X#define	isspace(c)	((_ctype+1)[c] & (_CT_S|_CT_SP))
X#define	isupper(c)	((_ctype+1)[c] & (_CT_U))
X#define	isxdigit(c)	((_ctype+1)[c] & (_CT_N|_CT_X))
X
X#define toascii(c)	((c) & 0x7f)
X#define _tolower(c)	((c) - 'A' + 'a')
X#define _toupper(c)	((c) - 'a' + 'A')
X#ifdef _SAFEMACRO
X#define tolower(c)	(_ct_c = (c), _isupper(_ct_c) ? _tolower(_ct_c) : _ct_c)
X#define toupper(c)	(_ct_c = (c), _islower(_ct_c) ? _toupper(_ct_c) : _ct_c)
X#endif
X
X#endif /* !defined __CTYPE_H */
/
echo x - dirent.h
sed '/^X/s///' > dirent.h << '/'
X#ifndef __DIRENT_H
X#define __DIRENT_H
X
X/*
X	<dirent.h> -- definitions for SVR3 directory access routines
X
X	last edit:	25-Apr-1987	D A Gwyn
X*/
X
X/* --- Prerequisites --- */
X#ifndef __SYS_TYPES_H
X#error <sys/types.h> is a prerequisite for <dirent.h>
X#endif
X
X/* --- Inclusions --- */
X#include "prototype.h"
X#include <sys/dirent.h>
X
X/* --- Types --- */
Xtypedef struct {
X  int	dd_fd;			/* file descriptor */
X  int	dd_loc;			/* offset in block */
X  int	dd_size;		/* amount of valid data */
X  char	*dd_buf;		/* -> directory block */
X} DIR;				/* stream data from opendir() */
X
X/* --- Prototypes --- */
XDIR	*opendir	_PROTO((char *dirname));
Xstruct dirent *readdir	_PROTO((DIR *dirp));
Xvoid	rewinddir	_PROTO((DIR *dirp));
Xint	closedir	_PROTO((DIR *dirp));
Xvoid	seekdir		_PROTO((DIR *dirp, off_t loc));	/* not POSIX */
Xoff_t	telldir		_PROTO((DIR *dirp));		/* not POSIX */
X
X#endif /* !defined __DIRENT_H */
/
echo x - errno.h
sed '/^X/s///' > errno.h << '/'
X#ifndef __ERRNO_H
X#define __ERRNO_H
X
X/* --- Constants --- */
X#define OK                 0
X#define ERROR              1
X#define EPERM              1
X#define ENOENT             2
X#define ESRCH              3
X#define EINTR              4
X#define EIO                5
X#define ENXIO              6
X#define E2BIG              7
X#define ENOEXEC            8
X#define EBADF              9
X#define ECHILD            10
X#define EAGAIN            11
X#define ENOMEM            12
X#define EACCES            13
X#define EFAULT            14
X#define ENOTBLK           15
X#define EBUSY             16
X#define EEXIST            17
X#define EXDEV             18
X#define ENODEV            19
X#define ENOTDIR           20
X#define EISDIR            21
X#define EINVAL            22
X#define ENFILE            23
X#define EMFILE            24
X#define ENOTTY            25
X#define ETXTBSY           26
X#define EFBIG             27
X#define ENOSPC            28
X#define ESPIPE            29
X#define EROFS             30
X#define EMLINK            31
X#define EPIPE             32
X#define EDOM              33
X#define ERANGE            34
X
X#define E_LOCKED         101
X#define E_BAD_CALL       102
X#define E_LONG_STRING    103
X
X/* --- Storage --- */
Xextern int errno;
X
X#endif /* !defined __ERRNO_H */
/
echo x - fcntl.h
sed '/^X/s///' > fcntl.h << '/'
X#ifndef __FCNTL_H
X#define __FCNTL_H
X
X/* --- Prerequisites --- */
X#ifndef __SYS_TYPES_H
X#error <sys/types.h> is a prerequisite for <fcntl.h>
X#endif
X
X/* --- Inclusions --- */
X#include "prototype.h"
X
X/* --- Constants --- */
X  /* --- For open(2) --- */
X#define O_RDONLY	0
X#define O_WRONLY	1
X#define O_RDWR		2
X#define	O_NONBLOCK	0x0004
X#define O_APPEND	0x0008
X#define O_NOCTTY	0x0100
X#define O_CREAT		0x0200
X#define O_TRUNC		0x0400
X#define O_EXCL		0x0800
X  /* --- For fcntl(2) --- */
X#define F_DUPFD		0
X#define F_GETFD		1
X#define F_SETFD		2
X#define F_GETFL		3
X#define F_SETFL		4
X#define F_GETLK		7
X#define F_SETLK		8
X#define F_SETLKW	9
X  /* --- fcntl(2) descriptor flags --- */
X#define FD_CLOEXEC	0x4000			/* Arbitrary!! */
X  /* --- fcntl(2) lock flags --- */
X#define F_RDLCK		1
X#define F_WRLCK		2
X#define F_UNLCK		3
X  /* --- Compatibility --- */
X#ifdef _SYSV
X#define O_NDELAY	O_NONBLOCK
X#endif
X
X#ifdef _BSD
X#define FNDELAY		O_NONBLOCK
X#define FAPPEND		O_APPEND
X#define FCREAT		O_CREAT
X#define FTRUNC		O_TRUNC
X#define FEXCL		O_EXCL
X#define F_GETOWN	5
X#define F_SETOWN	6
X#endif
X
X/* --- Structures --- */
Xstruct flock {
X  short l_type;
X  short l_whence;
X  off_t l_start;
X  off_t l_len;
X  pid_t l_pid;
X};
X
X/* --- Prototypes --- */
Xint	open	_PROTO((char *path, int oflag, ...));
Xint	creat	_PROTO((char *path, mode_t mode));
Xint	fcntl	_PROTO((int fd, int cmd, ...));
X
X#endif /* !defined __FCNTL_H */
/
echo x - grp.h
sed '/^X/s///' > grp.h << '/'
X#ifndef __GRP_H
X#define __GRP_H
X
X/* --- Prerequisites --- */
X#ifndef __SYS_TYPES_H
X#error <sys/types.h> is a prerequisite for <grp.h>
X#endif
X
X/* --- Inclusions --- */
X#include "prototype.h"
X
X/* --- Structures --- */
Xstruct group {
X  char	*gr_name;
X  char	*gr_passwd;		/* not required by POSIX */
X  gid_t	gr_gid;
X  char	**gr_mem;
X};
X
X/* --- Prototypes --- */
Xstruct group *getgrgid	_PROTO((gid_t gid));
Xstruct group *getgrnam	_PROTO((char *name));
X
X#endif /* !defined __GRP_H */
/
echo x - lib.h
sed '/^X/s///' > lib.h << '/'
X#include <minix/const.h>
X#include <minix/type.h>
X#include <minix/callnr.h>
X#include <errno.h>
X
Xextern message M;
X
X#define MM                 0
X#define FS                 1
X
Xextern int callm1(), callm3(), callx(), len();
Xextern int errno;
Xextern int begsig();		/* interrupts all vector here */
/
echo x - limits.h
sed '/^X/s///' > limits.h << '/'
X#ifndef __LIMITS_H
X#define __LIMITS_H
X
X/* --- Constants --- */
X#define CHAR_BIT	    8
X#define SCHAR_MIN	 -128
X#define SCHAR_MAX	  127
X#define CHAR_MIN	 -128	/* char is signed by default */
X#define CHAR_MAX	  127
X#define UCHAR_MAX	  255
X#define SHRT_MIN       -32767	/* PENDING - Minix 1.3 compiler bug */
X#define SHRT_MAX	32767
X#define USHRT_MAX	65535
X#define INT_MIN	       -32767	/* PENDING - Minix 1.3 compiler bug */
X#define INT_MAX		32767
X#define UINT_MAX	65535
X#define LONG_MIN  -2147483647	/* PENDING - Minix 1.3 compiler bug */
X#define LONG_MAX   2147483647
X#define ULONG_MAX  4294967295
X
X#ifdef _POSIX_SOURCE
X#define _POSIX_ARG_MAX		4096
X#define _POSIX_CHILD_MAX	6
X#define _POSIX_LINK_MAX		8
X#define _POSIX_MAX_CANON	255
X#define _POSIX_MAX_INPUT	255
X#define _POSIX_NAME_MAX		14
X#define _POSIX_NGROUPS_MAX	0
X#define _POSIX_OPEN_MAX		16
X#define _POSIX_PATH_MAX		255
X#define _POSIX_PIPE_BUF		512
X
X#define NGROUPS_MAX		0
X#define ARG_MAX			2048	/* PENDING - POSIX requires >= 4096 */
X#define OPEN_MAX		20
X#define LINK_MAX		127
X#define MAX_CANON		256
X#define MAX_INPUT		256
X#define NAME_MAX		14
X#define PATH_MAX		127	/* PENDING - POSIX requires >= 256 */
X#define PIPE_BUF		7168
X
X#endif /* defined _POSIX_SOURCE */
X
X#endif /* !defined __LIMITS_H */
/
echo x - prototype.h
sed '/^X/s///' > prototype.h << '/'
X#ifndef __PROTOTYPE_H
X#define __PROTOTYPE_H
X
X#ifdef __STDC__
X#define _PROTO(p) p
X#else
X#define _PROTO(p) ()
X#define const
X#endif
X
X#endif /* !defined __PROTOTYPE_H */
/
echo x - pwd.h
sed '/^X/s///' > pwd.h << '/'
X#ifndef __PWD_H
X#define __PWD_H
X
X/* --- Prerequisites --- */
X#ifndef __SYS_TYPES_H
X#error <sys/types.h> is a prerequisite for <pwd.h>
X#endif
X
X/* --- Inclusions --- */
X#include "prototype.h"
X
X/* --- Structures --- */
Xstruct passwd {
X	char *pw_name;
X	char *pw_passwd;	/* not required by POSIX */
X	uid_t pw_uid;
X	gid_t pw_gid;
X	char *pw_gecos;		/* not required by POSIX */
X	char *pw_dir;
X	char *pw_shell;
X};
X
X/* --- Prototypes --- */
Xstruct passwd *getpwuid	_PROTO((uid_t uid));
Xstruct passwd *getpwnam	_PROTO((char *name));
X
X#endif /* !defined __PWD_H */
/
echo x - setjmp.h
sed '/^X/s///' > setjmp.h << '/'
X#ifndef __SETJMP_H
X#define __SETJMP_H
X
X/* --- Inclusions --- */
X#include "../include/prototype.h"
X
X/* --- Constants --- */
X#ifndef _JB_LEN
X#ifdef i8088
X#define _JB_LEN	3
X#else
X#ifdef ATARI_ST
X#define _JB_LEN	13
X#else
X#error Either i8088 or ATARI_ST must be defined!
X#endif
X#endif
X#endif
X
X/* --- Types --- */
Xtypedef int jmp_buf[_JB_LEN];
X#ifdef _POSIX_SOURCE
Xtypedef int sigjmp_buf[_JB_LEN + sizeof(long)]	/* PENDING - just a guess! */
X#endif
X
X/* --- Prototypes --- */
Xint	setjmp		_PROTO((jmp_buf env));
Xvoid	longjmp		_PROTO((jmp_buf env, int value));
X#ifdef _POSIX_SOURCE
Xint	sigsetjmp	_PROTO((sigjmp_buf env, int savemask));
Xvoid	siglongjmp	_PROTO((sigjmp_buf env, int value));
X#endif
X
X#endif /* !defined __SETJMP_H */
/
echo x - signal.h
sed '/^X/s///' > signal.h << '/'
X#ifndef __SIGNAL_H
X#define __SIGNAL_H
X
X/* --- Prerequisites --- */
X#ifdef _POSIX_SOURCE
X#ifndef __SYS_TYPES_H
X#error <sys/types.h> is a prerequisite for <signal.h>
X#endif
X#endif
X
X/* --- Inclusions --- */
X#include "prototype.h"
X
X/* --- Constants --- */
X#define SIG_ERR	(void (*)())-1
X#define	SIG_DFL	(void (*)())0
X#define	SIG_IGN	(void (*)())1
X
X#define NSIG	16	/* PENDING! This limit needs to be 32 but the code */
X#define NR_SIGS NSIG	/* PENDING! in the kernel isn't fixed yet.  Also,  */
X#define STACK_FAULT 16	/* PENDING! these names pollute the name space.    */
X
X#define	SIGHUP	1	/* hangup */
X#define SIGINT	2	/* interrupt (DEL) */
X#define SIGQUIT	3	/* quit (ASCII FS) */
X#define SIGILL	4	/* illegal instruction (not reset when caught)*/
X#define SIGTRAP	5	/* trace trap (not reset when caught) */
X#define SIGABRT	6	/* abnormal termination */
X#define SIGIOT	SIGABRT	/* compatibility - IOT instruction (PDP 11!) */
X#define SIGEMT	7	/* EMT instruction (PDP 11!) */
X#define SIGFPE	8	/* floating point exception */
X#define SIGKILL	9	/* kill (cannot be caught or ignored) */
X#define SIGBUS	10	/* bus error */
X#define SIGSEGV	11	/* segmentation violation */
X#define SIGSYS	12	/* bad argument to system call */
X#define SIGPIPE	13	/* write on a pipe with no one to read it */
X#define SIGALRM	14	/* alarm clock */
X#define SIGTERM	15	/* software termination signal from kill */
X/*#define SIGUSR1	30	/* user defined signal 1 */
X/*#define SIGUSR2	31	/* user defined signal 2 */
X
X  /* --- Job control (POSIX requires definition but not support) --- */
X#define SIGSTOP	17	/* stop (cannot be caught or ignored) */
X#define SIGTSTP	18	/* interactive stop signal */
X#define SIGCONT	19	/* continue if stopped */
X#define SIGCHLD	20	/* child process terminated or stopped */
X#define SIGTTIN	21	/* to reader's process group on background read */
X#define SIGTTOU	22	/* to writer's process group on background write */
X
X/* --- Types --- */
Xtypedef int sig_atomic_t;
X
X/* --- Function prototypes --- */
Xint	raise	_PROTO((int sig));
Xvoid	(*signal _PROTO((int sig, void (*func)(int)))) _PROTO((int));
X#ifdef _POSIX_SOURCE
Xint	kill	_PROTO((pid_t pid, int sig));
X/* PENDING - A zillion sig* functions required by POSIX are missing. */
X#endif
X
X#endif /* !defined __SIGNAL_H */
/
echo x - stdarg.h
sed '/^X/s///' > stdarg.h << '/'
X#ifndef __STDARG_H
X#define __STDARG_H
X
X/* --- Types --- */
X#ifndef _VA_LIST
X#define _VA_LIST
Xtypedef char * va_list;
X#endif
X
X/* --- Definitions --- */
X  /* --- Add your favourite machine here! --- */
X  /*	_STK_OP	    indicates which way addresses change as one moves
X		    along an argument list
X	_STK_OPE    is _STK_OP with an = behind it
X	_STK_ALIGN  is the minimum number of bytes moved by a stack PUSH
X	_STK_OFFSET is the offset of an argument after the pointer has
X		    been bumped.
X	For example, if a machine has 4 bytes to a word, little endian,
X	grows its stack downwards and always pushes at least a word,
X	then we should define:
X	_STK_OP		+
X	_STK_OP		+=
X	_STK_ALIGN	4
X	_STK_OFFSET(v)	((sizeof(v) == 1) ? -4 : ((sizeof(v) == 2) ? -2 : -1))
X  */
X
X#ifdef i8088
X#define _STK_OP		+	/* stack grows down */
X#define _STK_OPE	+=
X#define _STK_ALIGN	2	/* PUSH moves at least 2 bytes */
X#define _STK_OFFSET(v)	((sizeof(v) < 2) ? -2 : -1) /* little endian */
X#endif
X
X#ifdef ATARI_ST
X#define _STK_OP		+	/* stack grows down */
X#define _STK_OPE	+=
X#define _STK_ALIGN	2	/* PUSH moves at least 2 bytes */
X#define _STK_OFFSET(v)	-1	/* big endian */	
X#endif
X
X#define _STK_BUMP(v)	((sizeof(v) < _STK_ALIGN) ? _STK_ALIGN : sizeof(v))
X
X/* --- Macros --- */
X#define va_start(ap, last) ((ap) = (va_list) &(last) _STK_OP _STK_BUMP(last))
X#define va_arg(ap, type) (((type *) ((ap) _STK_OPE _STK_BUMP(type)))[_STK_OFFSET(type)])
X#define va_end(ap)
X
X#endif /* !defined __STDARG_H */
/
echo x - stddef.h
sed '/^X/s///' > stddef.h << '/'
X#ifndef __STDDEF_H
X#define __STDDEF_H
X
X/* --- Constants --- */
X#ifndef __STDC__
X#define NULL	0
X#else
X#define NULL	((void *) 0)
X#endif
X
X/* --- Types --- */
X#ifndef __SIZE_T
X#define __SIZE_T
Xtypedef unsigned int size_t;
X#endif
X
X#ifndef __PTRDIFF_T
X#define __PTRDIFF_T
Xtypedef int ptrdiff_t;		/* Should be like size_t plus a sign bit! */
X#endif
X
X#ifndef __WCHAR_T
X#define __WCHAR_T
Xtypedef char wchar_t;		/* No special support for wide characters! */
X#endif
X
X/* --- Macros --- */
X#define offsetof(type, member)	((size_t) (&(((type *) 0)->member)))
X
X#endif /* !defined __STDDEF_H */
/
echo x - stdio.h
sed '/^X/s///' > stdio.h << '/'
X#ifndef __STDIO_H
X#define __STDIO_H
X
X/* --- Inclusions --- */
X#include "prototype.h"
X
X/* --- Constants --- */
X#ifndef __STDC__
X#define NULL	0
X#else
X#define NULL	((void *) 0)
X#endif
X#define EOF	(-1)
X#define BUFSIZ	1024
X
X#define _IOFBF		0
X#define _IOLBF		_IO_LBUF
X#define _IONBF		(-1)
X#define L_tmpnam	(4 + 1 + FILENAME_MAX) /* "/tmp/" + file name + '\0' */
X#define TMP_MAX		32767		/* Arbitrary! */
X#define SEEK_SET	0
X#define SEEK_CUR	1
X#define SEEK_END	2
X#ifdef _POSIX_SOURCE
X#ifdef __LIMITS_H
X#define FILENAME_MAX	(NAME_MAX + 1)	/* includes room for trailing '\0' */
X#define FOPEN_MAX	OPEN_MAX
X#endif
X#define L_cuserid	(30+1)		/* Arbitrary! */
X#define L_ctermid	(10+1)		/* Arbitrary! */
X#endif
X#ifndef FILENAME_MAX
X#define FILENAME_MAX	15		/* 14 character file name + '\0' */
X#define FOPEN_MAX	20
X#endif
X
X/* --- Types --- */
X#ifndef __SIZE_T
X#define __SIZE_T
Xtypedef unsigned int size_t;
X#endif
X
X#ifndef _VA_LIST
X#define _VA_LIST
Xtypedef char * va_list;
X#endif
X
Xtypedef long fpos_t;
X
Xtypedef struct {
X  int		_io_fd;
X  unsigned int	_io_flags;
X  int		_io_count;
X  int		_io_bufsiz;
X  unsigned char	*_io_buf;
X  union {
X  unsigned char	*_io_ptr;
X  int		_io_char;
X  } _io;
X} FILE;
X
X/* --- Definitions --- */
X#define stdin	(&_iob[0])
X#define stdout	(&_iob[1])
X#define stderr	(&_iob[2])
X  /* --- Flag bits --- */
X#define _IO_READ	0x0001
X#define _IO_WRITE	0x0002
X#define _IO_UPDATE	0x0004
X#define _IO_LBUF	0x0008
X#define _IO_MYBUF	0x0010
X#define _IO_EOF		0x0020
X#define _IO_ERR		0x0040
X#define _IO_STRING	0x0080
X#define _IO_TEMP	0x0100
X#define _IO_TTY		0x1000
X#ifdef _V7
X#define _IO_APPEND	0x4000		/* won't be needed with Posix */
X#define _IO_NEEDSEEK	0x8000		/* won't be needed with Posix */
X#endif
X
X/* --- Prototypes --- */
X  /* --- Streams: open and close --- */
Xint	fclose	_PROTO((FILE *stream));
X#ifdef _POSIX_SOURCE
XFILE	*fdopen	_PROTO((int fd, const char *mode));
X#endif
XFILE	*fopen	_PROTO((const char *filename, const char *mode));
XFILE	*freopen _PROTO((const char *filename, const char *mode, FILE *stream));
XFILE	*tmpfile _PROTO((void));
X  /* --- Streams: input --- */
Xint	fgetc	_PROTO((FILE *stream));
Xchar	*fgets	_PROTO((char *s, int n, FILE *stream));
Xsize_t	fread	_PROTO((void *ptr, size_t size, size_t nmemb, FILE *stream));
Xint	fscanf	_PROTO((FILE *stream, const char *format, ...));
Xint	getc	_PROTO((FILE *stream));
Xint	getchar	_PROTO((void));
Xchar	*gets	_PROTO((char *s));
Xint	scanf	_PROTO((const char *format, ...));
Xint	sscanf	_PROTO((const char *s, const char *format, ...));
Xint	ungetc	_PROTO((int c, FILE *stream));
X  /* --- Streams: output --- */
Xint	fprintf	_PROTO((FILE *stream, const char *format, ...));
Xint	fputc	_PROTO((int c, FILE *stream));
Xint	fputs	_PROTO((const char *s, FILE *stream));
Xsize_t	fwrite	_PROTO((const void *ptr, size_t size, size_t nmemb, FILE *stream));
Xint	printf	_PROTO((const char *format, ...));
Xint	putc	_PROTO((int c, FILE *stream));
Xint	putchar	_PROTO((int c));
Xint	puts	_PROTO((const char *s));
Xint	sprintf	_PROTO((char *s, const char *format, ...));
Xint	vfprintf _PROTO((FILE *stream, const char *format, va_list arg));
Xint	vprintf	_PROTO((const char *format, va_list arg));
Xint	vsprintf _PROTO((char *s, const char *format, va_list arg));
X  /* --- Streams: inquiry and control --- */
Xvoid	clearerr _PROTO((FILE *stream));
Xint	feof	_PROTO((FILE *stream));
Xint	ferror	_PROTO((FILE *stream));
Xint	fflush	_PROTO((FILE *stream));
Xint	fgetpos	_PROTO((FILE *stream, fpos_t *pos));
X#ifdef _POSIX_SOURCE
Xint	fileno	_PROTO((FILE *stream));
X#endif
Xint	fseek	_PROTO((FILE *stream, long int offset, int whence));
Xint	fsetpos	_PROTO((FILE *stream, const fpos_t *pos));
Xlong int ftell	_PROTO((FILE *stream));
Xvoid	rewind	_PROTO((FILE *stream));
Xvoid	setbuf	_PROTO((FILE *stream, char *buf));
Xint	setvbuf	_PROTO((FILE *stream, char *buf, int mode, size_t size));
X  /* --- File system manipulation --- */
Xint	remove	_PROTO((const char *filename));
Xint	rename	_PROTO((const char *old, const char *new));
X  /* --- Miscellaneous --- */
Xvoid	perror	_PROTO((const char *s));
Xchar	*tmpnam	_PROTO((char *s));
X
X/* --- Some standard functions are defined below as macros.  In	--- */
X/* --- general, using the macros results in faster code at the	--- */
X/* --- expense of larger code size and increased compile time.	--- */
X/* --- Any macro may be #undef'ed to expose a library function. --- */
X
X/* --- The macros getc() and putc() are "unsafe" in that they	--- */
X/* --- evaluate their arguments more than once.  By default,	--- */
X/* --- the safe alternatives are the functions fgetc()/fputc().	--- */
X/* --- #define _SAFEMACRO will define fgetc()/fputc() as	--- */
X/* ---		safe macros, at the cost of increased storage.	--- */
X
X  /* --- Streams: input --- */
X#ifdef _SAFEMACRO
X#define fgetc(f)	(_io_f = (f), getc(_io_f))
X#endif
X#define getc(f)	((--(f)->_io_count >= 0) ? *(f)->_io._io_ptr++ : _filbuf(f))
X#define getchar()	getc(stdin)
X  /* --- Streams: output --- */
X#ifdef _SAFEMACRO
X#define fputc(c, f)	(_io_c = (c), _io_f = (f), putc(_io_c, _io_f))
X#endif
X#define putc(c, f)							\
X  (									\
X   ((--(f)->_io_count < 0) || (_io_testflag(f, _IO_LBUF) && c == '\n'))	\
X	? _flsbuf(c, f)							\
X	: (int) (*(f)->_io._io_ptr++ = c)				\
X  )
X#define putchar(c)	putc(c, stdout)
X#define puts(s)								\
X  ((fputs(s, stdout) >= 0) ? ((putchar('\n') == '\n') ? 0 : EOF) : EOF)
X#define vfprintf(f, fmt, ap)	_doprnt(f, fmt, ap)
X#define vprintf(fmt, ap)	_doprnt(stdout, fmt, ap)
X  /* --- Streams: inquiry and control --- */
X#define clearerr(f)		_io_clearflag((f), (_IO_EOF | _IO_ERR))
X#define feof(f)			_io_testflag((f), _IO_EOF)
X#define ferror(f)		_io_testflag((f), _IO_ERR)
X#define _io_testflag(f, flag)	((f)->_io_flags & (flag))
X#ifdef _POSIX_SOURCE
X#define fileno(f)	((f)->_io_fd)
X#endif /* defined _POSIX_SOURCE */
X#define fgetpos(f, p)	((*(p) = (fpos_t) ftell(f)) >= 0L) ? 0 : EOF)
X#define fsetpos	(f, p)	fseek((f), *(p), SEEK_SET)
X#define setbuf(f, b) setvbuf((f), (b), ((b) == NULL) ? _IONBF : _IOFBF, BUFSIZ)
X  /* --- File system manipulation --- */
X#define remove(p)	unlink(p)
X
X/* --- Storage --- */
Xextern FILE _iob[FOPEN_MAX];
X
X#ifdef _SAFEMACRO
Xextern FILE *_io_f;
Xextern int _io_c;
X#endif
X
X#endif /* !defined __STDIO_H */
/
echo x - stdiolib.h
sed '/^X/s///' > stdiolib.h << '/'
X#ifndef __STDIOLIB_H
X#define __STDIOLIB_H
X
X/* --- Inclusions --- */
X#include "prototype.h"
X
X/* --- Constants --- */
X#define _IO_NEVER	(-1)	/* MAGIC count for virgin streams */
X#define P_tmpdir	"/tmp"	/* directory for temporary files */
X
X/* --- Prototypes --- */
Xvoid	_bufalloc	_PROTO((FILE *stream));
Xvoid	_buffree	_PROTO((FILE *stream));
Xvoid	_cleanup	_PROTO((void));
Xint	_doprnt		_PROTO((FILE *stream, const char *format, va_list arg));
Xint	_doscan		_PROTO((int is_string, void *source, const char *format, va_list arg));
Xint	_filbuf		_PROTO((FILE *stream));
Xint	_flsbuf		_PROTO((int c, FILE *stream));
Xint	_flspbuf	_PROTO((FILE *stream));
XFILE	*_ioballoc	_PROTO((void));
Xvoid	_iobfree	_PROTO((FILE *stream));
Xint	_iobindex	_PROTO((FILE *stream));
Xvoid	_i_init		_PROTO((FILE *stream));
Xvoid	_o_init		_PROTO((FILE *stream));
Xint	_valmode	_PROTO((const char *mode));
X
X/* --- Macros --- */
X#define _io_valid(f)		(_iobindex(f) >= 0)
X#define _io_setflag(f, flag)	((f)->_io_flags |= (flag))
X#define _io_clearflag(f, flag)	((f)->_io_flags &= ~(flag))
X
X#ifdef NDEBUG
X#define _io_assert(condition)
X#define _io_guarded(stmt)
X#else
X#define _io_assert(condition)	\
X  if (!(condition))		\
X	return (_IO_ERRVAL)
X#define _io_guarded(stmt) (stmt)
X#endif /* !defined NDEBUG */
X
X/* --- Storage --- */
Xextern void (*__cleanup)();
X
X#endif /* !defined __STDIOLIB_H */
/
echo x - stdlib.h
sed '/^X/s///' > stdlib.h << '/'
X#ifndef __STDLIB_H
X#define __STDLIB_H
X
X/* --- Inclusions --- */
X#include "prototype.h"
X
X/* --- Constants --- */
X#ifndef __STDC__
X#define NULL	0
X#else
X#define NULL	((void *) 0)
X#endif
X#define RAND_MAX	32767
X#define EXIT_SUCCESS	0
X#define EXIT_FAILURE	1
X
X/* --- Types --- */
X#ifndef __SIZE_T
X#define __SIZE_T
Xtypedef unsigned int size_t;
X#endif
X
X#ifndef __WCHAR_T
X#define __WCHAR_T
Xtypedef char wchar_t;		/* No special support for wide characters! */
X#endif
X
X#ifndef __DIV_T
X#define __DIV_T
Xtypedef struct {int quot; int rem;} div_t;
X#endif
X
X#ifndef __LDIV_T
X#define __LDIV_T
Xtypedef struct {long int quot; long int rem;} ldiv_t;
X#endif
X
X/* --- Prototypes --- */
X  /* --- String conversion --- */
Xdouble	atof	_PROTO((const char *nptr));
Xint	atoi	_PROTO((const char *nptr));
Xlong	atol	_PROTO((const char *nptr));
Xdouble	strtod	_PROTO((const char *nptr, char **endptr));
Xlong	strtol	_PROTO((const char *nptr, char **endptr, int base));
Xunsigned long strtoul _PROTO((const char *nptr, char **endptr, int base));
X  /* --- Pseudo-random sequence generation --- */
Xint	rand	_PROTO((void));
Xvoid	srand	_PROTO((unsigned int seed));
X  /* --- Memory management --- */
Xvoid 	*calloc	_PROTO((size_t nmemb, size_t size));
Xvoid	free	_PROTO((void *ptr));
Xvoid	*malloc	_PROTO((size_t size));
Xvoid	*realloc _PROTO((void *ptr, size_t size));
X  /* --- Communication with the environment --- */
Xvoid	abort	_PROTO((void));
Xint	atexit	_PROTO((void (*func)(void)));
Xvoid	exit	_PROTO((int status));
Xchar	*getenv	_PROTO((const char *name));
Xint	system	_PROTO((const char *string));
X  /* --- Searching and sorting --- */
Xvoid	*bsearch _PROTO((const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)));
Xvoid	qsort	_PROTO((void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)));
X  /* --- Integer arithmetic --- */
Xint	abs	_PROTO((int j));
Xdiv_t	div	_PROTO((int numer, int denom));
Xlong int labs	_PROTO((long int j));
Xldiv_t	ldiv	_PROTO((long int numer, long int denom));
X  /* --- Multibyte characters --- */
X/* Nothing implemented! */
X
X/* --- Macros --- */
X#define atoi(nptr)	((int) strtol((nptr), NULL, 10))
X#define atol(nptr)	strtol((nptr), NULL, 10)
X
X#endif /* !defined __STDLIB_H */
/
echo x - string.h
sed '/^X/s///' > string.h << '/'
X#ifndef __STRING_H
X#define __STRING_H
X
X/* --- Inclusions --- */
X#include "prototype.h"
X
X/* --- Constants --- */
X#ifndef __STDC__
X#define NULL	0
X#else
X#define NULL	((void *) 0)
X#endif
X
X/* --- Types --- */
X#ifndef __SIZE_T
X#define __SIZE_T
Xtypedef unsigned int size_t;
X#endif
X
X/* --- Prototypes --- */
X/*
X# String library.		Author: Henry Spencer
X
X# Configuration settings:  how should "size_t", "void *", "const" be written?
X# "size_t" is what's needed to hold the result of sizeof; beware of problems
X# with compatibility here, because X3J11 uses this for e.g. the third
X# argument of strncpy() as well.  You may need to make it "int" even if
X# this is a lie.  "void *" is the generic pointer type, "char *" in most
X# existing implementations.  "const" is the keyword marking read-only
X# variables and parameters, unimplemented in most existing implementations.
X# These things need to be defined this way because they must be fitted into
X# both the .h files and the .c files; see the make instructions for string.h
X# in the Makefile.
X
XSIZET = int
XVOIDSTAR = char *
XLVOIDSTAR = char*	# Lint shell file has problems with * alone.  Barf.
XCONST = 
X*/
X
X/*
X * String functions.
X */
X
Xvoid	*memcpy	_PROTO((void *dst, const void *src, size_t size));
Xvoid	*memccpy _PROTO((void *dst, const void *src, int ucharstop, size_t size));
Xchar	*strcpy	_PROTO((char *dst, const char *src));
Xchar	*strncpy _PROTO((char *dst, const char *src, size_t size));
Xchar	*strcat	_PROTO((char *dst, const char *src));
Xchar	*strncat _PROTO((char *dst, const char *src, size_t size));
Xint	memcmp	_PROTO((const void *s1, const void *s2, size_t size));
Xint	strcmp	_PROTO((const char *s1, const char *s2));
Xint	strncmp	_PROTO((const char *s1, const char *s2, size_t size));
Xvoid	*memchr	_PROTO((const void *s, int ucharwanted, size_t size));
Xchar	*strchr	_PROTO((const char *s, int charwanted));
Xsize_t	strcspn	_PROTO((const char *s, const char *reject));
Xchar	*strpbrk _PROTO((const char *s, const char *breakat));
Xchar	*strrchr _PROTO((const char *s, int charwanted));
Xsize_t	strspn	_PROTO((const char *s, const char *accept));
Xchar	*strstr	_PROTO((const char *s, const char *wanted));
Xchar	*strtok	_PROTO((char *s, const char *delim));
Xvoid	*memset	_PROTO((void *s, int ucharfill, size_t size));
Xsize_t	strlen	_PROTO((const char *s));
X
X/*
X * V7 and Berklix compatibility.
X */
X#ifdef _V7
Xchar	*index	_PROTO((const char *s, int charwanted));
Xchar	*rindex	_PROTO((const char *s, int charwanted));
X#endif
X#ifdef _BSD
Xint	bcopy	_PROTO((const char *src, char *dst, int length));
Xint	bcmp	_PROTO((const char *s1, const char *s2, int length));
Xint	bzero	_PROTO((char *dst, int length));
X#endif
X
X/*
X * Putting this in here is really silly, but who am I to argue with X3J11?
X */
Xchar *strerror	_PROTO((int errnum));
X
X#endif /* !defined __STRING_H */
/
echo x - termios.h
sed '/^X/s///' > termios.h << '/'
X#ifndef __TERMIOS_H
X#define __TERMIOS_H
X
X/* --- Inclusions --- */
X#include "prototype.h"
X
X/* PENDING - Fill these in when implemented. */
X/* PENDING - POSIX insists that all must be defined, even if unsupported. */
X/* --- Constants --- */
X  /* --- Input modes (c_iflag) --- */
X#define BRKINT			/* Signal interrupt on break */
X#define ICRNL			/* Map CR to NL on input */
X#define IGNBRK			/* Ignore break condition */
X#define IGNCR			/* Ignore CR */
X#define IGNPAR			/* Ignore characters with parity errors */
X#define INLCR			/* Map NL to CR on input */
X#define INPCK			/* Enable input parity check */
X#define ISTRIP			/* Strip character */
X#define IXOFF			/* Enable start/stop input control */
X#define IXON			/* Enable start/stop output control */
X#define PARMRK			/* Mark parity errors */
X  /* --- Output modes (c_oflag) --- */
X#define OPOST			/* Perform output processing */
X  /* --- Control modes (c_cflag) --- */
X#define CLOCAL			/* Ignore modem status lines */
X#define CREAD			/* Enable receiver */
X#define CSIZE			/* Number of bits per byte */
X#define   CS5			/*   5 bits */
X#define   CS6			/*   6 bits */
X#define   CS7			/*   7 bits */
X#define   CS8			/*   8 bits */
X#define CSTOPB			/* Send two stop bits, else one */
X#define HUPCL			/* Hang up on last close */
X#define PARENB			/* Parity enable */
X#define PARODD			/* Odd parity, else even */
X  /* --- Local modes (c_lflag) --- */
X#define ECHO			/* Enable echo */
X#define ECHOE			/* Echo ERASE as an error-correcting BS */
X#define ECHOK			/* Echo KILL */
X#define ECHONL			/* Echo '\n' */
X#define ICANON			/* Canonical input (erase and kill) */
X#define IEXTEN			/* Enable extended functions */
X#define ISIG			/* Enable signals */
X#define NOFLSH			/* Disable flush after interrupt, quit, suspend */
X#define TOSTOP			/* Send SIGTTOU for background output */
X  /* --- Special control characters --- */
X#define NCCS			/* Number of control characters */
X#define VEOF
X#define VEOL
X#define VERASE
X#define VINTR
X#define VKILL
X#define VMIN
X#define VQUIT
X#define VSUSP
X#define VTIME
X#define VSTART
X#define VSTOP
X  /* --- Line speeds --- */
X#define B0			/* Hang up */
X#define B50
X#define B75
X#define B110
X#define B134
X#define B150
X#define B200
X#define B300
X#define B600
X#define B1200
X#define B1800
X#define B2400
X#define B4800
X#define B9600
X#define B19200
X#define B38400
X
X/* --- Types --- */
X#ifndef __TCFLAG_T
X#define __TCFLAG_T
Xtypedef unsigned int tcflag_t;
X#endif
X
X#ifndef __CC_T
X#define __CC_T
Xtypedef unsigned int cc_t;
X#endif
X
X#ifndef __SPEED_T
X#define __SPEED_T
Xtypedef unsigned char speed_t;
X#endif
X
X/* --- Structures --- */
Xstruct termios {
X  tcflag_t	c_iflag;
X  tcflag_t	c_oflag;
X  tcflag_t	c_cflag;
X  tcflag_t	c_lflag;
X  cc_t		c_cc[NCCS];
X  speed_t	c_ispeed;
X  speed_t	c_ospeed;
X};
X
X/* --- Prototypes --- */
Xspeed_t	cfgetospeed	_PROTO((struct termios *termios_p));
Xspeed_t	cfsetospeed	_PROTO((struct termios *termios_p, speed_t speed));
Xspeed_t	cfgetispeed	_PROTO((struct termios *termios_p));
Xspeed_t	cfsetispeed	_PROTO((struct termios *termios_p, speed_t speed));
Xint	tcgetattr	_PROTO((int fd, struct termios *termios_p));
Xint	tcsetattr	_PROTO((int fd, int actions, struct termios *termios_p));
Xint	tcsendbreak	_PROTO((int fd, int duration));
Xint	tcdrain		_PROTO((int fd));
Xint	tcflush		_PROTO((int fd, int queue_selector));
Xint	tcflow		_PROTO((int fd, int action));
X
X#endif /* !defined __TERMIOS_H */
/
echo x - time.h
sed '/^X/s///' > time.h << '/'
X#ifndef __TIME_H
X#define __TIME_H
X
X/* --- Inclusions --- */
X#include "prototype.h"
X
X/* --- Constants --- */
X#ifndef __STDC__
X#define NULL	0
X#else
X#define NULL	((void *) 0)
X#endif
X#define CLOCKS_PER_SEC	60
X#define CLK_TCK		CLOCKS_PER_SEC	/* PENDING - looks like ANSI won't like this */
X
X/* --- Types --- */
X#ifndef __SIZE_T
X#define __SIZE_T
Xtypedef unsigned int size_t;
X#endif
X
X#ifndef __CLOCK_T
X#define __CLOCK_T
Xtypedef long int clock_t;
X#endif
X
X#ifndef __TIME_T
X#define __TIME_T
Xtypedef long int time_t;
X#endif
X
X/* --- Structures --- */
Xstruct tm {
X	int	tm_sec;
X	int	tm_min;
X	int	tm_hour;
X	int	tm_mday;
X	int	tm_mon;
X	int	tm_year;
X	int	tm_wday;
X	int	tm_yday;
X	int	tm_isdst;
X};
X
X/* --- Prototypes --- */
Xchar	*asctime	_PROTO((const struct tm *timeptr));
Xclock_t	clock		_PROTO((void));
Xchar	*ctime		_PROTO((time_t *timer));
Xdouble	difftime	_PROTO((time_t time1, time_t time2));
Xstruct tm *gmtime	_PROTO((const time_t *timer));
Xstruct tm *localtime	_PROTO((const time_t *timer));
Xtime_t	mktime		_PROTO((struct tm *timeptr));
Xsize_t	strftime	_PROTO((char *s, size_t maxsize, const char *format, const struct tm *timeptr));
Xtime_t	time		_PROTO((time_t *timer));
X#ifdef _POSIX_SOURCE
Xvoid	tzset		_PROTO((void));
X#endif
X
X#endif /* !defined __TIME_H */
/
echo x - unistd.h
sed '/^X/s///' > unistd.h << '/'
X#ifndef __UNISTD_H
X#define __UNISTD_H
X
X/* --- Prerequisites --- */
X#ifndef __SYS_TYPES_H
X#error <sys/types.h> is a prerequisite for <unistd.h>
X#endif
X
X/* --- Inclusions --- */
X#include "prototype.h"
X
X/* --- Constants --- */
X#ifndef __STDC__
X#define NULL	0
X#else
X#define NULL	((void *) 0)
X#endif
X#define _POSIX_VERSION	198808L
X
X/* --- For access(2) --- */
X#define     R_OK     	4
X#define     W_OK     	2
X#define     X_OK     	1
X#define     F_OK     	0
X
X/* --- For lockf(2) --- */
X#define     F_ULOCK	0
X#define     F_LOCK	1
X#define     F_TLOCK	2
X#define     F_TEST	3
X
X/* --- For lseek(2) --- */
X#define     SEEK_SET	0
X#define     SEEK_CUR	1
X#define     SEEK_END	2
X
X/* --- For sysconf() --- */
X#define _SC_ARG_MAX	1
X#define _SC_CHILD_MAX	2
X#define _SC_CLK_TCK	3
X#define _SC_NGROUPS_MAX	4
X#define _SC_OPEN_MAX	5
X#define _SC_JOB_CONTROL	6
X#define _SC_SAVED_IDS	7
X#define _SC_VERSION	8
X
X/* --- Prototypes --- */
X  /* --- Process creation and execution --- */
Xpid_t	fork		_PROTO((void));
Xint	execl		_PROTO((char *path, ...));
Xint	execv		_PROTO((char *path, char *argv[]));
Xint	execle		_PROTO((char *path, ...));
Xint	execve		_PROTO((char *path, char *argv[], char *envp[]));
Xint	execlp		_PROTO((char *file, ...));
Xint	execvp		_PROTO((char *file, char *argv[]));
X  /* --- Process termination --- */
Xvoid	_exit		_PROTO((int status));
X  /* --- Timer operations --- */
Xunsigned int alarm	_PROTO((unsigned int seconds));
Xint	pause		_PROTO((void));
Xunsigned int sleep	_PROTO((unsigned int seconds));
X  /* --- Process identification --- */
Xpid_t	getpid		_PROTO((void));
Xpid_t	getppid		_PROTO((void));
X  /* --- User identification --- */
Xuid_t	getuid		_PROTO((void));
Xuid_t	geteuid		_PROTO((void));
Xgid_t	getgid		_PROTO((void));
Xgid_t	getegid		_PROTO((void));
Xint	setuid		_PROTO((uid_t uid));
Xint	setgid		_PROTO((gid_t gid));
Xint	getgroups	_PROTO((int gidsetsize, gid_t grouplist[]));
Xchar	*getlogin	_PROTO((void));
Xchar	*cuserid	_PROTO((char *s));
X  /* --- Process groups --- */
Xpid_t	getpgrp		_PROTO((void));
Xpid_t	setsid		_PROTO((void));
Xint	setpgid		_PROTO((pid_t pid, pid_t pgid));
X  /* --- Terminal identification --- */
Xchar	*ctermid	_PROTO((char *s));
Xchar	*ttyname	_PROTO((int fd));
Xint	isatty		_PROTO((int fd));
X  /* --- Configurable system variables --- */
Xlong	sysconf		_PROTO((int name));
X  /* --- Working directory --- */
Xint	chdir		_PROTO((char *path));
Xchar	*getcwd		_PROTO((char *buf, int size));
X  /* --- General file creation --- */
Xint	link		_PROTO((char *path1, char *path2));
X  /* --- File removal --- */
Xint	unlink		_PROTO((char *path));
Xint	rmdir		_PROTO((char *path));
X  /* --- File characteristics --- */
Xint	access		_PROTO((char *path, int amode));
Xint	chown		_PROTO((char *path, uid_t owner, gid_t group));
X  /* --- Configurable pathname variables --- */
Xlong	pathconf	_PROTO((char *path, int name));
Xlong	fpathconf	_PROTO((int fd, int name));
X  /* --- Pipes --- */
Xint	pipe		_PROTO((int fildes[2]));
X  /* --- File descriptor manipulation --- */
Xint	dup		_PROTO((int fd));
Xint	dup2		_PROTO((int fd, int fd2));
X  /* --- File descriptor deassignment --- */
Xint	close		_PROTO((int fd));
X  /* --- Input and output --- */
Xint	read		_PROTO((int fd, char *buf, unsigned int n));
Xint	write		_PROTO((int fd, char *buf, unsigned int n));
X  /* --- Control operations on files --- */
Xoff_t	lseek		_PROTO((int fd, off_t offset, int whence));
X  /* --- General terminal interface control --- */
Xpid_t	tcgetpgrp	_PROTO((int fd));
Xint	tcsetpgrp	_PROTO((int fd, pid_t pgrp_id));
X
X#endif /* !defined __UNISTD_H */
/
echo x - utime.h
sed '/^X/s///' > utime.h << '/'
X#ifndef __UTIME_H
X#define __UTIME_H
X
X/* --- Prerequisites --- */
X#ifndef __SYS_TYPES_H
X#error <sys/types.h> is a prerequisite for <utime.h>
X#endif
X
X/* --- Inclusions --- */
X#include "prototype.h"
X
X/* --- Structures --- */
Xstruct utimbuf {
X	time_t	actime;
X	time_t	modtime;
X};
X
X/* --- Prototypes --- */
Xint	utime	_PROTO((char *path, struct utimbuf *times));
X
X#endif /* !defined __UTIME_H */
/
echo x - sys/dirent.h
sed '/^X/s///' > sys/dirent.h << '/'
X#ifndef __SYS_DIRENT_H
X#define __SYS_DIRENT_H
X
X/*
X	<sys/dirent.h> -- file system independent directory entry (SVR3)
X
X	last edit:	27-Oct-1988	D A Gwyn
X
X	prerequisite:	<sys/types.h>
X*/
X
X/* --- Structures --- */
Xstruct dirent {			/* data from getdents()/readdir() */
X  long	d_ino;			/* inode number of entry */
X  off_t	d_off;			/* offset of disk directory entry */
X  unsigned short d_reclen;	/* length of this record */
X  char	d_name[1];		/* name of file */	/* non-ANSI */
X};
X
X#ifdef BSD_SYSV				/* (e.g., when compiling getdents.c) */
Xextern struct dirent	__dirent;	/* (not actually used) */
X/* The following is portable, although rather silly. */
X#define	DIRENTBASESIZ		(__dirent.d_name - (char *)&__dirent.d_ino)
X
X#else
X/* The following nonportable ugliness could have been avoided by defining
X   DIRENTSIZ and DIRENTBASESIZ to also have (struct dirent *) arguments.
X   There shouldn't be any problem if you avoid using the DIRENTSIZ() macro. */
X
X#define	DIRENTBASESIZ		(((struct dirent *)0)->d_name \
X				- (char *)&((struct dirent *)0)->d_ino)
X#endif
X
X#define	DIRENTSIZ( namlen )	((DIRENTBASESIZ + sizeof(long) + (namlen)) \
X				/ sizeof(long) * sizeof(long))
X
X/* DAG -- the following was moved from <dirent.h>, which was the wrong place */
X#define	MAXNAMLEN	512		/* maximum filename length */
X
X#ifndef NAME_MAX
X#define	NAME_MAX	(MAXNAMLEN - 1)	/* DAG -- added for POSIX */
X#endif
X
X#endif /* !defined __SYS_DIRENT_H */
/
echo x - sys/stat.h
sed '/^X/s///' > sys/stat.h << '/'
X#ifndef __SYS_STAT_H
X#define __SYS_STAT_H
X
X/* --- Prerequisites --- */
X#ifndef __SYS_TYPES_H
X#error <sys/types.h> is a prerequisite for <sys/stat.h>
X#endif
X
X/* --- Inclusions --- */
X#include "prototype.h"
X
X/* --- Constants --- */
X#define S_IFMT  0170000		/* type of file */
X#define S_IFDIR 0040000  	/* directory */
X#define S_IFCHR 0020000		/* character special */
X#define S_IFBLK 0060000		/* block special */
X#define S_IFREG 0100000		/* regular */
X#define S_IFIFO 0010000		/* named pipe (FIFO) */
X#define S_ISUID	04000		/* set user id on execution */
X#define S_ISGID	02000		/* set group id on execution */
X#define S_IRWXU	00700		/* owner rwx	*/
X#define S_IRUSR	00400		/* owner r	*/
X#define S_IWUSR	00200		/* owner  w	*/
X#define S_IXUSR	00100		/* owner   x	*/
X#define S_IRWXG	00070		/* group rwx	*/
X#define S_IRGRP	00040		/* group r	*/
X#define S_IWGRP	00020		/* group  w	*/
X#define S_IXGRP	00010		/* group   x	*/
X#define S_IRWXO	00007		/* other rwx	*/
X#define S_IROTH	00004		/* other r	*/
X#define S_IWOTH	00002		/* other  w	*/
X#define S_IXOTH	00001		/* other   x	*/
X
X  /* --- Compatibility --- */
X#define S_IREAD   S_IRUSR	/* read permission, owner */
X#define S_IWRITE  S_IWUSR	/* write permission, owner */
X#define S_IEXEC   S_IXUSR	/* execute/search permission, owner */
X#define S_ISVTX   01000		/* save swapped text even after use */
X
X/* --- Structures --- */
Xstruct stat {
X	dev_t	st_dev;
X	ino_t	st_ino;
X	mode_t	st_mode;
X	nlink_t	st_nlink;
X	uid_t	st_uid;
X	gid_t	st_gid;
X	dev_t	st_rdev;
X	off_t	st_size;
X	time_t	st_atime;
X	time_t	st_mtime;
X	time_t	st_ctime;
X};
X
X/* --- Macros --- */
X#define S_ISDIR(m)	((m) & S_IFDIR)
X#define S_ISCHR(m)	((m) & S_IFCHR)
X#define S_ISBLK(m)	((m) & S_IFBLK)
X#define S_ISREG(m)	((m) & S_IFREG)
X#define S_ISFIFO(m)	((m) & S_IFIFO)	/* PENDING - should catch pipes */
X
X/* --- Prototypes --- */
Xmode_t	umask	_PROTO((mode_t cmask));
Xint	mkdir	_PROTO((char *path, mode_t mode));
Xint	mkfifo	_PROTO((char *path, mode_t mode));
Xint	stat	_PROTO((char *path, struct stat *buf));
Xint	fstat	_PROTO((int fd, struct stat *buf));
Xint	chmod	_PROTO((char *path, mode_t mode));
X
X#endif /* !defined __SYS_STAT_H */
/
echo x - sys/times.h
sed '/^X/s///' > sys/times.h << '/'
X#ifndef __SYS_TIMES_H
X#define __SYS_TIMES_H
X
X/* --- Prerequisites --- */
X#ifndef __TIME_H
X#error <time.h> is a prerequisite for <sys/times.h>
X#endif
X
X/* --- Inclusions --- */
X#include "prototype.h"
X
X/* --- Structures --- */
Xstruct tms {
X	clock_t	tms_utime;
X	clock_t tms_stime;
X	clock_t	tms_cutime;
X	clock_t tms_cstime;
X};
X
X/* --- Prototypes --- */
Xclock_t	times	_PROTO((struct tms *buffer));
X
X#endif /* !defined __SYS_TIMES_H */
/
echo x - sys/types.h
sed '/^X/s///' > sys/types.h << '/'
X#ifndef __SYS_TYPES_H
X#define __SYS_TYPES_H
X
X/* --- Types --- */
X#ifndef __DEV_T
X#define __DEV_T
Xtypedef unsigned short int dev_t;
X#endif
X
X#ifndef __GID_T
X#define __GID_T
Xtypedef char gid_t;
X#endif
X
X#ifndef __INO_T
X#define __INO_T
Xtypedef unsigned short int ino_t;
X#endif
X
X#ifndef __MODE_T
X#define __MODE_T
Xtypedef unsigned short int mode_t;
X#endif
X
X#ifndef __NLINK_T
X#define __NLINK_T
Xtypedef char nlink_t;
X#endif
X
X#ifndef __OFF_T
X#define __OFF_T
Xtypedef long int off_t;
X#endif
X
X#ifndef __PID_T
X#define __PID_T
Xtypedef int pid_t;
X#endif
X
X#ifndef __UID_T
X#define __UID_T
Xtypedef short int uid_t;
X#endif
X
X#ifndef __TIME_T
X#define __TIME_T
Xtypedef long int time_t;
X#endif
X
X#endif /* !defined __SYS_TYPES_H */
/
echo x - sys/utsname.h
sed '/^X/s///' > sys/utsname.h << '/'
X#ifndef __SYS_UTSNAME_H
X#define __SYS_UTSNAME_H
X
X/* --- Inclusions --- */
X#include "prototype.h"
X
X/* --- Structures --- */
Xstruct utsname {
X  char	*sysname;		/* name of the operating system */
X  char	*nodename;		/* name of this node in the network */
X  char	*release;		/* release level */
X  char	*version;		/* version of the release */
X  char	*machine;		/* machine type */
X};
X
X/* --- Prototypes --- */
Xint	uname	_PROTO((struct utsname *name));
X
X#endif /* !defined __SYS_UTSNAME_H */
/
echo x - sys/wait.h
sed '/^X/s///' > sys/wait.h << '/'
X#ifndef __SYS_WAIT_H
X#define __SYS_WAIT_H
X
X/* --- Prerequisites --- */
X#ifndef __SYS_TYPES_H
X#error <sys/types.h> is a prerequisite for <sys/wait.h>
X#endif
X
X/* --- Inclusions --- */
X#include "prototype.h"
X
X/* --- Constants --- */
X/* PENDING - Define these when implemented. */
X#define WNOHANG
X#define WUNTRACED
X
X/* --- Macros --- */
X#define _STAT_LO(stat_val)	((stat_val) & 0xff)
X#define _STAT_HI(stat_val)	(((stat_val) >> 8) & 0xff)
X#define WIFEXITED(stat_val)	(_STAT_LO(stat_val) == 0)
X#define WEXITSTATUS(stat_val)	(_STAT_HI(stat_val))
X#define WIFSIGNALED(stat_val)	(_STAT_HI(stat_val) == 0 && _STAT_LO(stat_val) != 0)
X#define WTERMSIG(stat_val)	(_STAT_LO(stat_val))
X#define WIFSTOPPED(stat_val)
X#define WSTOPSIG(stat_val)
X
X/* --- Prototypes --- */
Xpid_t	wait	_PROTO((int *stat_loc));
Xpid_t	waitpid	_PROTO((pid_t pid, int *stat_loc, int options));
X
X#endif /* !defined __SYS_WAIT_H */
/

nfs@notecnirp.Princeton.EDU (Norbert Schlenker) (09/30/89)

echo x - _bufproc.c
sed '/^X/s///' > _bufproc.c << '/'
X/* --- _bufproc.c --- */
X/* Manages buffers for stdio */
X
X#include <stdlib.h>
X#include <stdio.h>
X#include "stdiolib.h"
X
X/* _bufalloc - allocate a new buffer				*/
X/* Input:  A valid stream with _io_bufsiz appropriately set	*/
X/* Output: Maybe a buffer, maybe not				*/
X
Xvoid _bufalloc(stream)
Xregister FILE *stream;
X{
X  if (stream->_io_bufsiz > 0 &&
X     (stream->_io_buf = (unsigned char *) malloc(stream->_io_bufsiz)) != NULL) {
X	_io_setflag(stream, _IO_MYBUF);
X	stream->_io._io_ptr = stream->_io_buf;
X  } else {
X	stream->_io_bufsiz = 0;
X	stream->_io._io_char = EOF;
X  }
X}
X
X/* _buffree - free an existing buffer if allocated by _bufalloc	*/
X/* Input:  A valid stream					*/
X/* Output: A valid unbuffered stream				*/
X
Xvoid _buffree(stream)
Xregister FILE *stream;
X{
X  if (stream->_io_buf != NULL && _io_testflag(stream, _IO_MYBUF)) {
X	free(stream->_io_buf);
X	stream->_io_buf = NULL;
X	stream->_io_count = stream->_io_bufsiz = 0;
X	stream->_io._io_char = EOF;
X	_io_clearflag(stream, (_IO_LBUF | _IO_MYBUF));
X  }
X}
/
echo x - _cleanup.c
sed '/^X/s///' > _cleanup.c << '/'
X/* --- _cleanup.c --- */
X/* Flushes all buffers at program exit */
X/* Notes:  exit() knows about this through __cleanup	*/
X
X#include <stdio.h>
X#include "stdiolib.h"
X
Xvoid _cleanup()
X{
X  fflush(NULL);
X}
/
echo x - _doprnt.c
sed '/^X/s///' > _doprnt.c << '/'
X/* --- _doprnt.c --- */
X/* Formatted printing workhorse */
X/* Notes:  By default, this source compiles into _doprnt()		*/
X/*	   Floating point support is nominal				*/
X/*	   Cheap and nasty imitations of character type macros		*/
X/*	   Defining the symbol _KERNEL_ results in a routine named	*/
X/*	   printk() with the following differences:			*/
X/*		No floating point support				*/
X/*		An abbreviated version of the macro PUTC		*/
X
X#include <stdarg.h>
X
X#ifndef _KERNEL_
X#include <sys/types.h>
X#include <stdio.h>
X#include <unistd.h>
X#include "stdiolib.h"
X#else
Xextern int putc();
X#endif
X
X/* --- Constants --- */
X#define MAX_CONVERSION	512	/* largest possible conversion */
X
X#define LEFT_JUSTIFY	0x0001	/* conversion flags */
X#define ALWAYS_SIGN	0x0002
X#define PREFIX_SPACE	0x0004
X#define ALTERNATE_FORM	0x0008
X#define ZERO_FILL	0x0010
X#define SHORT		0x0100	/* length modifiers */
X#define LONG		0x0200
X#define LONGDOUBLE	0x0400
X#define SIGNED		0x1000	/* signed integer argument */
X#define UPPER_CASE	0x4000	/* %X, %E, %G */
X
X#define UNSPECIFIED	(-1)	/* for precision */
X
X#define POINTER_BASE	16	/* constant for %p conversion */
X
X/* --- Global state --- */
Xstatic struct {
X#ifndef _KERNEL_
X  FILE *stream;			/* destination file */
X#endif
X  const char *fp;		/* format pointer */
X  va_list ap;			/* argument pointer */
X  int chars_written;		/* number of characters written to the stream */
X} gs;
X
X/* --- Macros --- */
X#define TESTFLAG(x)	(flags & (x))
X#define CLEARFLAG(x)	(flags &= ~(x))
X#define SETFLAG(x)	(flags |= (x))
X#define isdigit(c)	((c) >= '0' && (c) <= '9')
X#define _tolower(c)	((c) - 'A' + 'a')
X
X#ifdef _KERNEL_
X#define EOF		(-1)
X#define PUTC(c, f)	putc(c)
X#else
X/* --- Local unsafe fast version of putc: ignores line buffering;	--- */
X/* --- has no rvalue; returns EOF from including routine on failure	--- */
X#define PUTC(c, f) {			\
X  if (--(f)->_io_count >= 0)		\
X	*(f)->_io._io_ptr++ = c;	\
X  else					\
X	if (_flsbuf(c, f) == EOF)	\
X		return EOF;		\
X  }
X#endif
X
X/* --- Format processors --- */
Xstatic int _parse_format();	/* parse formats */
Xstatic int _iconvert();		/* convert integers */
X#ifndef _KERNEL_
Xstatic int _fconvert();		/* convert floating point */
X#endif
Xstatic int _sconvert();		/* convert strings */
Xstatic int _outcnvrt();		/* writes converted output to the stream */
X
X#ifdef _KERNEL_
Xint printk(format, arg)
X#else
Xint _doprnt(stream, format, arg)
XFILE *stream;
X#endif
Xregister const char *format;
Xva_list arg;
X{
X#ifndef _KERNEL_
X  gs.stream = stream;
X#endif
X  gs.fp = format;
X  gs.ap = arg;
X  gs.chars_written = 0;
X
X  while (*format) {
X	if (*format != '%') {
X		PUTC(*format, stream);
X		format++;
X		gs.chars_written++;
X	} else {
X		gs.fp = ++format;
X		if (_parse_format() == EOF)
X			return EOF;
X		format = gs.fp;
X	}
X  }
X
X#ifndef _KERNEL_
X  if (_io_testflag(stream, _IO_LBUF))
X	_flspbuf(stream);
X#endif
X  return gs.chars_written;
X}
X
Xstatic int _parse_format()
X{
X  register const char *fp = gs.fp;
X  register int c;
X  int width;
X  int precision;
X  int flags;
X  union {
X    unsigned long l;
X    double d;
X    char c;
X    char *s;
X  } arg;
X
X  if (*fp == '%') {
X	PUTC(*fp, gs.stream);
X	gs.fp++;
X	gs.chars_written++;
X	return 0;
X  }
X
X  precision = UNSPECIFIED;
X  flags = 0;
X
X/* --- Extract the flags --- */
X  c = *fp;
X  while (1) {
X	if (c == '-')
X		SETFLAG(LEFT_JUSTIFY);
X	else
X	if (c == '+')
X		SETFLAG(ALWAYS_SIGN);
X	else
X	if (c == ' ')
X		SETFLAG(PREFIX_SPACE);
X	else
X	if (c == '#')
X		SETFLAG(ALTERNATE_FORM);
X	else
X	if (c == '0')
X		SETFLAG(ZERO_FILL);
X	else
X		break;
X	c = *++fp;
X  }
X
X/* --- Extract the width --- */
X  if (c == '*') {
X	width = va_arg(gs.ap, int);
X	++fp;
X  }
X  else {
X	width = 0;
X	while (isdigit(*fp))
X		width = 10 * width + *fp++ - '0';
X  }
X  if (width < 0) {
X	SETFLAG(LEFT_JUSTIFY);
X	width = 0 - width;
X  }
X
X/* --- Extract the precision --- */
X  if (*fp == '.') {
X	if (*++fp == '*') {
X		precision = va_arg(gs.ap, int);
X		++fp;
X	}
X	else {			/* PENDING - this should handle +/- signs */
X		precision = 0;
X		while (isdigit(*fp))
X			precision = 10 * precision + *fp++ - '0';
X	}
X	if (precision < 0)
X		precision = UNSPECIFIED;
X  }
X
X/* --- Extract the length modifiers --- */
X  if ((c = *fp) == 'h') {
X	SETFLAG(SHORT);
X	++fp;
X  } else
X  if (c == 'l') {
X	SETFLAG(LONG);
X	++fp;
X  } else
X  if (c == 'L') {
X	SETFLAG(LONGDOUBLE);
X	++fp;
X  }
X
X/* --- Fetch argument type and save global format pointer --- */
X  c = *fp;
X  gs.fp = ++fp;
X  if (c == 'D' || c == 'O' || c == 'U') {	/* not ANSI */
X	SETFLAG(LONG);
X	c = _tolower(c);
X  }
X
X/* --- Fetch the argument --- */
X  switch (c) {
X  case 'd':
X  case 'i':
X	if (TESTFLAG(SHORT))
X		arg.l = (long) va_arg(gs.ap, short);
X	else
X	if (TESTFLAG(LONG))
X		arg.l = va_arg(gs.ap, long);
X	else
X		arg.l = (long) va_arg(gs.ap, int);
X	break;
X  case 'o':
X  case 'u':
X  case 'X':
X  case 'x':
X	if (TESTFLAG(SHORT))
X		arg.l = (unsigned long) va_arg(gs.ap, unsigned short);
X	else
X	if (TESTFLAG(LONG))
X		arg.l = va_arg(gs.ap, unsigned long);
X	else
X		arg.l = (unsigned long) va_arg(gs.ap, unsigned int);
X	break;
X#ifndef _KERNEL_
X	/* PENDING - This is probably wrong (due to argument widening). */
X  case 'f':
X  case 'E':
X  case 'e':
X  case 'G':
X  case 'g':
X	if (TESTFLAG(LONG))
X		arg.d = va_arg(gs.ap, double);
X#ifdef __STDC__
X	else
X	if (TESTFLAG(LONGDOUBLE))
X		arg.d = (double) va_arg(gs.ap, long double);
X#endif
X	else
X		arg.d = va_arg(gs.ap, float);
X	break;
X#endif
X  case 'c':
X	arg.c = va_arg(gs.ap, int);
X	break;
X  case 's':
X	arg.s = va_arg(gs.ap, char *);
X	break;
X  case 'p':
X	arg.l = (unsigned long) va_arg(gs.ap, void *);
X	break;
X  default:
X	break;
X  }
X
X/* --- Resolve mutually exclusive flags --- */
X  if (TESTFLAG(ALWAYS_SIGN))
X	CLEARFLAG(PREFIX_SPACE);
X  if (TESTFLAG(LEFT_JUSTIFY))
X	CLEARFLAG(ZERO_FILL);
X
X/* --- Produce some output (finally!) --- */
X  switch (c) {
X  case 'd':
X  case 'i':
X	SETFLAG(SIGNED);
X	CLEARFLAG(ALTERNATE_FORM);
X	return _iconvert(arg.l, 10, width, precision, flags);
X  case 'o':
X	return _iconvert(arg.l, 8, width, precision, flags);
X  case 'u':
X	CLEARFLAG(ALTERNATE_FORM);
X	return _iconvert(arg.l, 10, width, precision, flags);
X  case 'X':
X	SETFLAG(UPPER_CASE);
X  case 'x':
X	return _iconvert(arg.l, 16, width, precision, flags);
X#ifndef _KERNEL_
X  case 'f':
X	return _fconvert(arg.d, width, precision, flags);
X  case 'E':
X	SETFLAG(UPPER_CASE);
X  case 'e':
X	return _fconvert(arg.d, width, precision, flags);
X  case 'G':
X	SETFLAG(UPPER_CASE);
X  case 'g':
X	return _fconvert(arg.d, width, precision, flags);
X#endif
X  case 'c':
X	return _outcnvrt(&(arg.c), 1, width, flags);
X  case 's':
X	return _sconvert(arg.s, width, precision, flags);
X  case 'p':
X	SETFLAG(ALTERNATE_FORM);
X	return _iconvert(arg.l, POINTER_BASE, width, precision, flags);
X  case 'n':
X	*va_arg(gs.ap, int *) = gs.chars_written;
X	return 0;
X  default:
X	return EOF;
X  }
X}
X
Xstatic int _iconvert(number, base, width, precision, flags)
Xunsigned long number;
Xint base;
Xint width;
Xint precision;
Xint flags;
X{
X  char buf[MAX_CONVERSION];
X  register char *p = &buf[MAX_CONVERSION - 1];
X  register int digit;
X  int negative = 0;
X
X/* --- Set default precision (and annul zero fill if precision set) --- */
X  if (precision == UNSPECIFIED)
X	precision = 1;
X  else
X	CLEARFLAG(ZERO_FILL);
X
X/* --- Get the sign right --- */
X  if (TESTFLAG(SIGNED))
X	if ((long) number < 0L) {
X		negative = 1;
X		number = (unsigned long) (0L - (long) number);
X	}
X
X/* --- Build the number back to front (at the back of the buffer) --- */
X  while (--precision >= 0 || number != 0) {
X	digit = number % base;
X	if (digit < 10)
X		digit += '0';
X	else
X		digit += (TESTFLAG(UPPER_CASE) ? 'A' : 'a') - 10;
X	*p-- = digit;
X	number /= base;
X  }
X
X/* --- Ensure enough precision --- */
X  while (--precision >= 0)
X	*p-- = '0';
X
X/* --- Zero fill if needed (but leave room for prefix and sign) --- */
X  if (TESTFLAG(ZERO_FILL)) {
X	precision = width - (&buf[MAX_CONVERSION - 1] - p);
X	if (TESTFLAG(ALTERNATE_FORM))
X		if (base == 8 && *(p+1) != '0')
X			precision--;
X		else
X		if (base == 16)
X			precision -= 2;
X	if (TESTFLAG(SIGNED))
X		if (negative || TESTFLAG(ALWAYS_SIGN | PREFIX_SPACE))
X			precision--;
X	while (--precision >= 0)
X		*p-- = '0';
X  }
X
X/* --- Generate alternate forms for %o and %x --- */
X  if (TESTFLAG(ALTERNATE_FORM)) {
X	if (base == 8 && *(p+1) != '0')
X		*p-- = '0';
X	else
X	if (base == 16) {
X		*p-- = TESTFLAG(UPPER_CASE) ? 'X' : 'x';
X		*p-- = '0';
X	}
X  }
X
X/* --- Generate signs --- */
X  if (TESTFLAG(SIGNED)) {
X	if (negative)
X		*p-- = '-';
X	else {
X		if (TESTFLAG(ALWAYS_SIGN))
X			*p-- = '+';
X		else
X		if (TESTFLAG(PREFIX_SPACE))
X			*p-- = ' ';
X	}
X  }
X
X  p++;
X  return _outcnvrt(p, &buf[MAX_CONVERSION] - p, width, flags);
X}
X
X#ifndef _KERNEL_
X
Xstatic int _fconvert(arg, width, precision, flags)	/* PENDING */
Xdouble arg;
Xint width;
Xint precision;
Xint flags;
X{
X/* --- Set default precision --- */
X  if (precision == UNSPECIFIED)
X	precision = 6;
X
X/* --- What do you expect? --- */
X  PUTC(' ', gs.stream);
X  PUTC('*', gs.stream);
X  PUTC('F', gs.stream);
X  PUTC('P', gs.stream);
X  PUTC('*', gs.stream);
X  PUTC(' ', gs.stream);
X  gs.chars_written += 6;
X  return 0;
X}
X
X#endif
X
Xstatic int _sconvert(s, width, precision, flags)
Xchar *s;
Xint width;
Xregister int precision;
Xint flags;
X{
X  register char *p = s;
X
X  if (precision == UNSPECIFIED)
X	precision = MAX_CONVERSION;
X  while (--precision >= 0 && *p)
X	p++;
X  return _outcnvrt(s, p - s, width, flags);
X}
X
Xstatic int _outcnvrt(p, n, width, flags)
Xregister char *p;		/* start of converted field */
Xint n;				/* number of characters in field */
Xint width;
Xint flags;
X{
X#ifndef _KERNEL_
X  register FILE *stream = gs.stream;
X#endif
X  int i;
X
X  if (!TESTFLAG(LEFT_JUSTIFY))			/* pad to right justify */
X	for (i = width - n ; --i >= 0; )
X		PUTC(' ', stream);
X
X  for (i = n; --i >= 0; p++)			/* copy conversion result */
X	PUTC(*p, stream);
X
X  if (TESTFLAG(LEFT_JUSTIFY))			/* pad to left justify */
X	for (i = width - n ; --i >= 0; )
X		PUTC(' ', stream);
X
X  gs.chars_written += (n > width) ? n : width;
X  return 0;
X}
/
echo x - _doscan.c
sed '/^X/s///' > _doscan.c << '/'
X/* --- _doscan.c --- */
X/* Formatted input workhorse */
X/* Notes:  Floating point support is nonexistent			*/
X
X#include <ctype.h>
X#include <limits.h>
X#include <stdarg.h>
X#include <stdio.h>
X#include <string.h>
X#include "stdiolib.h"
X
X/* --- Constants --- */
X#define OK			0	/* return values from input eaters */
X#define INPUT_FAILURE		EOF
X#define MATCHING_FAILURE	1 
X#define UNIMPLEMENTED		2
X
X#define POINTER_BASE		16	/* constants for %p conversion */
X#define POINTER_TYPE		'\0'
X
X#define SIGNED			0	/* constants for _strtol() */
X#define UNSIGNED		1
X
X#define NO_NULL			0	/* constants for _strtostr() */
X#define ADD_NULL		1
X#define NO_COMPARE		0
X#define WHITE_COMPARE		1
X#define SET_COMPARE		2
X#define CHAR_SET_SIZE		128
X
X/* --- Global state --- */
Xstatic struct {
X  int (*next_char)();	/* pointer to input function */
X  union {
X    unsigned char *s;	/* pointer to input string */
X    FILE *f;		/* pointer to input file */
X  } src;
X  int input_char;	/* buffer for next input character */
X  const char *fp;	/* format pointer */
X  va_list ap;		/* argument pointer */
X  int chars_read;	/* number of characters read from the stream (%n) */
X  int items_converted;	/* successful conversions */
X  int items_assigned;	/* successful assignments */
X  int no_assign;	/* if set, conversion is done but not assignment */
X  int width;		/* maximum input field width */
X  char modifier;	/* short/long modifier */
X} gs;
X
Xstatic char valid_char[CHAR_SET_SIZE];
X
X/* --- Macros --- */
X#define BACKUP_INPUT(c)	((gs.input_char = (c)), (gs.chars_read--))
X
X/* --- Input functions --- */
Xstatic int _i_string();
Xstatic int _i_stream();
X
X/* --- Input processors --- */
Xstatic int _eat_white(),	/* ' ' */
X	   _eat_one(),		/* any literal character */
X	   _parse_format(),	/* parse formats */
X	   _strtol(),		/* convert integer formats */
X	   _strtod(),		/* convert floating formats */
X	   _strtostr();		/* convert string formats */
X
X	    
Xint _doscan(is_string, source, format, arg)
Xint is_string;
Xvoid *source;
Xconst char *format;
Xva_list arg;
X{
X  register int c;
X  register int error = OK;
X
X  gs.next_char = (is_string) ? _i_string : _i_stream;
X  gs.src.s = (unsigned char *) source;
X  gs.input_char = EOF;
X  gs.fp = format;
X  gs.ap = arg;
X  gs.items_converted = 0;
X  gs.items_assigned = 0;
X
X  while ((c = (int) *gs.fp++) && (error == OK)) {
X	if (isspace(c))
X		error = _eat_white();
X	else
X	if (c == '%')
X		error = _parse_format();
X	else
X		error = _eat_one(c);
X  }
X  if (gs.input_char != EOF && !is_string)
X	ungetc(gs.input_char, gs.src.f);
X  return (error == INPUT_FAILURE && gs.items_converted == 0)
X	? EOF : gs.items_assigned;
X}
X
Xstatic int _i_stream()
X{
X  int rc;
X
X  gs.chars_read++;
X  if ((rc = gs.input_char) != EOF) {
X	gs.input_char = EOF;
X	return rc;
X  }
X  return getc(gs.src.f);
X}
X
Xstatic int _i_string()
X{
X  int rc;
X  gs.chars_read++;
X  if ((rc = gs.input_char) != EOF) {
X	gs.input_char = EOF;
X	return rc;
X  }
X  if (*gs.src.s == '\0')
X	return EOF;
X  return (int) *gs.src.s++;
X}
X
Xstatic int _parse_format()
X{
X  register int c;
X
X  if ((c = *gs.fp++) == '%')
X	return _eat_one(c);
X
X  gs.no_assign = 0;		/* default: assign converted value */
X  gs.width = INT_MAX;		/* default: enormous maximum width */
X  gs.modifier = '\0';		/* default: no long/short modifier */
X
X  if (c == '*') {
X	gs.no_assign = 1;
X	c = *gs.fp++;
X  }
X  if (isdigit(c)) {
X	gs.width = 0;
X	while (isdigit(c)) {	/* PENDING - this should handle +/- signs */
X		gs.width = 10 * gs.width + c - '0';
X		c = *gs.fp++;
X	}
X  }
X  if (c == 'h' || c == 'l' || c == 'L') {
X	gs.modifier = c;
X	c = *gs.fp++;
X  }
X  if (c == 'D' || c == 'O' || c == 'U') {	/* not ANSI */
X	gs.modifier = 'l';
X	c = _tolower(c);
X  }
X  switch (c) {
X  case 'd':
X	return _strtol(10, SIGNED);
X  case 'i':
X	return _strtol(0, SIGNED);
X  case 'o':
X	return _strtol(8, UNSIGNED);
X  case 'u':
X	return _strtol(10, UNSIGNED);
X  case 'x':
X  case 'X':
X	return _strtol(16, UNSIGNED);
X  case 'f':
X  case 'e':
X  case 'E':
X  case 'g':
X  case 'G':
X	return _strtod();
X  case 's':
X	return _strtostr(WHITE_COMPARE, ADD_NULL);
X  case '[':
X	return _strtostr(SET_COMPARE, ADD_NULL);
X  case 'c':
X	if (gs.width == INT_MAX)
X		gs.width = 1;
X	return _strtostr(NO_COMPARE, NO_NULL);
X  case 'p':
X	return _strtol(POINTER_BASE, UNSIGNED);
X  case 'n':
X	if (!gs.no_assign)
X		*va_arg(gs.ap, int *) = gs.chars_read;
X	return OK;
X  default:
X	return MATCHING_FAILURE;
X  }
X}
X
X/* --- Input processors --- */
Xstatic int _eat_white()
X{
X  register int c;
X
X  while ((c = (*gs.next_char)()) != EOF && isspace(c)) ;
X  BACKUP_INPUT(c);
X  return (c == EOF) ? INPUT_FAILURE : OK;
X}
X
Xstatic int _eat_one(c)
Xint c;
X{
X  register int i;
X
X  if ((i = (*gs.next_char)()) == EOF)
X	return INPUT_FAILURE;
X  return (i == c) ? OK : MATCHING_FAILURE;
X}
X
Xstatic int _strtol(base, is_unsigned)
Xint base;
Xint is_unsigned;
X{
X  register int c;
X  long result = 0L;
X  int negative = 0;
X  int original_width = gs.width;
X  int digit;
X
X  if (_eat_white() == INPUT_FAILURE)
X	return INPUT_FAILURE;
X
X/* --- Handle signs --- */
X  c = (*gs.next_char)();
X  if (c == '+' || c == '-') {
X	negative = (c == '-');
X	gs.width--;
X	c = (*gs.next_char)();
X  }
X
X/* --- Determine base if unknown --- */
X  if (base == 0) {
X	base = 10;
X	if (c == '0') {
X		base = 8;
X		gs.width--;
X		c = (*gs.next_char)();
X		if (c == 'x' || c == 'X') {
X			base = 16;
X			gs.width--;
X			c = (*gs.next_char)();
X		}
X	}
X  }
X
X/* --- Discard 0x or 0X prefix if hexadecimal --- */
X  else
X  if (base == 16 && c == '0') {
X	gs.width--;
X	c = (*gs.next_char)();
X	if (c == 'x' || c == 'X') {
X		gs.width--;
X		c = (*gs.next_char)();
X	}
X  }
X
X/* --- Convert the number --- */
X  while (gs.width-- > 0 && c != EOF) {
X	if (isdigit(c))
X		digit = c - '0';
X	else
X		digit = c - (isupper(c) ? 'A' : 'a') + 10;
X	if (digit < 0 || digit >= base)
X		break;
X	result = base * result + digit;
X	c = (*gs.next_char)();
X  }
X  gs.width++;
X  BACKUP_INPUT(c);
X  gs.items_converted++;
X
X/* --- Sign the result --- */
X  if (negative)
X	result = 0L - result;
X
X/* --- Stash the result --- */
X  if (gs.width == original_width)
X	return (c == EOF) ? INPUT_FAILURE : MATCHING_FAILURE;
X  if (!gs.no_assign) {
X    if (is_unsigned) {
X	if (gs.modifier == 'l')
X		*va_arg(gs.ap, unsigned long *)  = (unsigned long)  result;
X	else
X	if (gs.modifier == 'h')
X		*va_arg(gs.ap, unsigned short *) = (unsigned short) result;
X	else
X		*va_arg(gs.ap, unsigned int *)   = (unsigned int)   result;
X    } else {
X	if (gs.modifier == 'l')
X		*va_arg(gs.ap, long *)  = (long)  result;
X	else
X	if (gs.modifier == 'h')
X		*va_arg(gs.ap, short *) = (short) result;
X	else
X		*va_arg(gs.ap, int *)   = (int)   result;
X    }
X    gs.items_assigned++;
X  }
X  return OK;
X}
X
Xstatic int _strtod()				/* PENDING */
X{
X  return UNIMPLEMENTED;
X}
X
Xstatic int _strtostr(method, string_end)
Xint method;
Xint string_end;
X{
X  int negated;
X  register int c;
X  register unsigned char *target;
X  int original_width = gs.width;
X
X/* --- Set up for comparisons --- */
X  if (method == WHITE_COMPARE) {
X	if (_eat_white() == INPUT_FAILURE)
X		return INPUT_FAILURE;
X  } else
X  if (method == SET_COMPARE) {
X	negated = 0;
X	if (*gs.fp == '^') {
X		negated = 1;
X		gs.fp++;
X	}
X	memset(valid_char, negated, CHAR_SET_SIZE);
X	negated = !negated;
X	c = EOF;
X	do {
X		register int next = gs.fp[1];
X
X		if (c != EOF && *gs.fp == '-' && next != ']') {
X			for (c++ ; c <= next; c++)
X				valid_char[c] = negated;
X			gs.fp++;
X			c = EOF;
X		}
X		else
X			valid_char[c = *gs.fp] = negated;
X	} while (*++gs.fp != ']');
X	gs.fp++;
X  }
X
X/* --- Copy the string --- */
X  if (!gs.no_assign)
X	target = va_arg(gs.ap, unsigned char *);
X  c = (*gs.next_char)();
X  while (gs.width-- > 0 && c != EOF) {
X	if (method == WHITE_COMPARE && isspace(c))
X		break;
X	else
X	if (method == SET_COMPARE && !valid_char[c])
X		break;
X	if (!gs.no_assign)
X		*target++ = c;
X	c = (*gs.next_char)();
X  }
X  gs.width++;
X  BACKUP_INPUT(c);
X  gs.items_converted++;
X
X/* --- Finish up --- */
X  if (!gs.no_assign) {
X	if (string_end == ADD_NULL)
X		*target = '\0';
X	gs.items_assigned++;
X  }
X  if (gs.width == original_width)
X	return (c == EOF) ? INPUT_FAILURE : MATCHING_FAILURE;
X  return OK;
X}
/
echo x - _filbuf.c
sed '/^X/s///' > _filbuf.c << '/'
X/* --- _filbuf.c --- */
X/* Read from the file associated with a stream */
X/* Notes:  Will flush stdout if reading stdin and both are tty's	*/
X
X#include <sys/types.h>
X#include <stdio.h>
X#include <unistd.h>
X#include "stdiolib.h"
X
Xint _filbuf(stream)
Xregister FILE *stream;
X{
X  int c;
X
X/* --- Virgin stream: set things up --- */
X  if (stream->_io_count < _IO_NEVER)
X	_i_init(stream);
X
X/* --- Read a bufferful --- */
X  if (stream->_io_bufsiz == 0) {	/* unbuffered */
X	if (stream->_io._io_char != EOF) {	/* check for ungetc()ed char */
X		c = stream->_io._io_char;
X		stream->_io._io_char = EOF;
X		return c;
X	}
X	stream->_io_count = read(stream->_io_fd, (char *) &c, 1);
X  } else {
X	stream->_io_count =
X		read(stream->_io_fd, (char *) stream->_io_buf, stream->_io_bufsiz);
X	stream->_io._io_ptr = stream->_io_buf;
X  }
X  if (stream->_io_count < 0) {
X	_io_setflag(stream, _IO_ERR);
X	return EOF;
X  }
X  if (stream->_io_count == 0) {
X	_io_setflag(stream, _IO_EOF);
X	if (_io_testflag(stream, _IO_UPDATE))
X		_io_clearflag(stream, (_IO_READ | _IO_WRITE));
X	return EOF;
X  }
X  stream->_io_count--;
X  return (stream->_io_bufsiz == 0)
X	? c
X	: *stream->_io._io_ptr++;
X}
/
echo x - _flsbuf.c
sed '/^X/s///' > _flsbuf.c << '/'
X/* --- _flsbuf.c --- */
X/* Flushes full stream buffers */
X/* Notes:  #define _V7 gives support for append mode when kernel doesn't*/
X
X#include <sys/types.h>
X#include <stdio.h>
X#include <unistd.h>
X#include "stdiolib.h"
X
Xint _flsbuf(c, stream)		/* stream must be valid, writable */
Xint c;
Xregister FILE *stream;
X{
X/* --- Virgin stream: set things up --- */
X  if (++stream->_io_count == _IO_NEVER)
X	_o_init(stream);
X
X#ifdef _V7
X/* --- Append kludge --- */
X  if (_io_testflag(stream, _IO_APPEND) && _io_testflag(stream, _IO_NEEDSEEK)) {
X	lseek(stream->_io_fd, 0L, SEEK_END);
X	_io_clearflag(stream, _IO_NEEDSEEK);
X  }
X#endif
X
X/* --- Unbuffered stream: write one character --- */
X  if (stream->_io_bufsiz == 0) {
X	stream->_io_count = 0;
X	if (write(stream->_io_fd, (char *) &c, 1) != 1) {
X		_io_setflag(stream, _IO_ERR);
X		return EOF;
X	}
X	return c;
X  }
X
X/* --- Buffered stream: write out a full buffer --- */
X  if (stream->_io_count == 0) {
X	if (write(stream->_io_fd, (char *) stream->_io_buf, stream->_io_bufsiz)
X							!= stream->_io_bufsiz) {
X		_io_setflag(stream, _IO_ERR);
X		return EOF;
X	}
X	stream->_io._io_ptr = stream->_io_buf;
X	stream->_io_count = stream->_io_bufsiz;
X  }
X
X/* --- Buffered stream: start filling new buffer --- */
X  --stream->_io_count;
X  *stream->_io._io_ptr++ = c;
X
X/* --- Line buffered stream: flush a partial buffer --- */
X  if (_io_testflag(stream, _IO_LBUF) && c == '\n' && _flspbuf(stream) != 0)
X	return EOF;
X
X  return c;
X}
/
echo x - _flspbuf.c
sed '/^X/s///' > _flspbuf.c << '/'
X/* --- _flspbuf.c --- */
X/* Flushes partially full stream buffers */
X/* Notes:  #define _V7 gives support for append mode when kernel doesn't*/
X
X#include <sys/types.h>
X#include <stdio.h>
X#include <unistd.h>
X#include "stdiolib.h"
X
Xint _flspbuf(stream)
Xregister FILE *stream;
X{
X  register int bytes = stream->_io_bufsiz - stream->_io_count;
X
X#ifdef _V7
X  if (_io_testflag(stream, _IO_APPEND) && _io_testflag(stream, _IO_NEEDSEEK)) {
X	lseek(stream->_io_fd, 0L, SEEK_END);
X	_io_clearflag(stream, _IO_NEEDSEEK);
X  }
X#endif
X
X  if (write(stream->_io_fd, stream->_io_buf, bytes) != bytes) {
X	_io_setflag(stream, _IO_ERR);
X	return EOF;
X  }
X  stream->_io._io_ptr = stream->_io_buf;
X  stream->_io_count = stream->_io_bufsiz;
X  return 0;
X}
/
echo x - _iobdata.c
sed '/^X/s///' > _iobdata.c << '/'
X/* --- _iobdata.c --- */
X/* Data structures for stdio */
X
X#include <stdio.h>
X#include "stdiolib.h"
X
X#define STDIN	{0, _IO_READ  | _IO_LBUF | _IO_TTY, _IO_NEVER, BUFSIZ, NULL}
X#define STDOUT	{1, _IO_WRITE | _IO_LBUF | _IO_TTY, _IO_NEVER, BUFSIZ, NULL}
X#define STDERR	{2, _IO_WRITE,                      _IO_NEVER, 0,      NULL}
X
XFILE _iob[FOPEN_MAX] = {STDIN,	STDOUT,	STDERR	};
Xchar _iov[FOPEN_MAX] = {1,	1,	1	};
X
XFILE *_io_f;		/* for fgetc()/fputc() macros */
Xint _io_c;
X
Xint (*__tmprm)();	/* pointer for cleaning up tmpfile()'s trash */
/
echo x - _iobproc.c
sed '/^X/s///' > _iobproc.c << '/'
X/* --- _iobproc.c --- */
X/* Manages allocation of FILEs */
X/* Notes:  Includes _ioballoc(), _iobfree(), and _iobindex()	*/
X
X#include <stdio.h>
X#include "stdiolib.h"
X
X#define INVALID (-1)
X
Xextern char _iov[];
X
X/* _ioballoc - allocates an i/o block (FILE)	*/
X/* Input:  none					*/
X/* Output: Pointer to a currently free FILE	*/
X
XFILE *_ioballoc()
X{
X  register int i;
X
X  for (i = 0; i < FOPEN_MAX; i++)
X	if (_iov[i] == 0) {
X		_iov[i] = 1;
X		return &_iob[i];
X	}
X  return NULL;
X}
X
X/* _iobfree - frees an i/o block (FILE)	*/
X/* Input:  A stream			*/
X/* Output: None	(but FILE is freed)	*/
X
Xvoid _iobfree(stream)
XFILE *stream;
X{
X  register int i;
X
X  if ((i = _iobindex(stream)) != INVALID)
X	_iov[i] = 0;
X}
X
X/* _iobindex - finds the index of a given stream	*/
X/* Input:  A stream					*/
X/* Output: Index of the stream if valid, -1 otherwise	*/
X
Xint _iobindex(stream)
Xregister FILE *stream;
X{
X  register FILE *f;
X  register int i;
X
X  for (i = 0, f = _iob; i < FOPEN_MAX; i++, f++)
X	if (stream == f)
X		return _iov[i] ? i : INVALID;
X  return INVALID;
X}
/
echo x - _ioinit.c
sed '/^X/s///' > _ioinit.c << '/'
X/* --- _ioinit.c --- */
X/* Checks for a whole bunch of initial conditions on i/o */
X/* Notes:  Includes _i_init() and _o_init() */
X
X#include <sys/types.h>
X#include <stdio.h>
X#include <unistd.h>
X#include "stdiolib.h"
X
Xvoid _i_init(stream)
Xregister FILE *stream;
X{
X/* --- Allocate a buffer if necessary --- */
X  if (stream->_io_buf == NULL && stream->_io_bufsiz != 0)
X	_bufalloc(stream);
X  stream->_io_count = 0;
X  _io_setflag(stream, _IO_READ);
X
X/* --- Line buffering: check once and turn it off if stream is not a tty --- */
X  if (_io_testflag(stream, _IO_TTY)) {
X	if (_io_testflag(stream, _IO_LBUF) && !isatty(stream->_io_fd))
X		_io_clearflag(stream, _IO_LBUF);
X	_io_clearflag(stream, _IO_TTY);
X  }
X
X/* --- Flush stdout (if _IOLBF) when reading from _IONBF/_IOLBF stream --- */
X  if (stream->_io_bufsiz == 0 || _io_testflag(stream, _IO_LBUF))
X	if (_io_testflag(stdout, _IO_LBUF))
X		fflush(stdout);
X}
X
Xvoid _o_init(stream)
Xregister FILE *stream;
X{
X/* --- Register _cleanup() so that exit() can find it --- */
X  if (__cleanup == NULL)
X	__cleanup = _cleanup;
X
X/* --- Allocate a buffer if necessary --- */
X  if (stream->_io_buf == NULL && stream->_io_bufsiz != 0)
X	_bufalloc(stream);
X  stream->_io_count = stream->_io_bufsiz;
X  _io_setflag(stream, _IO_WRITE);
X
X/* --- Line buffering: check once and turn it off if stream is not a tty --- */
X  if (_io_testflag(stream, _IO_TTY)) {
X	if (_io_testflag(stream, _IO_LBUF) && !isatty(stream->_io_fd))
X		_io_clearflag(stream, _IO_LBUF);
X	_io_clearflag(stream, _IO_TTY);
X  }
X}
/
echo x - _valmode.c
sed '/^X/s///' > _valmode.c << '/'
X/* --- _valmode.c --- */
X/* Validates mode for stream opening functions	*/
X
X/* Input:  mode - a mode string for fopen()		*/
X/* Output: EOF for a bad string				*/
X/*	   0 for a good string without a '+'		*/
X/*	   _IO_UPDATE for a good string with a '+'	*/
X
X#include <stdio.h>
X#include "stdiolib.h"
X
Xint _valmode(mode)
Xregister const char *mode;
X{
X  register int rc = 0;
X
X/* --- Check basic mode --- */
X  if (*mode != 'r' && *mode != 'w' && *mode != 'a')
X	return EOF;
X  if (*++mode == '\0')
X	return rc;
X
X/* --- Check second character of mode string --- */
X  if (*mode == '+')
X	rc = _IO_UPDATE;
X  else
X  if (*mode == 'b')			/* ANSI mandated - of no use here */
X	;
X  else
X	return EOF;
X  if (*++mode == '\0')
X	return rc;
X
X/* --- Check third character of mode string --- */
X  if (*mode == '+' && rc != _IO_UPDATE)
X	rc = _IO_UPDATE;
X  else
X  if (*mode == 'b' && rc == _IO_UPDATE)
X	;
X  else
X	return EOF;
X  if (*++mode == '\0')
X	return rc;
X
X/* --- Mode string too long --- */
X  return EOF;
X}
/
echo x - atexit.c
sed '/^X/s///' > atexit.c << '/'
X/* Copyright 1988 Frank Wortner
X**	You may reproduce and use this software as long as you
X**	do not delete this notice from the source code.
X*/
X
X#define MAXFN 33	/* Maximum number of functions registerable
X			   (includes 1 for __cleanup)			*/
X
Xtypedef void (*PFN)();	/* Pointer to FuNction */
X
Xextern PFN __cleanup;	/* imported from exit.c */
X
Xstatic PFN fn[MAXFN];	/* addresses of functions stored here */
Xstatic int nfn = -1;	/* number of functions registered less one */
X
Xstatic void checkcleanup(), run_atexit();
X
Xint atexit(fun)
XPFN fun;
X{
X	if (nfn == -1)			/* Do we need to check for stdio? */
X		checkcleanup();
X	if (nfn >= MAXFN)		/* Run out of room yet? */
X		return (-1);
X	fn[++nfn] = fun;		/* Save the address of the subr. */
X	return (0);
X}
X
X/* Check to see if stdio is used.  If yes register stdio's cleanup routine
X** with the atexit() system and then force stdio to call run_atexit().
X*/
Xstatic void checkcleanup()
X{
X	if (__cleanup)			/* stdio used ? */
X		fn[++nfn] = __cleanup;
X	__cleanup = run_atexit;
X}
X
X/* Run the requested subroutines */
Xstatic void run_atexit()
X{
X	while (nfn >= 0) {
X		(*fn[nfn--])();
X	}
X}
/
echo x - exit.c
sed '/^X/s///' > exit.c << '/'
X#include <stddef.h>
X#include "lib.h"
X
XPUBLIC void (*__cleanup)() = NULL;
X
XPUBLIC int exit(status)
Xint status;
X{
X  if (__cleanup != NULL)
X	(*__cleanup)();
X  return callm1(MM, EXIT, status, 0, 0, NIL_PTR, NIL_PTR, NIL_PTR);
X}
X
XPUBLIC int _exit(status)
Xint status;
X{
X  return callm1(MM, EXIT, status, 0, 0, NIL_PTR, NIL_PTR, NIL_PTR);
X}
/
echo x - fclose.c
sed '/^X/s///' > fclose.c << '/'
X/* --- fclose.c --- */
X/* Closes a stream and its associated file */
X
X#include <sys/types.h>
X#include <stdio.h>
X#include <unistd.h>
X#include "stdiolib.h"
X#undef fclose
X
X#define _IO_ERRVAL EOF
X
Xextern int (*__tmprm)();
X
Xint fclose(stream)
Xregister FILE *stream;
X{
X  _io_assert(_io_valid(stream));
X
X  if (fflush(stream))
X	return _IO_ERRVAL;
X  _buffree(stream);
X  if (close(stream->_io_fd))
X	return _IO_ERRVAL;
X  if (_io_testflag(stream, _IO_TEMP))
X	if (__tmprm) (*__tmprm)(_iobindex(stream));
X  _iobfree(stream);
X  return 0;
X}
/
echo x - fdopen.c
sed '/^X/s///' > fdopen.c << '/'
X/* --- fdopen.c --- */
X/* Associates a stream with an already open file */
X/* Notes:  Open mode of file must agree with open mode specified	*/
X/*	   #define _V7 gives support for append mode when kernel doesn't*/
X/*	   POSIX function						*/
X
X#include <sys/types.h>
X#include <stdio.h>
X#include <unistd.h>
X#include "stdiolib.h"
X#undef fdopen
X
X#define _IO_ERRVAL NULL
X
X
XFILE *fdopen(fd, mode)
Xint fd;
Xconst char *mode;
X{
X  int flags;
X  register FILE *stream;
X
X  _io_assert(fd >= 0);
X
X  if ((flags = _valmode(mode)) < 0)
X	return _IO_ERRVAL;
X  if ((stream = _ioballoc()) == NULL)
X	return _IO_ERRVAL;
X
X  switch (*mode) {
X	case 'r':
X		flags |= _IO_READ;
X		break;
X	case 'w':
X		flags |= _IO_WRITE;
X		break;
X	case 'a':
X#ifdef _V7
X		flags |= _IO_WRITE | _IO_APPEND;
X		lseek(fd, 0L, SEEK_END);
X#else
X		flags |= _IO_WRITE;
X#endif
X		break;
X	default:
X		_iobfree(stream);
X		return _IO_ERRVAL;
X  }
X
X  if (isatty(fd))
X	flags |= _IO_LBUF;
X  stream->_io_fd = fd;
X  stream->_io_flags = flags;
X  stream->_io_count = _IO_NEVER;
X  stream->_io_bufsiz = BUFSIZ;
X  return stream;
X}
/
echo x - fflush.c
sed '/^X/s///' > fflush.c << '/'
X/* --- fflush.c --- */
X/* Flushes a stream's buffer */
X/* Notes:  Given a NULL pointer as a stream, fflush() flushes all streams. */
X/*	   Flushing a readable stream discards the buffer contents	   */
X/*		and lseek()'s the underlying file to meet expectations.    */
X
X#include <sys/types.h>
X#include <stdio.h>
X#include <unistd.h>
X#include "stdiolib.h"
X#undef fflush
X
X#define _IO_ERRVAL EOF
X
Xextern char _iov[];
Xstatic int _fflush	_PROTO((FILE *stream));
X
Xint fflush(stream)
Xregister FILE *stream;
X{
X  register int i;
X  register int rc;
X
X  if (stream == NULL) {
X	rc = 0;
X	for (i = 0, stream = _iob; i < FOPEN_MAX; i++, stream++) {
X		if (_iov[i])
X			rc |= _fflush(stream);
X	}
X	return rc;
X  } else {
X	_io_assert(_io_valid(stream));
X	return _fflush(stream);
X  }
X}
X
Xstatic int _fflush(stream)
Xregister FILE *stream;
X{
X  register int rc = 0;
X
X  if (stream->_io_count == _IO_NEVER)
X	return rc;
X  if (stream->_io_bufsiz != 0) {
X	if (_io_testflag(stream, _IO_WRITE))
X		rc = _flspbuf(stream);
X	else
X	if (_io_testflag(stream, _IO_READ) && !feof(stream))
X		if (lseek(stream->_io_fd, 0L - stream->_io_count, SEEK_CUR) < 0L)
X			rc = EOF;
X  }
X  stream->_io_count = _IO_NEVER;
X  if (stream->_io_bufsiz == 0)
X	stream->_io._io_char = EOF;
X  else
X	stream->_io._io_ptr = stream->_io_buf;
X  if (_io_testflag(stream, _IO_UPDATE))
X	_io_clearflag(stream, (_IO_READ | _IO_WRITE));
X  return rc;
X}
/
echo x - fgetc.c
sed '/^X/s///' > fgetc.c << '/'
X/* --- fgetc.c --- */
X/* Retrieves the next character from a stream */
X/* Notes:  Includes getc() and getchar(), backstops for macros in <stdio.h> */
X
X#include <stdio.h>
X#include "stdiolib.h"
X#undef fgetc
X#undef getc
X#undef getchar
X
X#define _IO_ERRVAL EOF
X
Xint fgetc(stream)
Xregister FILE *stream;
X{
X  _io_assert(_io_valid(stream));
X  _io_assert(!_io_testflag(stream, _IO_WRITE));
X  _io_assert(!_io_testflag(stream, (_IO_EOF | _IO_ERR)));
X
X  return (--stream->_io_count >= 0) ?
X	*stream->_io._io_ptr++ : _filbuf(stream);
X}
X
Xint getc(stream)
XFILE *stream;
X{
X  return fgetc(stream);
X}
X
Xint getchar()
X{
X  return fgetc(stdin);
X}
/
echo x - fgets.c
sed '/^X/s///' > fgets.c << '/'
X/* --- fgets.c --- */
X/* Reads limited number of characters from a stream, up to a newline */
X/* Notes:  Returns EOF only if no characters read before end of file	*/
X
X#include <stdio.h>
X#include "stdiolib.h"
X#undef fgets
X
X#define _IO_ERRVAL NULL
X
Xchar *fgets(s, n, stream)
Xchar *s;
Xregister int n;
XFILE *stream;
X{
X  register int c;
X  register char *p = s;
X
X  _io_assert(s);
X  _io_assert(n > 0);
X  _io_assert(_io_valid(stream));
X  _io_assert(!_io_testflag(stream, _IO_WRITE));
X  _io_assert(!_io_testflag(stream, (_IO_EOF | _IO_ERR)));
X
X  while (--n > 0 && (c = getc(stream)) != EOF) {
X	*p++ = c;
X	if (c == '\n')
X		break;
X  }
X  *p = '\0';
X  return (p == s && c == EOF) ? NULL : s;
X}
/
echo x - fopen.c
sed '/^X/s///' > fopen.c << '/'
X/* --- fopen.c --- */
X/* Opens a file and associates a stream with it */
X/* Notes:  #define _V7 gives support for append mode when kernel doesn't*/
X
X#include <sys/types.h>
X#include <fcntl.h>
X#include <stdio.h>
X#include <unistd.h>
X#include "stdiolib.h"
X#undef fopen
X
X#define _IO_ERRVAL NULL
X#define PMODE	0666
X
XFILE *fopen(filename, mode)
Xconst char *filename;
Xconst char *mode;
X{
X  int fd;
X  int flags;
X  register FILE *stream;
X
X  _io_assert(filename);
X  _io_assert(mode);
X
X  if ((flags = _valmode(mode)) < 0)
X	return _IO_ERRVAL;
X  if ((stream = _ioballoc()) == NULL)
X	return _IO_ERRVAL;
X
X  switch (*mode) {
X	case 'r':
X		fd = open(filename, flags ? O_RDWR : O_RDONLY);
X		flags |= _IO_READ;
X		break;
X	case 'w':
X#ifdef _V7
X		if ((fd = creat(filename, PMODE)) >= 0 && flags) {
X			close(fd);
X			fd = open(filename, O_RDWR);
X		}
X#else
X		fd = open(filename, O_CREAT | O_TRUNC | (flags ? O_RDWR : O_WRONLY), PMODE);
X#endif
X		flags |= _IO_WRITE;
X		break;
X	case 'a':
X#ifdef _V7
X		if ((fd = open(filename, flags ? O_RDWR : O_WRONLY)) >= 0) {
X			lseek(fd, 0L, SEEK_END);
X		}
X		else
X		if ((fd = creat(filename, PMODE)) >= 0 && flags) {
X			close(fd);
X			fd = open(filename, O_RDWR);
X		}
X		flags |= (_IO_WRITE | _IO_APPEND);
X#else
X		fd = open(filename, O_CREAT | O_APPEND | (flags ? O_RDWR : O_WRONLY), PMODE);
X		flags |= _IO_WRITE;
X#endif
X		break;
X	default:
X		fd = -1;
X  }
X  if (fd < 0) {
X	_iobfree(stream);
X	return _IO_ERRVAL;
X  }
X
X  if (isatty(fd))
X	flags |= _IO_LBUF;
X  stream->_io_fd = fd;
X  stream->_io_flags = flags;
X  stream->_io_count = _IO_NEVER;
X  stream->_io_bufsiz = BUFSIZ;
X  return stream;
X}
/
echo x - fputc.c
sed '/^X/s///' > fputc.c << '/'
X/* --- fputc.c --- */
X/* Writes a single character onto a stream */
X/* Notes:  Includes putc() and putchar(), macro backstops for <stdio.h>	*/
X
X#include <stdio.h>
X#include "stdiolib.h"
X#undef fputc
X#undef putc
X#undef putchar
X
X#define _IO_ERRVAL EOF
X
X
Xint fputc(c, stream)
Xregister int c;
Xregister FILE *stream;
X{
X  _io_assert(_io_valid(stream));
X  _io_assert(!_io_testflag(stream, _IO_READ));
X  _io_assert(!_io_testflag(stream, (_IO_EOF | _IO_ERR)));
X
X#ifndef NDEBUG
X  if (_io_testflag(stream, _IO_STRING))
X	return (int) (*stream->_io._io_ptr++ = c);
X#endif
X
X  return ((--stream->_io_count < 0) ||
X	  (_io_testflag(stream, _IO_LBUF) && c == '\n'))
X	? _flsbuf(c, stream)
X	: (int) (*stream->_io._io_ptr++ = c);
X}
X
Xint putc(c, stream)
Xint c;
Xregister FILE *stream;
X{
X  return fputc(c, stream);
X}
X
Xint putchar(c)
Xint c;
X{
X  return fputc(c, stdout);
X}
/
echo x - fputs.c
sed '/^X/s///' > fputs.c << '/'
X/* --- fputs.c --- */
X/* Writes a string to a stream */
X/* Notes:  Includes puts(), which backstops a macro in <stdio.h>	*/
X
X#include <stdio.h>
X#include "stdiolib.h"
X#undef fputs
X#undef puts
X
X#define _IO_ERRVAL EOF
X
X
Xint fputs(s, stream)
Xregister const char *s;
Xregister FILE *stream;
X{
X  _io_assert(s);
X  _io_assert(_io_valid(stream));
X  _io_assert(!_io_testflag(stream, _IO_READ));
X  _io_assert(!_io_testflag(stream, _IO_ERR));
X
X  while (*s) {
X	if (putc(*s, stream) == EOF)
X		return EOF;
X	s++;
X  }
X  return 0;
X}
X
Xint puts(s)
Xconst char *s;
X{
X  return (fputs(s, stdout) >= 0) ? ((putchar('\n') == '\n') ? 0 : EOF) : EOF;
X}
X
/
echo x - fread.c
sed '/^X/s///' > fread.c << '/'
X/* --- fread.c --- */
X/* Reads directly from a stream into a buffer */
X/* Notes:  Attempts to buffer requests but reads directly if impossible	*/
X
X#include <sys/types.h>
X#include <limits.h>
X#include <stdio.h>
X#include <string.h>
X#include <unistd.h>
X#include "stdiolib.h"
X#undef fread
X
X#define _IO_ERRVAL 0
X
X/* --- The following value determines whether fread() requests go	--- */
X/* --- through the buffer or are done directly.  As set, the limit	--- */
X/* --- means that small requests (less than half the stream's buffer	--- */
X/* --- size) will use buffering; larger requests are done directly.	--- */
X/* --- Empirical testing shows this is reasonable; more should be done.	--- */
X#define BUFFER_LIMIT	(stream->_io_bufsiz >> 1)
X
X#define FROM_IO(bytes) {			\
X	memcpy(p, stream->_io._io_ptr, bytes);	\
X	p += bytes;				\
X	stream->_io._io_ptr += bytes;		\
X	stream->_io_count -= bytes;		\
X	}
X#define FROM_FS(bytes)	read(stream->_io_fd, (char *) p, bytes)
X
Xsize_t fread(ptr, size, nmemb, stream)
Xvoid *ptr;
Xsize_t size;
Xsize_t nmemb;
XFILE *stream;
X{
X  long total_size;
X  long bytes_left;
X  register unsigned char *p = (unsigned char *) ptr;
X  register int bytes;
X  int c;
X  int n;
X
X  _io_assert(p != NULL);
X  _io_assert(_io_valid(stream));
X  _io_assert(!_io_testflag(stream, _IO_WRITE));
X  _io_assert(!_io_testflag(stream, (_IO_EOF | _IO_ERR)));
X
X  if ((total_size = (long) nmemb * (long) size) == 0)
X	return 0;
X
X/* --- Virgin stream: set things up --- */
X  if (stream->_io_count == _IO_NEVER)
X	_i_init(stream);
X
X/* --- Most common case(?): from the buffer --- */
X  if (total_size <= stream->_io_count) {
X	bytes = total_size;
X	FROM_IO(bytes);
X	return nmemb;
X  }
X
X/* --- Empty the buffer --- */
X  bytes_left = total_size;
X  if (stream->_io_count > 0) {
X	bytes_left -= stream->_io_count;
X	FROM_IO(stream->_io_count);
X  }
X
X/* --- Small objects: try filling the stdio buffer ONCE --- */
X  if (bytes_left <= BUFFER_LIMIT) {
X	if ((c = _filbuf(stream)) == EOF)
X		return (total_size - bytes_left) / size;
X	*p++ = c;
X	if ((bytes = --bytes_left) <= stream->_io_count) {
X		FROM_IO(bytes);
X		return nmemb;
X	}
X  }
X
X/* --- Buffering failed: read() directly --- */
X  if (stream->_io_count > 0) {
X	bytes_left -= stream->_io_count;
X	FROM_IO(stream->_io_count);
X  }
X  for ( ; bytes_left > INT_MAX; bytes_left -= n) {
X	if ((n = FROM_FS(INT_MAX)) <= 0) {
X		if (n < 0) {
X			_io_setflag(stream, _IO_ERR);
X		} else {
X			_io_setflag(stream, _IO_EOF);
X			if (_io_testflag(stream, _IO_UPDATE))
X				_io_clearflag(stream, (_IO_READ | _IO_WRITE));
X		}
X		return (total_size - bytes_left) / size;
X	}
X	p += n;
X  }
X  for (bytes = bytes_left; bytes > 0; bytes -= n) {
X	if ((n = FROM_FS(bytes)) <= 0) {
X		if (n < 0) {
X			_io_setflag(stream, _IO_ERR);
X		} else {
X			_io_setflag(stream, _IO_EOF);
X			if (_io_testflag(stream, _IO_UPDATE))
X				_io_clearflag(stream, (_IO_READ | _IO_WRITE));
X		}
X		return (total_size - bytes) / size;
X	}
X	p += n;
X  }
X  return nmemb;
X}
/
echo x - freopen.c
sed '/^X/s///' > freopen.c << '/'
X/* --- freopen.c --- */
X/* Closes the file associated with a stream and then opens a new file */
X/* Notes:  #define _V7 gives support for append mode when kernel doesn't*/
X/*	   Maintains buffer and buffering mode on stream.		*/
X
X#include <sys/types.h>
X#include <fcntl.h>
X#include <stdio.h>
X#include <unistd.h>
X#include "stdiolib.h"
X#undef freopen
X
X#define _IO_ERRVAL ((FILE *) NULL)
X#define PMODE	0666
X
X 
XFILE *freopen(filename, mode, stream)
Xconst char *filename;
Xconst char *mode;
Xregister FILE *stream;
X{
X  int fd;
X  int flags;
X
X  _io_assert(_io_valid(stream));
X
X  if (fflush(stream) || close(stream->_io_fd))
X	return _IO_ERRVAL;
X  if ((flags = _valmode(mode)) < 0)
X	return _IO_ERRVAL;
X
X  switch (*mode) {
X	case 'r':
X		fd = open(filename, flags ? O_RDWR : O_RDONLY);
X		flags |= _IO_READ;
X		break;
X	case 'w':
X#ifdef _V7
X		if ((fd = creat(filename, PMODE)) >= 0 && flags) {
X			close(fd);
X			fd = open(filename, O_RDWR);
X		}
X#else
X		fd = open(filename, O_CREAT | O_TRUNC | (flags ? O_RDWR : O_WRONLY), PMODE);
X#endif
X		flags |= _IO_WRITE;
X		break;
X	case 'a':
X#ifdef _V7
X		if ((fd = open(filename, flags ? O_RDWR : O_WRONLY)) >= 0) {
X			lseek(fd, 0L, SEEK_END);
X		}
X		else
X		if ((fd = creat(filename, PMODE)) >= 0 && flags) {
X			close(fd);
X			fd = open(filename, O_RDWR);
X		}
X		flags |= (_IO_WRITE | _IO_APPEND);
X#else
X		fd = open(filename, O_CREAT | O_APPEND | (flags ? O_RDWR : O_WRONLY), PMODE);
X		flags |= _IO_WRITE;
X#endif
X		break;
X	default:
X		fd = -1;
X  }
X
X  if (fd < 0) {
X	_buffree(stream);
X	_iobfree(stream);
X	return _IO_ERRVAL;
X  }
X
X  if (isatty(fd))
X	flags |= _IO_LBUF;
X  stream->_io_fd = fd;
X  _io_clearflag(stream, ~(_IO_LBUF | _IO_MYBUF));
X  _io_setflag(stream, flags);
X  stream->_io_count = _IO_NEVER;
X  return stream;
X}
/
echo x - fseek.c
sed '/^X/s///' > fseek.c << '/'
X/* --- fseek.c --- */
X/* Sets the position of a stream */
X/* Notes:  Always flushes a stream's buffer				*/
X/*	   Includes fsetpos() and rewind()				*/
X/*	   fsetpos() is a backstop for a macro in <stdio.h>		*/
X/*	   #define _V7 gives support for append mode when kernel doesn't*/
X
X#include <sys/types.h>
X#include <stdio.h>
X#include <unistd.h>
X#include "stdiolib.h"
X#undef fseek
X#undef fsetpos
X#undef rewind
X
X#define _IO_ERRVAL EOF
X
Xint fseek(stream, offset, whence)
Xregister FILE *stream;
Xlong int offset;
Xregister int whence;
X{
X  _io_assert(_io_valid(stream));
X  _io_assert(whence == SEEK_SET || whence == SEEK_CUR || whence == SEEK_END);
X
X  fflush(stream);
X  _io_clearflag(stream, _IO_EOF);
X
X#ifdef _V7
X  if (_io_testflag(stream, _IO_APPEND)) {
X	if (!_io_testflag(stream, _IO_UPDATE))
X		return 0;
X	if (whence != SEEK_END || offset != 0L)
X		_io_setflag(stream, _IO_NEEDSEEK);
X  }
X#endif
X
X  return (lseek(stream->_io_fd, offset, whence) < 0L) ? _IO_ERRVAL : 0;
X}
X
Xint fsetpos(stream, pos)
XFILE *stream;
Xconst fpos_t *pos;
X{
X  return fseek(stream, *pos, SEEK_SET);
X}
X
Xvoid rewind(stream)
XFILE *stream;
X{
X  (void) fseek(stream, 0L, SEEK_SET);
X  clearerr(stream);
X}
/
echo x - ftell.c
sed '/^X/s///' > ftell.c << '/'
X/* --- ftell.c --- */
X/* Returns the position of a stream */
X/* Notes:  Includes fgetpos(), which backstops a macro in <stdio.h>	*/
X
X#include <errno.h>
X#include <sys/types.h>
X#include <stdio.h>
X#include <unistd.h>
X#include "stdiolib.h"
X#undef ftell
X#undef fgetpos
X
X#define _IO_ERRVAL -1L
X
X
Xlong ftell(stream)
Xregister FILE *stream;
X{
X  extern int errno;
X  int adjustment;
X  long position;
X  long lseek();
X
X  errno = EBADF;
X  if (!_io_valid(stream))
X	return _IO_ERRVAL;
X  errno = 0;
X
X  if (stream->_io_count == _IO_NEVER)
X	adjustment = 0;
X  else
X  if (_io_testflag(stream, _IO_READ))
X	adjustment = -stream->_io_count;
X  else
X  if (_io_testflag(stream, _IO_WRITE))
X	adjustment = stream->_io_bufsiz - stream->_io_count;
X
X  return ((position = lseek(stream->_io_fd, 0L, SEEK_CUR)) >= 0L)
X	? position + (long) adjustment
X	: _IO_ERRVAL;
X}
X
Xint fgetpos(stream, position)
XFILE *stream;
Xfpos_t *position;
X{
X  return (*position = (fpos_t) ftell(stream)) >= 0L ? 0 : EOF;
X}
/
echo x - fwrite.c
sed '/^X/s///' > fwrite.c << '/'
X/* --- fwrite.c --- */
X/* Writes directly from a buffer into a stream */
X/* Notes:  Attempts to buffer requests but writes directly if impossible*/
X/*	   #define _V7 gives support for append mode when kernel doesn't*/
X
X#include <sys/types.h>
X#include <limits.h>
X#include <stdio.h>
X#include <string.h>
X#include <unistd.h>
X#include "stdiolib.h"
X#undef fwrite
X
X#define _IO_ERRVAL 0
X
X/* --- The following value determines whether fwrite() requests go	--- */
X/* --- through the buffer or are done directly.  As set, the limit	--- */
X/* --- means that small requests (less than half the stream's buffer	--- */
X/* --- size) will use buffering; larger requests are done directly.	--- */
X/* --- Empirical testing shows this is reasonable; more should be done.	--- */
X#define BUFFER_LIMIT	(stream->_io_bufsiz >> 1)
X
X#define TO_IO(bytes) {				\
X	memcpy(stream->_io._io_ptr, p, bytes);	\
X	stream->_io._io_ptr += bytes;		\
X	stream->_io_count -= bytes;		\
X	}
X#define TO_FS(bytes)	write(stream->_io_fd, (char *) p, bytes)
X
Xsize_t fwrite(ptr, size, nmemb, stream)
Xconst void *ptr;
Xsize_t size;
Xsize_t nmemb;
XFILE *stream;
X{
X  register unsigned char *p = (unsigned char *) ptr;
X  long total_size;
X  int buffer_limit;
X  size_t items;
X  int n;
X
X  _io_assert(p != NULL);
X  _io_assert(_io_valid(stream));
X  _io_assert(!_io_testflag(stream, _IO_READ));
X  _io_assert(!_io_testflag(stream, _IO_ERR));
X
X  if ((total_size = (long) nmemb * (long) size) == 0)
X	return 0;
X
X/* --- Virgin stream: set things up --- */
X  if (stream->_io_count == _IO_NEVER)
X	_o_init(stream);
X
X#ifdef _V7
X/* --- Append kludge --- */
X  if (_io_testflag(stream, _IO_APPEND) && _io_testflag(stream, _IO_NEEDSEEK)) {
X	lseek(stream->_io_fd, 0L, SEEK_END);
X	_io_clearflag(stream, _IO_NEEDSEEK);
X  }
X#endif
X
X/* --- Most common case(?): into the buffer --- */
X  buffer_limit = (stream->_io_count < BUFFER_LIMIT)
X	? stream->_io_count : BUFFER_LIMIT;
X  if (total_size <= buffer_limit) {
X	register int bytes = (int) total_size;
X
X	TO_IO(bytes);
X	return nmemb;
X  }
X
X/* --- Doesn't fit: flush what we've accumulated --- */
X  _flspbuf(stream);
X
X/* --- Huge objects: write() in manageable sections --- */
X  items = 0;
X  if (size > INT_MAX) {
X	while (nmemb-- > 0) {
X		register size_t obj_size = size;
X
X		while (obj_size > INT_MAX) {
X			if ((n = TO_FS(INT_MAX)) != INT_MAX) {
X				_io_setflag(stream, _IO_ERR);
X				return items;
X			}
X			obj_size -= INT_MAX;
X			p += INT_MAX;
X		}
X		if ((n = TO_FS(obj_size)) != obj_size) {
X			_io_setflag(stream, _IO_ERR);
X			return items;
X		}
X		p += obj_size;
X		items++;
X	}
X	return items;
X  }
X
X/* --- Lots of small objects: write() in chunks --- */
X  {
X	size_t items_per_chunk;
X	register int chunk_size;
X	long cutoff = stream->_io_count;
X
X	items_per_chunk = INT_MAX / size;
X	if ((chunk_size = size * items_per_chunk) > cutoff)
X		cutoff = chunk_size;
X	while (total_size > cutoff) {
X		if ((n = TO_FS(chunk_size)) != chunk_size) {
X			_io_setflag(stream, _IO_ERR);
X			return items + n / size;
X		} else {
X			items += items_per_chunk;
X		}
X		total_size -= chunk_size;
X		p += chunk_size;
X	}
X	if ((chunk_size = (int) total_size) > BUFFER_LIMIT) {
X		if ((n = TO_FS(chunk_size)) != chunk_size)
X			_io_setflag(stream, _IO_ERR);
X		return items + n / size;
X	}
X	TO_IO(chunk_size);
X	return nmemb;
X  }
X}
/
echo x - gets.c
sed '/^X/s///' > gets.c << '/'
X/* --- gets.c --- */
X/* Reads characters from stdin, up to a newline */
X/* Notes:  Returns EOF only if no characters read before end of file	*/
X
X#include "stdio.h"
X#include "stdiolib.h"
X#undef gets
X
X#define _IO_ERRVAL NULL
X
Xchar *gets(s)
Xchar *s;
X{
X  register char *p = s;
X  register int c;
X
X  _io_assert(s);
X
X  while ((c = getchar()) != EOF && c != '\n')
X	*p++ = c;
X  *p = '\0';
X  return (p == s && c == EOF) ? NULL : s;
X}
/
echo x - perror.c
sed '/^X/s///' > perror.c << '/'
X/* --- perror.c --- */
X/* Prints the current error message */
X/* Notes:  Only minor changes from standard Minix issue	*/
X
X#include <sys/types.h>
X#include <errno.h>
X#include <stdio.h>
X#include <string.h>
X#include <unistd.h>
X
Xchar *sys_errlist[] = {
X        "Error 0",
X        "Not owner",
X        "No such file or directory",
X        "No such process",
X        "Interrupted system call",
X        "I/O error",
X        "No such device or address",
X        "Arg list too long",
X        "Exec format error",
X        "Bad file number",
X        "No children",
X        "No more processes",
X        "Not enough core",
X        "Permission denied",
X        "Bad address",
X        "Block device required",
X        "Mount device busy",
X        "File exists",
X        "Cross-device link",
X        "No such device",
X        "Not a directory",
X        "Is a directory",
X        "Invalid argument",
X        "File table overflow",
X        "Too many open files",
X        "Not a typewriter",
X        "Text file busy",
X        "File too large",
X        "No space left on device",
X        "Illegal seek",
X        "Read-only file system",
X        "Too many links",
X        "Broken pipe",
X        "Math argument",
X        "Result too large"
X};
X
Xint sys_nerr = sizeof(sys_errlist)/sizeof(char *);
X
Xvoid perror(s)
Xconst char *s;
X{
X  if (errno < 0 || errno >= sizeof(sys_errlist)/sizeof(char *)) {
X	write(2, "Invalid errno\n", 14);
X  } else {
X	write(2, s, strlen(s));
X	write(2, ": ", 2);
X	write(2, sys_errlist[errno], strlen(sys_errlist[errno]));
X	write(2, "\n", 1);
X  }
X}
/
echo x - printf.c
sed '/^X/s///' > printf.c << '/'
X/* --- printf.c --- */
X/* Formatted printing functions */
X/* Notes:  Includes fprintf(), printf(), vfprintf(), and vprintf();	*/
X/*	   All are front ends for _doprnt()				*/
X/*	   vfprintf() and vprintf() backstop macros in <stdio.h>	*/
X
X#include <stdarg.h>
X#include <stdio.h>
X#include "stdiolib.h"
X#undef fprintf
X#undef printf
X#undef vfprintf
X#undef vprintf
X
X
X#define _IO_ERRVAL 0
X
Xint fprintf(stream, format /*, ... */)
XFILE *stream;
Xconst char *format;
X{
X  va_list arg;
X  int n;
X
X  _io_assert(_io_valid(stream));
X  _io_assert(!_io_testflag(stream, _IO_READ));
X  _io_assert(!_io_testflag(stream, _IO_ERR));
X  _io_assert(format);
X
X  va_start(arg, format);
X  n = _doprnt(stream, format, arg);
X  va_end(arg);
X  return n;
X}
X
Xint printf(format /*, ... */)
Xconst char *format;
X{
X  va_list arg;
X  int n;
X
X  _io_assert(_io_valid(stdout));
X  _io_assert(!_io_testflag(stdout, _IO_READ));
X  _io_assert(!_io_testflag(stdout, _IO_ERR));
X  _io_assert(format);
X
X  va_start(arg, format);
X  n = _doprnt(stdout, format, arg);
X  va_end(arg);
X  return n;
X}
X
Xint vfprintf(stream, format, arg)
XFILE *stream;
Xconst char *format;
Xva_list arg;
X{
X  _io_assert(_io_valid(stream));
X  _io_assert(!_io_testflag(stream, _IO_READ));
X  _io_assert(!_io_testflag(stream, _IO_ERR));
X  _io_assert(format);
X
X  return _doprnt(stream, format, arg);
X}
X
Xint vprintf(format, arg)
Xconst char *format;
Xva_list arg;
X{
X  return _doprnt(stdout, format, arg);
X}
/
echo x - remove.c
sed '/^X/s///' > remove.c << '/'
X/* --- remove.c --- */
X/* Removes a file from the file system */
X/* Notes:  Backstops a macro in <stdio.h> */
X
X#include <sys/types.h>
X#include <stdio.h>
X#include <unistd.h>
X#undef remove
X
Xint remove(filename)
Xconst char *filename;
X{
X  return unlink(filename);
X}
/
echo x - rename.c
sed '/^X/s///' > rename.c << '/'
X/* --- rename.c --- */
X/* Renames a file in the file system */
X/* Author: Freeman Pascal */
X
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <errno.h>
X#include <signal.h>
X#include <stdio.h>
X#include <unistd.h>
X#undef rename
X
X/*========================================================================*\
X**				rename()				  **
X\*========================================================================*/
Xint rename(old, new)
Xconst char *old;
Xconst char *new;
X{
X/*
X *	Attempts new link 'old' as 'new'.  If 'new' exists it is unlinked.
X *
X *	NOTE:  	'rename()' will not rename across file systems or 
X *		file types.  Also, if an attempt is made to copy across
X *		file systems both files will be left intact and an
X *		error will be returned.
X */
X  struct stat	s_new, s_old;
X  void		(*s_int)(), (*s_hup)(), (*s_quit)();
X  int		ret = 0;
X  
X  /*
X   *	Get status of 'old' and 'new'; if either attempt fails we know 
X   *	one of the files doesn't exist.  If 'old' doesn't exist, then
X   *	return an error condition.  If both files exist, then test if
X   *	they are both on the same file system.  If 'new' doesn't exist,
X   *	then don't worry about it - it soon will.
X   */
X  if (stat(old, &s_old) == 0) {
X	if (stat(new, &s_new) == 0) {
X		if (s_new.st_dev == s_old.st_dev) {
X			errno = EXDEV;
X			return -1;
X		}
X	}
X	/* Ignore SIGINT, SIGHUP, and SIGQUIT until we're finished. */
X	s_int  = signal(SIGINT,  SIG_IGN);
X	s_hup  = signal(SIGHUP,  SIG_IGN);
X	s_quit = signal(SIGQUIT, SIG_IGN);  
X	/* Does 'new' exist? If so, remove it. */
X	ret = unlink(new);
X	if ((ret = link(old, new)) == 0) 
X		ret = unlink(old);
X	/* Restore signals. */
X	signal(SIGINT,  s_int );
X	signal(SIGHUP,  s_hup );
X	signal(SIGQUIT, s_quit);
X	return ret;
X  }
X  return -1;
X}
/
echo x - scanf.c
sed '/^X/s///' > scanf.c << '/'
X/* --- scanf.c --- */
X/* Formatted input functions */
X/* Notes:  Includes fscanf() and scanf(), front ends for _doscan()	*/
X
X#include <stdarg.h>
X#include <stdio.h>
X#include "stdiolib.h"
X#undef fscanf
X#undef scanf
X
X#define _IO_ERRVAL EOF
X
Xint fscanf(stream, format /*, ... */)
XFILE *stream;
Xconst char *format;
X{
X  va_list arg;
X  int n;
X
X  _io_assert(_io_valid(stream));
X  _io_assert(!_io_testflag(stream, _IO_WRITE));
X  _io_assert(!_io_testflag(stream, (_IO_EOF | _IO_ERR)));
X  _io_assert(format);
X
X  va_start(arg, format);
X  n = _doscan(0, (void *) stream, format, arg);
X  va_end(arg);
X  return n;
X}
X
X
Xint scanf(format /*, ... */)
Xconst char *format;
X{
X  va_list arg;
X  int n;
X
X  _io_assert(_io_valid(stdin));
X  _io_assert(!_io_testflag(stdin, _IO_WRITE));
X  _io_assert(!_io_testflag(stdin, (_IO_EOF | _IO_ERR)));
X  _io_assert(format);
X
X  va_start(arg, format);
X  n = _doscan(0, (void *) stdin, format, arg);
X  va_end(arg);
X  return n;
X}
/
echo x - setvbuf.c
sed '/^X/s///' > setvbuf.c << '/'
X/* --- setvbuf.c --- */
X/* Associates a buffer with a stream and sets buffering modes */
X/* Notes:  Does not actually allocate a buffer; just sets things up	*/
X/*	   Includes setbuf(), which backstops a macro in <stdio.h>	*/
X
X#include <stdio.h>
X#include "stdiolib.h"
X#undef setvbuf
X#undef setbuf
X
X#define _IO_ERRVAL EOF
X
X
Xint setvbuf(stream, buffer, type, size)
Xregister FILE *stream;
Xchar *buffer;
Xint type;
Xsize_t size;
X{
X  _io_assert(_io_valid(stream));
X  _io_assert(type == _IONBF || size != 0);
X  _io_assert(stream->_io_count == _IO_NEVER);
X
X  fflush(stream);
X  _buffree(stream);
X  _io_clearflag(stream, (_IO_LBUF | _IO_MYBUF));
X  switch (type) {
X	case _IONBF:
X		stream->_io_bufsiz = 0;
X		stream->_io_buf = NULL;
X		stream->_io._io_char = EOF;
X		stream->_io_count = _IO_NEVER;
X		return 0;
X	case _IOLBF:
X	case _IOFBF:
X		stream->_io_bufsiz = size;
X		stream->_io._io_ptr = stream->_io_buf = (unsigned char *) buffer;
X		stream->_io_count = _IO_NEVER;
X		_io_setflag(stream, type);
X		return 0;
X	default:
X		return _IO_ERRVAL;
X  }
X}
X
X
Xvoid setbuf(stream, buffer)	/* ANSI requires function definition */
XFILE *stream;			/* (even if the default is a macro)  */
Xchar *buffer;
X{
X  (void) setvbuf(stream, buffer, (buffer == NULL) ? _IONBF : _IOFBF, BUFSIZ);
X}
/
echo x - sprintf.c
sed '/^X/s///' > sprintf.c << '/'
X/* --- sprintf.c --- */
X/* Formatted printing functions for strings */
X/* Notes:  Includes sprintf() and vsprintf()	*/
X/*	   Both are front ends for _doprnt()	*/
X
X#include <limits.h>
X#include <stdarg.h>
X#include <stdio.h>
X#include "stdiolib.h"
X#undef sprintf
X#undef vsprintf
X
X#define _IO_ERRVAL 0
X
X
Xint sprintf(s, format /*, ... */)
Xchar *s;
Xconst char *format;
X{
X  FILE fake;
X  va_list arg;
X  int n;
X
X  _io_assert(s);
X  _io_assert(format);
X
X  fake._io_fd = -1;
X  fake._io_flags = _IO_WRITE | _IO_STRING;
X  fake._io_bufsiz = fake._io_count = INT_MAX;
X  fake._io._io_ptr = fake._io_buf = (unsigned char *) s;
X  va_start(arg, format);
X  n = _doprnt(&fake, format, arg);
X  putc('\0', &fake);
X  va_end(arg);
X  return n;
X}
X
Xint vsprintf(s, format, arg)
Xchar *s;
Xconst char *format;
Xva_list arg;
X{
X  FILE fake;
X  int n;
X
X  _io_assert(s);
X  _io_assert(format);
X
X  fake._io_fd = -1;
X  fake._io_flags = _IO_WRITE | _IO_STRING;
X  fake._io_bufsiz = fake._io_count = INT_MAX;
X  fake._io._io_ptr = fake._io_buf = (unsigned char *) s;
X  n = _doprnt(&fake, format, arg);
X  putc('\0', &fake);
X  return n;
X}
/
echo x - sscanf.c
sed '/^X/s///' > sscanf.c << '/'
X/* --- sscanf.c --- */
X/* Formatted input function for strings */
X/* Notes:  Front end for _doscan()	*/
X
X#include <stdarg.h>
X#include <stdio.h>
X#include "stdiolib.h"
X#undef sscanf
X
X#define _IO_ERRVAL EOF
X
Xint sscanf(s, format /*, ... */)
Xconst char *s;
Xconst char *format;
X{
X  va_list arg;
X  int n;
X
X  _io_assert(s);
X  _io_assert(format);
X
X  va_start(arg, format);
X  n = _doscan(1, (void *) s, format, arg);
X  va_end(arg);
X  return n;
X}
/
echo x - stdio_misc.c
sed '/^X/s///' > stdio_misc.c << '/'
X/* --- stdio_misc.c --- */
X/* Miscellaneous stream functions */
X/* Notes:  Includes clearerr(), feof(), ferror(), and (POSIX) fileno()	*/
X/*	   All functions backstop macros in <stdio.h>			*/
X
X#include <stdio.h>
X#include "stdiolib.h"
X#undef clearerr
X#undef feof
X#undef ferror
X#undef fileno
X
X#define _IO_ERRVAL EOF
X
Xvoid clearerr(stream)
XFILE *stream;
X{
X  _io_assert(_io_valid(stream));
X  _io_clearflag(stream, (_IO_EOF | _IO_ERR));
X}
X
Xint feof(stream)
XFILE *stream;
X{
X  _io_assert(_io_valid(stream));
X  return _io_testflag(stream, _IO_EOF);
X}
X
Xint ferror(stream)
XFILE *stream;
X{
X  _io_assert(_io_valid(stream));
X  return _io_testflag(stream, _IO_ERR);
X}
X
Xint fileno(stream)		/* Posix */
XFILE *stream;
X{
X  _io_assert(_io_valid(stream));
X  return stream->_io_fd;
X}
/
echo x - tmpfile.c
sed '/^X/s///' > tmpfile.c << '/'
X/* --- tmpfile.c --- */
X/* Opens a temporary file which will be deleted on close or exit */
X/* Notes:  Also includes two cleanup routines:				*/
X/*	   _tmp_cleanup - registered with atexit() if tmpfile() is used */
X/*	   _tmp_remove  - removes one temporary file			*/
X
X#include <sys/types.h>
X#include <stdio.h>
X#include <stdlib.h>
X#include <unistd.h>
X#include "stdiolib.h"
X#undef tmpfile
X
Xstatic void _tmp_cleanup();
Xstatic int _tmp_remove();
X
Xextern int (*__tmprm)();
Xstatic char* tmp_name[FOPEN_MAX];
X
XFILE *tmpfile()
X{
X  register char *name;
X  register FILE *stream;
X
X  if ((name = (char *) malloc(L_tmpnam)) == NULL)
X	return NULL;
X
X  (void) tmpnam(name);
X  if (stream = fopen(name, "w+b")) {
X	_io_setflag(stream, _IO_TEMP);
X	tmp_name[_iobindex(stream)] = name;
X	if (!__tmprm) {
X		__tmprm = _tmp_remove;
X		atexit(_tmp_cleanup);
X	}
X  } else {
X	free(name);
X  }
X  return stream;
X}
X
Xstatic void _tmp_cleanup()
X{
X  register int i;
X
X  for (i = 0; i < FOPEN_MAX; i++)
X	_tmp_remove(i);
X}
X
Xstatic int _tmp_remove(i)
Xregister int i;
X{
X  int rc = -1;
X
X  if (tmp_name[i]) {
X	rc = unlink(tmp_name[i]);
X	free(tmp_name[i]);
X	tmp_name[i] = NULL;
X  }
X  return rc;
X}
/
echo x - tmpnam.c
sed '/^X/s///' > tmpnam.c << '/'
X/* --- tmpnam.c --- */
X/* Generates a unique file name */
X/* Notes:  File name is of the form Tmpxxxxx.yyyyy	*/
X/*	   Not reentrant				*/
X
X#include <sys/types.h>
X#include <stdio.h>
X#include <string.h>
X#include <unistd.h>
X#include "stdiolib.h"
X#undef tmpnam
X
X#define DIGITS	5		/* maximum digits converted */
X
Xchar *tmpnam(s)
Xchar *s;
X{
X  static char buf[L_tmpnam];
X  static int pid = 0;
X  static int suffix = 1;
X  int length;
X  register int width;
X  register char *p;
X  int k;
X
X  if (s == NULL)
X	s = buf;
X  if (suffix >= TMP_MAX) {
X	*s = '\0';
X	return NULL;
X  }
X  if (pid == 0)
X	pid = getpid();
X
X  strcpy(s, P_tmpdir);
X  strcat(s, "/Tmp00000.00000");
X  length = strlen(s);
X  p = s + (length - 1 - DIGITS - 1);	/* pid ends here */
X  width = DIGITS;
X  k = pid;
X  do {
X	*p-- = k % 10 + '0';
X  } while ((k /= 10) && (--width > 0));
X  p = s + (length - 1);			/* suffix ends here */
X  width = DIGITS;
X  k = suffix++;
X  do {
X	*p-- = k % 10 + '0';
X  } while ((k /= 10) && (--width > 0));
X  return s;
X}
/
echo x - ungetc.c
sed '/^X/s///' > ungetc.c << '/'
X/* --- ungetc.c --- */
X/* Pushes one character back into an input stream */
X/* Notes:  Will not push back EOF					*/
X/*	   Can fail if tried too many times				*/
X
X#include <stdio.h>
X#include "stdiolib.h"
X#undef ungetc
X
X#define _IO_ERRVAL EOF
X
Xint ungetc(c, stream)
Xregister int c;
Xregister FILE *stream;
X{
X  _io_assert(_io_valid(stream));
X  _io_assert(!_io_testflag(stream, _IO_WRITE));
X
X  if (c == EOF || stream->_io_count == _IO_NEVER)
X	return _IO_ERRVAL;
X
X  if (stream->_io_bufsiz == 0) {
X	if (stream->_io._io_char == EOF) {
X		stream->_io._io_char = c;
X		_io_clearflag(stream, _IO_EOF);
X	} else {
X		c = _IO_ERRVAL;
X	}
X  } else {
X	if (stream->_io._io_ptr != stream->_io_buf) {
X		stream->_io_count++;
X		*--stream->_io._io_ptr = c;
X		_io_clearflag(stream, _IO_EOF);
X	} else {
X		c = _IO_ERRVAL;
X	}
X  }
X  return c;
X}
/

nfs@notecnirp.Princeton.EDU (Norbert Schlenker) (09/30/89)

echo x - ctype.c
sed '/^X/s///' > ctype.c << '/'
X#include <ctype.h>
X#undef isalnum
X#undef isalpha
X#undef isascii
X#undef iscntrl
X#undef isdigit
X#undef isgraph
X#undef islower
X#undef isprint
X#undef ispunct
X#undef isspace
X#undef isupper
X#undef isxdigit
X#undef toascii
X#undef _tolower
X#undef _toupper
X#undef tolower
X#undef toupper
X
X#define _CT_CS	(_CT_C | _CT_S)		/* control character and white space */
X#define _CT_UX	(_CT_U | _CT_X)		/* upper case hex digit */
X#define _CT_LX	(_CT_L | _CT_X)		/* lower case hex digit */
X
Xchar _ctype[] = {
X	0,
X	_CT_C,	_CT_C,	_CT_C,	_CT_C,	_CT_C,	_CT_C,	_CT_C,	_CT_C,
X	_CT_C,	_CT_CS,	_CT_CS,	_CT_CS,	_CT_CS,	_CT_CS,	_CT_C,	_CT_C,
X	_CT_C,	_CT_C,	_CT_C,	_CT_C,	_CT_C,	_CT_C,	_CT_C,	_CT_C,
X	_CT_C,	_CT_C,	_CT_C,	_CT_C,	_CT_C,	_CT_C,	_CT_C,	_CT_C,
X	_CT_SP,	_CT_P,	_CT_P,	_CT_P,	_CT_P,	_CT_P,	_CT_P,	_CT_P,
X	_CT_P,	_CT_P,	_CT_P,	_CT_P,	_CT_P,	_CT_P,	_CT_P,	_CT_P,
X	_CT_N,	_CT_N,	_CT_N,	_CT_N,	_CT_N,	_CT_N,	_CT_N,	_CT_N,
X	_CT_N,	_CT_N,	_CT_P,	_CT_P,	_CT_P,	_CT_P,	_CT_P,	_CT_P,
X	_CT_P,	_CT_UX,	_CT_UX,	_CT_UX,	_CT_UX,	_CT_UX,	_CT_UX,	_CT_U,
X	_CT_U,	_CT_U,	_CT_U,	_CT_U,	_CT_U,	_CT_U,	_CT_U,	_CT_U,
X	_CT_U,	_CT_U,	_CT_U,	_CT_U,	_CT_U,	_CT_U,	_CT_U,	_CT_U,
X	_CT_U,	_CT_U,	_CT_U,	_CT_P,	_CT_P,	_CT_P,	_CT_P,	_CT_P,
X	_CT_P,	_CT_LX,	_CT_LX,	_CT_LX,	_CT_LX,	_CT_LX,	_CT_LX,	_CT_L,
X	_CT_L,	_CT_L,	_CT_L,	_CT_L,	_CT_L,	_CT_L,	_CT_L,	_CT_L,
X	_CT_L,	_CT_L,	_CT_L,	_CT_L,	_CT_L,	_CT_L,	_CT_L,	_CT_L,
X	_CT_L,	_CT_L,	_CT_L,	_CT_P,	_CT_P,	_CT_P,	_CT_P,	_CT_C
X};
Xint _ct_c;
X
X
Xint isalnum(c)
Xint c;
X{
X  return (_ctype+1)[c] & (_CT_U | _CT_L | _CT_N);
X}
X
Xint isalpha(c)
Xint c;
X{
X  return (_ctype+1)[c] & (_CT_U | _CT_L);
X}
X
Xint isascii(c)
Xint c;
X{
X  return (unsigned) c <= 0x7f;
X}
X
Xint iscntrl(c)
Xint c;
X{
X  return (_ctype+1)[c] & (_CT_C);
X}
X
Xint isdigit(c)
Xint c;
X{
X  return (_ctype+1)[c] & (_CT_N);
X}
X
Xint isgraph(c)
Xint c;
X{
X  return (_ctype+1)[c] & (_CT_U | _CT_L | _CT_N | _CT_P);
X}
X
Xint islower(c)
Xint c;
X{
X  return (_ctype+1)[c] & (_CT_L);
X}
X
Xint isprint(c)
Xint c;
X{
X  return (_ctype+1)[c] & (_CT_U | _CT_L | _CT_N | _CT_P | _CT_SP);
X}
X
Xint ispunct(c)
Xint c;
X{
X  return (_ctype+1)[c] & (_CT_P);
X}
X
Xint isspace(c)
Xint c;
X{
X  return (_ctype+1)[c] & (_CT_S | _CT_SP);
X}
X
Xint isupper(c)
Xint c;
X{
X  return (_ctype+1)[c] & (_CT_U);
X}
X
Xint isxdigit(c)
Xint c;
X{
X  return (_ctype+1)[c] & (_CT_N | _CT_X);
X}
X
Xint toascii(c)
Xint c;
X{
X  return c & 0x7f;
X}
X
Xint _tolower(c)
Xint c;
X{
X  return c - 'A' + 'a';
X}
X
Xint _toupper(c)
Xint c;
X{
X  return c - 'a' + 'A';
X}
X
Xint tolower(c)
Xint c;
X{
X  return ((_ctype+1)[c] & (_CT_U)) ? c - 'A' + 'a' : c;
X}
X
Xint toupper(c)
Xint c;
X{
X  return ((_ctype+1)[c] & (_CT_L)) ? c - 'a' + 'A' : c;
X}
/
echo x - div.c
sed '/^X/s///' > div.c << '/'
X#include <stdlib.h>
X
Xdiv_t div(numer, denom)
Xint numer;
Xint denom;
X{
X  div_t result;
X
X  result.quot = numer / denom;
X  result.rem  = numer % denom;
X  return result;
X}
/
echo x - ldiv.c
sed '/^X/s///' > ldiv.c << '/'
X#include <stdlib.h>
X
Xldiv_t ldiv(numer, denom)
Xlong int numer;
Xlong int denom;
X{
X  ldiv_t result;
X
X  result.quot = numer / denom;
X  result.rem  = numer % denom;
X  return result;
X}
/
echo x - strtol.c
sed '/^X/s///' > strtol.c << '/'
X#include <ctype.h>
X#include <errno.h>
X#include <limits.h>
X#include <stdlib.h>
X#undef strtol
X#undef atoi
X#undef atol
X
Xlong int strtol(nptr, endptr, base)
Xregister const char *nptr;
Xchar **endptr;
Xint base;
X{
X  register int c;
X  long result = 0L;
X  long limit;
X  int negative = 0;
X  int overflow = 0;
X  int digit;
X
X  while ((c = *nptr) && isspace(c))	/* skip leading white space */
X	nptr++;
X  if ((c = *nptr) == '+' || c == '-') {	/* handle signs */
X	negative = (c == '-');
X	nptr++;
X  }
X  if (base == 0) {			/* determine base if unknown */
X	base = 10;
X	if (*nptr == '0') {
X		base = 8;
X		nptr++;
X		if ((c = *nptr) == 'x' || c == 'X') {
X			base = 16;
X			nptr++;
X		}
X	}
X  }
X  else
X  if (base == 16 && *nptr == '0') {	/* discard 0x/0X prefix if hex */
X	nptr++;
X	if ((c = *nptr == 'x') || c == 'X')
X		nptr++;
X  }
X
X  limit = LONG_MAX / base;		/* ensure no overflow */
X
X  nptr--;				/* convert the number */
X  while (c = *++nptr) {
X	if (isdigit(c))
X		digit = c - '0';
X	else
X		digit = c - (isupper(c) ? 'A' : 'a') + 10;
X	if (digit < 0 || digit >= base)
X		break;
X	if (result > limit)
X		overflow = 1;
X	if (!overflow) {
X		result = base * result;
X		if (digit > LONG_MAX - result)
X			overflow = 1;
X		else	
X			result += digit;
X	}
X  }
X  if (negative && !overflow)
X	result = 0L - result;
X  if (overflow) {
X	errno = ERANGE;
X	if (negative)
X		result = LONG_MIN;
X	else
X		result = LONG_MAX;
X  }
X
X  if (endptr != NULL)			/* set up return values */
X	*endptr = nptr;
X  return result;
X}
X
Xint atoi(nptr)
Xconst char *nptr;
X{
X  return (int) strtol(nptr, NULL, 10);
X}
X
Xlong atol(nptr)
Xconst char *nptr;
X{
X  return strtol(nptr, NULL, 10);
X}
/
echo x - strtoul.c
sed '/^X/s///' > strtoul.c << '/'
X#include <ctype.h>
X#include <errno.h>
X#include <limits.h>
X#include <stdlib.h>
X#undef strtoul
X
Xunsigned long int strtoul(nptr, endptr, base)
Xregister const char *nptr;
Xchar **endptr;
Xint base;
X{
X  register int c;
X  unsigned long result = 0L;
X  unsigned long limit;
X  int negative = 0;
X  int overflow = 0;
X  int digit;
X
X  while ((c = *nptr) && isspace(c))	/* skip leading white space */
X	nptr++;
X  if ((c = *nptr) == '+' || c == '-') {	/* handle signs */
X	negative = (c == '-');
X	nptr++;
X  }
X  if (base == 0) {			/* determine base if unknown */
X	base = 10;
X	if (*nptr == '0') {
X		base = 8;
X		nptr++;
X		if ((c = *nptr) == 'x' || c == 'X') {
X			base = 16;
X			nptr++;
X		}
X	}
X  }
X  else
X  if (base == 16 && *nptr == '0') {	/* discard 0x/0X prefix if hex */
X	nptr++;
X	if ((c = *nptr == 'x') || c == 'X')
X		nptr++;
X  }
X
X  limit = ULONG_MAX / base;		/* ensure no overflow */
X
X  nptr--;				/* convert the number */
X  while (c = *++nptr) {
X	if (isdigit(c))
X		digit = c - '0';
X	else
X		digit = c - (isupper(c) ? 'A' : 'a') + 10;
X	if (digit < 0 || digit >= base)
X		break;
X	if (result > limit)
X		overflow = 1;
X	if (!overflow) {
X		result = base * result;
X		if (digit > ULONG_MAX - result)
X			overflow = 1;
X		else	
X			result += digit;
X	}
X  }
X  if (negative && !overflow)	/* BIZARRE, but ANSI says we should do this! */
X	result = 0L - result;
X  if (overflow) {
X	errno = ERANGE;
X	result = ULONG_MAX;
X  }
X
X  if (endptr != NULL)			/* point at tail */
X	*endptr = nptr;
X  return result;
X}
/
echo x - printk.c
sed '/^X/s///' > printk.c << '/'
X/* --- printk.c --- */
X/* Kernel's version of printf() */
X
X#define _KERNEL_
X#include <prototype.h>
X#include "_doprnt.c"
/
echo x - prints.c
sed '/^X/s///' > prints.c << '/'
X/* prints() is like printf(), except that it doesn't have anything to do
X * with streams and it can only handle %s and %c.  It cannot print any
X * of the numeric types such as %d, %o, etc.  It always left justifies
X * strings; it cannot right justify them.  It has the advantage of not
X * requiring the runtime code for converting binary numbers to ASCII,
X * which saves 1K bytes in the object program.  Since many of the small
X * utilities do not need numeric printing, they often use prints().  It
X * has the disadvantage that its output is not synchronized with any stream.  
X */
X
X#include <sys/types.h>
X#include <stdarg.h>
X#include <unistd.h>
X
X#define STDOUT		1
X#define TRUNC_SIZE	128
X#define PUT(c)		{ if (bp != &buf[TRUNC_SIZE]) *bp++ = c; }
X
Xint prints(s)
Xchar *s;
X{
X  va_list ap;
X  char buf[TRUNC_SIZE];
X  register char *fp = s;
X  register char *bp = buf;
X  register int width;
X  char *p, *p1;
X
X  va_start(ap, s);
X  while (*fp) {
X	if (*fp != '%') {
X		PUT(*fp++);
X		continue;
X	}
X	fp++;
X	width = 0;
X	while (*fp >= '0' && *fp <= '9')
X		width = 10 * width + (*fp++ - '0');
X	switch (*fp) {
X	    case 'c':
X		PUT(va_arg(ap, char));
X		break;
X	    case 's':
X		p1 = p = va_arg(ap, char *);
X		while(*p1) PUT(*p1++);
X		for (width -= (p1 - p); --width >= 0; )
X			PUT(' ');
X		break;
X	    default:
X		PUT('%'); PUT(*s);
X		break;
X	}
X	fp++;
X  }
X  write(STDOUT, buf, bp - buf);		/* write everything at once */
X  return bp - buf;
X}
/
echo x - cuserid.c
sed '/^X/s///' > cuserid.c << '/'
X#define _POSIX_SOURCE
X#include <sys/types.h>
X#include <pwd.h>
X#include <stdio.h>
X#include <string.h>
X#include <unistd.h>
X
Xchar *cuserid(s)
Xchar *s;
X{
X  static char id[L_cuserid];
X  struct passwd *pwd;
X
X  if (s == NULL)
X    s = id;
X
X  if ((pwd = getpwuid(geteuid())) == NULL) {
X	*s = '\0';
X	return NULL;
X  }
X  strcpy(s, pwd->pw_name);
X  return s;
X}
/
echo x - getlogin.c
sed '/^X/s///' > getlogin.c << '/'
X#define _POSIX_SOURCE
X#include <sys/types.h>
X#include <pwd.h>
X#include <stdio.h>
X#include <string.h>
X#include <unistd.h>
X
Xchar *getlogin()
X{
X  static char id[L_cuserid];
X  struct passwd *pwd;
X
X  if ((pwd = getpwuid(getuid())) == NULL)
X	return NULL;
X  return strcpy(id, pwd->pw_name);
X}
/
echo x - getgrent.c
sed '/^X/s///' > getgrent.c << '/'
X/*
X * get entry from group file
X *   By Patrick van Kleef
X *   POSIX conversion by Norbert Schlenker
X */
X
X#define _POSIX_SOURCE
X#include <sys/types.h>
X#include <fcntl.h>
X#include <grp.h>
X#include <stdlib.h>
X#include <string.h>
X#include <unistd.h>
X
X#define PRIVATE static
X
X
XPRIVATE char _gr_file[] = "/etc/group";
XPRIVATE char _grbuf[256];
XPRIVATE char _buffer[1024];
XPRIVATE char *_pnt;
XPRIVATE char *_buf;
XPRIVATE int  _gfd = -1;
XPRIVATE int  _bufcnt;
XPRIVATE struct group grp;
XPRIVATE char *_mem = NULL;
X
Xint setgrent()
X{
X  if (_gfd >= 0)
X	lseek (_gfd, 0L, SEEK_SET);
X  else
X	_gfd = open(_gr_file, O_RDONLY);
X
X  _bufcnt = 0;
X  return (_gfd);
X}
X
X
Xvoid endgrent() 
X{
X  if (_gfd >= 0)
X	close (_gfd);
X
X  _gfd = -1;
X  _bufcnt = 0;
X}
X
X
XPRIVATE int _getline() 
X{
X  if (_gfd < 0 && setgrent() < 0)
X	return 0;
X
X  _buf = _grbuf;
X  do {
X	if (--_bufcnt <= 0) {
X		if ((_bufcnt = read(_gfd, _buffer, 1024)) <= 0)
X			return 0;
X		else
X			_pnt = _buffer;
X	}
X	*_buf++ = *_pnt++;
X  } while (*_pnt != '\n');
X  _pnt++;
X  _bufcnt--;
X  *_buf = 0;
X  _buf = _grbuf;
X  return 1;
X}
X
XPRIVATE void _skip_period() 
X{
X  while ((*_buf) && (*_buf != ':'))
X	_buf++;
X  *_buf++ = '\0';
X}
X
Xstruct group *getgrent() 
X{
X  if (_getline() == 0)
X       return 0;
X
X  grp.gr_name = _buf;
X  _skip_period();
X  grp.gr_passwd = _buf;
X  _skip_period();
X  grp.gr_gid = (gid_t) atoi (_buf);
X  _skip_period();
X  return &grp;
X}
X
XPRIVATE void _grp_members()  /* PENDING - needs to be rather more elaborate */
X{
X  grp.gr_mem = &_mem;
X}
X
Xstruct group *getgrnam(name)
Xchar *name;
X{
X  struct group *grp;
X
X  setgrent();
X  while ((grp = getgrent()) != 0)
X	if (!strcmp(grp->gr_name, name))
X		break;
X  endgrent();
X  _grp_members();
X  return grp;
X}
X
Xstruct group *getgrgid(gid)
Xgid_t gid;
X{
X  struct group *grp;
X
X  setgrent();
X  while ((grp = getgrent()) != 0)
X	if (grp->gr_gid == gid)
X		break;
X  endgrent();
X  _grp_members();
X  return grp;
X}
/
echo x - getpwent.c
sed '/^X/s///' > getpwent.c << '/'
X/*
X * get entry from password file
X *   By Patrick van Kleef
X *   POSIX conversion by Norbert Schlenker
X */
X
X#define _POSIX_SOURCE
X#include <sys/types.h>
X#include <fcntl.h>
X#include <pwd.h>
X#include <stdlib.h>
X#include <string.h>
X#include <unistd.h>
X
X#define PRIVATE static
X
XPRIVATE char  _pw_file[] = "/etc/passwd";
XPRIVATE char  _pwbuf[256];
XPRIVATE char  _buffer[1024];
XPRIVATE char *_pnt;
XPRIVATE char *_buf;
XPRIVATE int   _pw = -1;
XPRIVATE int   _bufcnt;
XPRIVATE struct passwd pwd;
X
Xint setpwent() 
X{
X  if (_pw >= 0)
X	lseek(_pw, 0L, SEEK_SET);
X  else
X	_pw = open(_pw_file, O_RDONLY);
X
X  _bufcnt = 0;
X  return _pw;
X}
X
X
Xvoid endpwent() 
X{
X  if (_pw >= 0)
X	close (_pw);
X
X  _pw = -1;
X  _bufcnt = 0;
X}
X
XPRIVATE int _getline() 
X{
X  if (_pw < 0 && setpwent() < 0)
X	return 0;
X  _buf = _pwbuf;
X  do {
X	if (--_bufcnt <= 0) {
X		if ((_bufcnt = read(_pw, _buffer, 1024)) <= 0)
X			return 0;
X		else
X			_pnt = _buffer;
X	}
X	*_buf++ = *_pnt++;
X  } while (*_pnt != '\n');
X  _pnt++;
X  _bufcnt--;
X  *_buf = 0;
X  _buf = _pwbuf;
X  return 1;
X}
X
XPRIVATE void _skip_period() 
X{
X  while (*_buf != ':')
X	_buf++;
X  *_buf++ = '\0';
X}
X
Xstruct passwd *getpwent() 
X{
X  if (_getline() == 0)
X	return 0;
X
X  pwd.pw_name = _buf;
X  _skip_period();
X  pwd.pw_passwd = _buf;
X  _skip_period();
X  pwd.pw_uid = (uid_t) atoi (_buf);
X  _skip_period();
X  pwd.pw_gid = (gid_t) atoi (_buf);
X  _skip_period();
X  pwd.pw_gecos = _buf;
X  _skip_period();
X  pwd.pw_dir = _buf;
X  _skip_period();
X  pwd.pw_shell = _buf;
X
X  return &pwd;
X}
X
Xstruct passwd *getpwnam(name)
Xchar *name;
X{
X  struct passwd *pwd;
X
X  setpwent();
X  while ((pwd = getpwent()) != 0)
X	if (!strcmp(pwd->pw_name, name))
X		break;
X  endpwent();
X  return pwd;
X}
X
Xstruct passwd *getpwuid(uid)
Xuid_t uid;
X{
X  struct passwd *pwd;
X
X  setpwent();
X  while ((pwd = getpwent()) != 0)
X	if (pwd->pw_uid == uid)
X		break;
X  endpwent();
X  return pwd;
X}
/