Path: utzoo!attcan!uunet!wuarchive!udel!princeton!notecnirp!nfs From: nfs@notecnirp.Princeton.EDU (Norbert Schlenker) Newsgroups: comp.os.minix Subject: Another new stdio (part 0 of 4) Summary: Release notes Message-ID: <19734@princeton.Princeton.EDU> Date: 30 Sep 89 16:02:32 GMT Sender: news@princeton.Princeton.EDU Reply-To: nfs@notecnirp.UUCP (Norbert Schlenker) Organization: Dept. of Computer Science, Princeton University Lines: 193 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,, 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 and ). - Various headers that should be included are not. I have not supplied , , or . I look forward to having them. - Copyright acknowledgements: is pretty much like the original; and 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 . 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 or and should probably be recompiled. The existing versions will continue to work as currently linked.