diff -Nurd linux86.old/Changes linux86/Changes --- linux86.old/Changes Fri Dec 17 17:50:58 1999 +++ linux86/Changes Mon May 21 14:09:17 2001 @@ -1,3 +1,27 @@ +For version 0.16.0. + +> As major bugs seem to be absent 0.16.0 is escaping. + +> Seperated the multi-pass optimisation from the jump extension. We now have + the -j back to it's old meaning and -O added to help shorten instructions. + +> Fix for nested conditionals in the assembler. + +> Fix for listing to unusual locations; assembler tried to list non-existant + lines. + +> Removed lots of warning from the ar86 code. (__STDC__ flags too) + +> Stop trying to strip scripts on install. + +> Remove non-working versions of malloc and stdio from libc directories. + +> Lots of changes in the 'bootblocks' example code. + +> Updated 'make distribution' to be all in the distribution. + +> bin86 Makefile adjusted so that the as86 script isn't installed with -s. + For version 0.15.0. > Added support for archives to nm86/objdump86 and size86. diff -Nurd linux86.old/Contributors linux86/Contributors --- linux86.old/Contributors Sat Nov 28 10:32:15 1998 +++ linux86/Contributors Thu Feb 10 08:47:58 2000 @@ -31,5 +31,5 @@ Dale Schumacher Wietse Venema Joel Weber II -Claudio Matsuoka +Claudio Matsuoka Andrew Chittenden diff -Nurd linux86.old/Libc_version linux86/Libc_version --- linux86.old/Libc_version Fri Dec 17 18:06:30 1999 +++ linux86/Libc_version Tue May 22 09:46:45 2001 @@ -1 +1 @@ -0.15.0 +0.16.0 diff -Nurd linux86.old/Makefile linux86/Makefile --- linux86.old/Makefile Tue Mar 9 13:22:02 1999 +++ linux86/Makefile Sat May 12 08:03:01 2001 @@ -23,8 +23,7 @@ $(TARGETS): make.fil PATH="`pwd`/bin:$$PATH" $(MAKE) -f make.fil TOPDIR=`pwd` $@ -$(TARGETS): phony -phony: +$(TARGETS): ld: ld86 as: as86 @@ -54,7 +53,7 @@ ifdef.o: ifdef.c $(CC) $(CFLAGS) $(IFDEFFLAGS) -c ifdef.c -Uninstall: phony +Uninstall: @# CHECK FROM HERE @make -n Uninstall @echo 'Are you really sure... have you checked this... ^C to interrupt' @@ -71,50 +70,5 @@ @# TO HERE distribution: - @[ `id -u` -eq 0 ] || fakeroot --nomixedlibhack -c $(MAKE) do_dist - @[ `id -u` -ne 0 ] || $(MAKE) do_dist - -do_dist: - @rm -f /tmp/linux-86 || true - @[ ! -f Copy_dist ] || sh Copy_dist - mkdir -p -m 0777 /tmp/Dist - [ -d /tmp/linux-86 ] || ln -s `pwd` /tmp/linux-86 - cd /tmp &&\ - $(MAKE) -C linux-86 realclean &&\ - $(MAKE) -C linux-86/libc Libc_version &&\ - VER=`cat linux-86/Libc_version` &&\ - tar cf Dist/Dev86src-$$VER.tar linux-86/* - gzip -f9 /tmp/Dist/Dev86src-*.tar & - - cd /tmp &&\ - VER=`cat linux-86/Libc_version` &&\ - ln -s linux-86/as as86 &&\ - cp -p linux-86/man/as86.1 as86/as86.1 &&\ - cp -p linux-86/COPYING as86/COPYING &&\ - tar cf Dist/as86-$$VER.tar `find as86/* -prune -type f` &&\ - rm as86/as86.1 as86 - gzip -f9 /tmp/Dist/as86-*.tar & - - cd /tmp/linux-86 &&\ - VER=`cat Libc_version` &&\ - make -C bin86 grab &&\ - tar cf /tmp/Dist/bin86-$$VER.tar bin86 &&\ - make -C bin86 ungrab - gzip -f9 /tmp/Dist/bin86-*.tar & - - cd /tmp &&\ - VER=`cat linux-86/Libc_version` &&\ - $(MAKE) -C /tmp/linux-86 install \ - ARFLAGS=q DIST=/tmp/linux-86-dist ELKSSRC=/dev/null &&\ - $(MAKE) -C /tmp/linux-86 other &&\ - tar cf /tmp/Dist/Dev86bin-$$VER.tar -C /tmp/linux-86-dist . &&\ - rm -f /tmp/Dist/Dev86clb-$$VER.zip Bcc &&\ - ln -s /tmp/linux-86 Bcc &&\ - zip -9rpk /tmp/Dist/Dev86clb-$$VER.zip \ - Bcc/lib/crt0.o Bcc/lib/libc.a Bcc/lib/libbsd.a \ - Bcc/lib/libdos.a Bcc/lib/libc_f.a Bcc/lib/libc_s.a \ - Bcc/lib/i386/crt0.o Bcc/lib/i386/libc.a &&\ - rm Bcc - - gzip -v9f /tmp/Dist/Dev86bin-*.tar - @rm /tmp/linux-86 || true + @[ `id -u` -eq 0 ] || fakeroot -- sh ./Mk_dist + @[ `id -u` -ne 0 ] || sh ./Mk_dist diff -Nurd linux86.old/Mk_dist linux86/Mk_dist --- linux86.old/Mk_dist Thu Jan 1 01:00:00 1970 +++ linux86/Mk_dist Mon May 21 15:15:45 2001 @@ -0,0 +1,159 @@ +#!/bin/sh - +# +# This script builds _and checks_ all the distribution files from my source +# directory. It's very selective because I've got a lot of historical and +# other 'junk' in the same directory. (85Mb!) +# + +trap "exit 1" 1 2 3 15 + +DIR="`pwd`" +TMPDIR=/tmp/Linux-86 +TMPSRC=linux86 +ARCDIR="$DIR"/dev86arc + +SRCDIRS='bcc unproto as ar ld copt man elksemu dis88 tests libbsd bin86' +DISTFILES='Libc_version Makefile README COPYING MAGIC Changes Contributors + mkcompile mkcompile2 later.c GNUmakefile libcompat + ifdef.c makefile.in Mk_dist' + +TMPDIST=$TMPDIR/$TMPSRC +rm -rf ${TMPDIR} +mkdir -p ${TMPDIST} + +#----------------------------------------------------------------------- + +echo Checking version + +make -s -C libc Libc_version +make -s -C bin86 ungrab +VER=`cat Libc_version` + +echo Copying most program files. +cp -a $DISTFILES $SRCDIRS ${TMPDIST} + +#----------------------------------------------------------------------- + +echo Copying libc. + +LIBC_FILES='Makefile Make.defs crt0.c + README COPYING KERNEL + New_subdir Pre_main Config_sh Config.dflt' + +mkdir ${TMPDIST}/libc + +( + cd libc + LIBC_DIRS="`for i in */Makefile */Config; do dirname $i; done | sort -u`" + cp -a $LIBC_FILES include $LIBC_DIRS ${TMPDIST}/libc/. +) + +#----------------------------------------------------------------------- + +echo Copying bootblocks and doselks. +make -s -C bootblocks distribution +make -s -C doselks distribution + +mkdir ${TMPDIST}/bootblocks +( cd ${TMPDIST}/bootblocks ; tar xzf /tmp/bootblocks.tar.gz ) + +mkdir ${TMPDIST}/doselks +( cd ${TMPDIST}/doselks ; tar xzf /tmp/doselks.tar.gz ) + +[ "`id -un`" = "root" ] && { + chown -R root:root ${TMPDIST} + chmod -R og=u-w ${TMPDIST} +} + +rm -f /tmp/bootblocks.tar.gz /tmp/doselks.tar.gz /tmp/libc-8086-$VER.tar.gz + +echo Extracting previous version +rm -f $ARCDIR/Dev86src-$VER.tar.gz + +mkdir ${TMPDIST}.tmp +( cd ${TMPDIST}.tmp + tar xzf `ls -tr $ARCDIR/Dev86src*.0.tar.gz | tail -1` + mv * ${TMPDIST}.old +) +rmdir ${TMPDIST}.tmp + +# ARCDIR=${TMPDIR}/arc ; mkdir -p ${ARCDIR} +cd ${TMPDIST} +echo COPY COMPLETE -- Switched to ${TMPDIST}, ARCDIR now $ARCDIR +echo + +#----------------------------------------------------------------------- +# +# + +echo 'Ensuring clean tree' + +cd ${TMPDIST} + make -s clean realclean + mv as/obj1 ${TMPDIST}-obj1 + EXCL="`find . -name '*.o' -o -name '*.obj' \ + -o -name '*.lib' -o -name '*.bak' \ + -o -name '*~' -o -name '*.exe' \ + -o -name '*.orig' -o -name '*.rej' \ + `" + mv ${TMPDIST}-obj1 as/obj1 + rm -f $EXCL + rm -f `find . -type l` + +echo Generating patch against previous .0 version. + +cd ${TMPDIR} + +mv ${TMPSRC}.old/bootblocks boot.old +mv ${TMPSRC}/bootblocks boot + +diff -Nurd ${TMPSRC}.old ${TMPSRC} > ${ARCDIR}/Dev86src-$VER.patch + +mv boot.old ${TMPSRC}.old/bootblocks +mv boot ${TMPSRC}/bootblocks + +diff -Nurd ${TMPSRC}.old/bootblocks ${TMPSRC}/bootblocks >> ${ARCDIR}/Dev86src-$VER.patch + +gzip -f9 ${ARCDIR}/Dev86src-$VER.patch + +echo Creating full source archive. +ln -s ${TMPSRC} dev86-$VER +tar cf ${ARCDIR}/Dev86src-$VER.tar dev86-$VER/* +gzip -f9 ${ARCDIR}/Dev86src-$VER.tar + +echo Creating as86 source archive. +ln -s ${TMPSRC}/as as86-$VER +cp -p ${TMPSRC}/man/as86.1 as86-$VER/as86.1 +cp -p ${TMPSRC}/COPYING as86-$VER/COPYING +tar cf ${ARCDIR}/as86-$VER.tar `find as86-$VER/* -prune -type f` +gzip -f9 ${ARCDIR}/as86-*.tar + +echo Creating bin86 source archive. +make -s -C ${TMPSRC}/bin86 grab +ln -s ${TMPSRC}/bin86 bin86-$VER +tar chf ${ARCDIR}/bin86-$VER.tar bin86-$VER +make -s -C ${TMPSRC}/bin86 ungrab +gzip -f9 ${ARCDIR}/bin86-*.tar + +################################################################### + +echo Compile up the binaries. + +cd ${TMPDIR} || exit 1 +mkdir -p ${TMPDIST}.ins +make -C ${TMPDIST} install ARFLAGS=q DIST=${TMPDIST}.ins ELKSSRC=/dev/null || + exit +make -C ${TMPDIST} other || exit +tar cf ${ARCDIR}/Dev86bin-$VER.tar -C ${TMPDIST}.ins . +rm -f ${ARCDIR}/Dev86clb-$VER.zip Bcc +ln -s ${TMPDIST} Bcc + +zip -9rpk ${ARCDIR}/Dev86clb-$VER.zip \ + Bcc/lib/crt0.o Bcc/lib/libc.a Bcc/lib/libbsd.a \ + Bcc/lib/libdos.a Bcc/lib/libc_f.a Bcc/lib/libc_s.a \ + Bcc/lib/i386/crt0.o Bcc/lib/i386/libc.a || exit +rm Bcc + +gzip -9f ${ARCDIR}/Dev86bin-$VER.tar || exit + +echo Process completed. diff -Nurd linux86.old/ar/Makefile linux86/ar/Makefile --- linux86.old/ar/Makefile Tue Sep 28 10:28:06 1999 +++ linux86/ar/Makefile Sat Jan 6 12:14:55 2001 @@ -2,7 +2,6 @@ # This file is part of the Linux-8086 Development environment and is # distributed under the GNU General Public License. -xCC=bcc -0 LIBDIR =/usr/bin CFLAGS =-O LDFLAGS = @@ -12,7 +11,7 @@ all: ar86 ar86: $(OBJS) - $(CC) $(LDFLAGS) $(OBJS) -o $@ + $(CC) $(LDFLAGS) $^ -o $@ install: ar86 install -d $(LIBDIR) diff -Nurd linux86.old/ar/ar.c linux86/ar/ar.c --- linux86.old/ar/ar.c Sat Jul 17 05:00:16 1999 +++ linux86/ar/ar.c Sun Dec 3 08:20:47 2000 @@ -19,6 +19,11 @@ #include #include +#ifdef __STDC__ +#include +#include +#include +#endif #include #include #include @@ -214,6 +219,7 @@ /* Name this program was run with. */ char *program_name; +#ifndef __STDC__ char *xmalloc (), *xrealloc (); void free (); @@ -236,6 +242,57 @@ void delete_members (), move_members (), replace_members (); void quick_append (); char *basename (); +void print_modes (); +char *make_tempname (); +void copy_out_member (); +#else +/* Grrr. */ +extern void error (); +extern void fatal (); +extern void extract_members (); + +extern char *basename (char *path); +extern char *concat (char *s1, char *s2, char *s3); +extern char *make_tempname (char *name); +extern char *xmalloc (unsigned int size); +extern char *xrealloc (char *ptr, unsigned int size); +extern int filter_symbols (struct nlist *syms, unsigned int symcount); +extern int insert_in_map (char *name, struct mapelt *map, struct mapelt *after); +extern int main (int argc, char **argv); +extern int move_in_map (char *name, struct mapelt *map, struct mapelt *after); +extern int read_header_info (struct mapelt *mapelt, int desc, long int offset, long int *syms_offset, unsigned int *syms_size, long int *strs_offset, unsigned int *strs_size); +extern struct mapelt *find_mapelt (struct mapelt *map, char *name); +extern struct mapelt *find_mapelt_noerror (struct mapelt *map, register char *name); +extern struct mapelt *last_mapelt (struct mapelt *map); +extern struct mapelt *make_map (int nonexistent_ok); +extern struct mapelt *prev_mapelt (struct mapelt *map, struct mapelt *elt); +extern void add_to_map (struct member_desc member); +extern void close_archive (void); +extern void copy_out_member (struct mapelt *mapelt, int archive_indesc, int outdesc, char *outname); +extern void delete_from_map (char *name, struct mapelt *map); +extern void delete_members (void); +extern void error_with_file (char *string, struct mapelt *mapelt); +extern void extract_member (struct member_desc member, FILE *istream); +extern void header_from_map (struct ar_hdr *header, struct mapelt *mapelt); +extern void lock_for_update (void); +extern void make_new_symdefs (struct mapelt *mapelt, int archive_indesc); +extern void move_members (void); +extern void mywrite (int desc, char *buf, int bytes, char *file); +extern void perror_with_name (char *name); +extern void pfatal_with_name (char *name); +extern void print_contents (struct member_desc member, FILE *istream); +extern void print_descr (struct member_desc member); +extern void print_modes (int modes); +extern void quick_append (void); +extern void read_old_symdefs (struct mapelt *map, int archive_indesc); +extern void replace_members (void); +extern void touch_symdef_member (int outdesc, char *outname); +extern void two_operations (void); +extern void update_symdefs (struct mapelt *map, int archive_indesc); +extern void usage (char *s1, char *s2); +extern void write_archive (struct mapelt *map, int appendflag); +extern void write_symdef_member (struct mapelt *mapelt, struct mapelt *map, int outdesc, char *outname); +#endif /* Output BYTES of data at BUF to the descriptor DESC. FILE is the name of the file (for error messages). */ @@ -539,8 +596,6 @@ fclose (arcstream); } -void print_modes (); - void print_descr (member) struct member_desc member; @@ -872,9 +927,6 @@ to do any I/O on the archive file. */ -char *make_tempname (); -void copy_out_member (); - void write_archive (map, appendflag) struct mapelt *map; @@ -1327,7 +1379,7 @@ change_map = change_map->next; if (!changed && (!symdef_flag || symdef_exists)) /* Nothing changed. */ - close_archive (change_map); + close_archive (); else write_archive (change_map, 0); } diff -Nurd linux86.old/as/Makefile linux86/as/Makefile --- linux86.old/as/Makefile Fri Jul 31 09:53:43 1998 +++ linux86/as/Makefile Sat Jan 6 09:52:28 2001 @@ -12,13 +12,13 @@ all: as86 as86_encap as86: $(OBJS) - $(CC) $(LDFLAGS) $(OBJS) -o as86 + $(CC) $(LDFLAGS) $(OBJS) -o $@ as86_encap: as86_encap.sh sed -e "s:%%LIBDIR%%:$(LIBDIR):" -e "s:%%BINDIR%%:$(BINDIR):" \ - < as86_encap.sh > tmp - @mv -f tmp as86_encap - chmod +x as86_encap + < $^ > tmp + @mv -f tmp $@ + chmod +x $@ install: all install -d $(LIBDIR) diff -Nurd linux86.old/as/as.c linux86/as/as.c --- linux86.old/as/as.c Thu Mar 18 07:07:04 1999 +++ linux86/as/as.c Tue Sep 26 21:08:13 2000 @@ -221,7 +221,9 @@ #ifdef I80386 case 'j': jumps_long = flag_state; - if( jumps_long ) ++last_pass; + break; + case 'O': + if( flag_state ) last_pass = 2; else last_pass = 1; break; #endif @@ -328,7 +330,7 @@ { as_abort( #ifdef I80386 -"usage: as [-03agjuw] [-b [bin]] [-lm [list]] [-n name] [-o obj] [-s sym] src"); +"usage: as [-03agjuwO] [-b [bin]] [-lm [list]] [-n name] [-o obj] [-s sym] src"); #else "usage: as [-guw] [-b [bin]] [-lm [list]] [-n name] [-o obj] [-s sym] src"); #endif diff -Nurd linux86.old/as/assemble.c linux86/as/assemble.c --- linux86.old/as/assemble.c Mon Mar 22 18:38:38 1999 +++ linux86/as/assemble.c Fri Oct 27 09:02:12 2000 @@ -9,7 +9,6 @@ #include "scan.h" PRIVATE bool_t nocolonlabel; /* set for labels not followed by ':' */ -PRIVATE offset_t oldlabel = 0; PRIVATE void (*routine) P((void)); PRIVATE pfv rout_table[] = { @@ -164,7 +163,7 @@ if (nocolonlabel) error(NEEDENDLABEL); #endif - if( label->value_reg_or_op.value != oldlabel) + if(pass && label->value_reg_or_op.value != oldlabel) { dirty_pass = TRUE; if( pass == last_pass ) @@ -246,21 +245,7 @@ labelerror(RELAB); label = symptr; -#if 0 -if(pass==last_pass) -{ - if( ((label->data^lcdata)&~FORBIT) || label->value_reg_or_op.value != lc) - { - printf("Movement %x:%d -> %x:%d\n", - label->data, - label->value_reg_or_op.value, - lcdata, - lc); - } -} -#endif - /* This is a bit dodgy, I think it's ok but ... */ - if (pass && (label->data & RELBIT)) + if (pass && !(symptr->type & VARBIT) /*&& last_pass>1*/) { label->data = (label->data & FORBIT) | lcdata; label->value_reg_or_op.value = lc; diff -Nurd linux86.old/as/error.c linux86/as/error.c --- linux86.old/as/error.c Sun Nov 10 11:45:34 1996 +++ linux86/as/error.c Tue Sep 26 20:52:45 2000 @@ -84,7 +84,7 @@ "illegal FP register pair", "junk after operands", "already defined", - "label moved in last pass, add -j?", + "label moved in last pass, add -O?", "instruction illegal for current cpu", "short branch would do", "unknown error", diff -Nurd linux86.old/as/genlist.c linux86/as/genlist.c --- linux86.old/as/genlist.c Mon Jan 4 14:38:03 1999 +++ linux86/as/genlist.c Sat Jun 17 11:23:51 2000 @@ -169,7 +169,7 @@ PUBLIC void listline() { - if (!listpre) + if (!listpre && lineptr != 0) { if (errcount || (list.current && (!macflag || mcount != 0)) || (macflag && maclist.current) || list_force ) diff -Nurd linux86.old/as/globvar.h linux86/as/globvar.h --- linux86.old/as/globvar.h Mon Jan 4 14:39:47 1999 +++ linux86/as/globvar.h Wed Sep 27 20:03:50 2000 @@ -65,6 +65,8 @@ /* FORBIT is set if lc is forward referenced */ /* RELBIT is is if lc is relocat. (not ASEG) */ EXTERN offset_t lcjump; /* lc jump between lines */ + +EXTERN offset_t oldlabel; /* Used for checking for moving labels */ #ifdef LOW_BYTE #define mcount (((unsigned char *) &lcjump)[LOW_BYTE]) /* low byte of lcjump */ diff -Nurd linux86.old/as/mops.c linux86/as/mops.c --- linux86.old/as/mops.c Mon Jul 26 14:28:00 1999 +++ linux86/as/mops.c Wed Sep 27 21:15:14 2000 @@ -1068,7 +1068,8 @@ if (!(lastexp.data & (RELBIT | UNDBIT))) { lastexp.offset = lastexp.offset - lc - lcjump; - if (backamount != 0x0 && !(lastexp.data & IMPBIT) && + if ( last_pass<2 && backamount != 0x0 && + !(lastexp.data & IMPBIT) && lastexp.offset + backamount < 0x80 + backamount) error(SHORTB); /* -0x8? to 0x7F, warning */ } @@ -1206,7 +1207,8 @@ else if (opcode == JMP_SHORT_OPCODE) { if (jumps_long && - (pass!=0 && !is8bitsignedoffset(lastexp.offset - lc - 2))) + ((pass!=0 && !is8bitsignedoffset(lastexp.offset - lc - 2)) || + (last_pass==1))) { opcode = JMP_OPCODE; lbranch(0x83); @@ -1945,7 +1947,8 @@ getea(&target); lastexp = target.displ; - if (pass!=0 && !is8bitsignedoffset(lastexp.offset - lc - 2)) + if ( (pass!=0 && !is8bitsignedoffset(lastexp.offset - lc - 2)) || + last_pass==1) { if (target.indcount >= 0x2 || target.base != NOREG) kgerror(REL_REQ); @@ -2749,7 +2752,7 @@ if (!(lastexp.data & (RELBIT | UNDBIT))) { lastexp.offset = lastexp.offset - lc - lcjump; - if (!(lastexp.data & IMPBIT) && + if ( last_pass<2 && !(lastexp.data & IMPBIT) && lastexp.offset + 0x81 < 0x101) error(SHORTB); /* -0x81 to 0x7F, warning */ } diff -Nurd linux86.old/as/pops.c linux86/as/pops.c --- linux86.old/as/pops.c Mon Jul 26 11:21:24 1999 +++ linux86/as/pops.c Fri Oct 27 09:00:01 2000 @@ -175,6 +175,12 @@ elseflag = FALSE; } } + else + { + /* Skip to EOL */ + while (sym != EOLSYM) + getsym(); + } } } @@ -213,6 +219,13 @@ labptr->data = lastexp.data; labptr->value_reg_or_op.value = lastexp.offset; showlabel(); + + if(pass && !(labits & VARBIT) && labptr->value_reg_or_op.value != oldlabel) + { + dirty_pass = TRUE; + if( pass == last_pass ) + error(UNSTABLE_LABEL); + } } /* common routine for ENTRY/EXPORT */ @@ -397,6 +410,12 @@ ifflag = FALSE; /* not assembling */ elseflag = TRUE;/* but ELSE will change that */ } + } + else + { + /* Skip to EOL */ + while (sym != EOLSYM) + getsym(); } } } diff -Nurd linux86.old/as/readsrc.c linux86/as/readsrc.c --- linux86.old/as/readsrc.c Thu Mar 18 07:07:35 1999 +++ linux86/as/readsrc.c Wed Sep 27 07:45:09 2000 @@ -15,7 +15,7 @@ /* * Ok, lots of hack & slash here. * 1) Added BIG buffer to load entire _primary_ file into memory. - * 2) This means primay file can be standard input. + * 2) This means the primary file can be standard input. * 3) Fixed so 'get/include' processing now works. * 4) Altered for a 'normal' style buffer otherwise (MINIBUF) * 5) Have the option of completely unbuffered if you need the last Kb. @@ -244,7 +244,7 @@ else if (pass!=last_pass) { pass++; - if( last_pass>2 && last_pass<30 && dirty_pass && pass==last_pass ) + if( last_pass>1 && last_pass<30 && dirty_pass && pass==last_pass ) last_pass++; if( pass==last_pass ) diff -Nurd linux86.old/bcc/Makefile linux86/bcc/Makefile --- linux86.old/bcc/Makefile Fri Jul 31 11:02:34 1998 +++ linux86/bcc/Makefile Sat Jan 6 09:55:53 2001 @@ -26,16 +26,16 @@ install -m 755 bcc-cc1 $(LIBDIR)/bcc-cc1 bcc: bcc.c - $(CC) $(ANSI) $(CFLAGS) $(BCCDEFS) $(LDFLAGS) bcc.c -o $@ + $(CC) $(ANSI) $(CFLAGS) $(BCCDEFS) $(LDFLAGS) $^ -o $@ ncc: bcc.c - $(CC) $(ANSI) $(CFLAGS) -DL_TREE -DDEFARCH=0 $(LDFLAGS) bcc.c -o $@ + $(CC) $(ANSI) $(CFLAGS) -DL_TREE -DDEFARCH=0 $(LDFLAGS) $^ -o $@ bcc09: bcc.c - $(CC) $(ANSI) $(CFLAGS) -DMC6809 $(BCCDEFS) $(LDFLAGS) bcc.c -o $@ + $(CC) $(ANSI) $(CFLAGS) -DMC6809 $(BCCDEFS) $(LDFLAGS) $^ -o $@ ccc: bcc.c - $(CC) $(ANSI) $(CFLAGS) -DCCC $(BCCDEFS) $(LDFLAGS) bcc.c -o $@ + $(CC) $(ANSI) $(CFLAGS) -DCCC $(BCCDEFS) $(LDFLAGS) $^ -o $@ bcc-cc1: $(OBJS) $(CC) $(BCCARCH) $(LDFLAGS) $(OBJS) -o bcc-cc1 diff -Nurd linux86.old/bcc/bcc.c linux86/bcc/bcc.c --- linux86.old/bcc/bcc.c Sat Feb 7 11:01:44 1998 +++ linux86/bcc/bcc.c Wed Sep 27 21:43:51 2000 @@ -572,6 +572,8 @@ addarg(&ldargs, DEFAULT_LIBDIR0); } + if (optimize) + addarg(&asargs, "-O"); addarg(&optargs, OPTIM_RULES); temp=optflags; optflags=stralloc2(optflags,",end"); free(temp); for(temp=strtok(optflags,","); temp; temp=strtok((char*)0,",")) diff -Nurd linux86.old/bin86/ChangeLog linux86/bin86/ChangeLog --- linux86.old/bin86/ChangeLog Fri Jun 11 13:10:43 1999 +++ linux86/bin86/ChangeLog Tue May 22 09:26:11 2001 @@ -1,3 +1,12 @@ + +This file is NOT the current changelog. +Please see the Changes file in the directory above +(the main directory of the Dev86 package). + + Robert de Bath. + + + Fri Jun 11 13:08:27 BST 1999 Robert de Bath (rdebath@poboxes.com) * objdump86 program included. diff -Nurd linux86.old/bin86/Makefile linux86/bin86/Makefile --- linux86.old/bin86/Makefile Sun Aug 1 19:41:25 1999 +++ linux86/bin86/Makefile Fri May 4 09:40:18 2001 @@ -9,6 +9,7 @@ MANDIR=$(PREFIX)/man/man1 SUF=86 +INSTALL_OPT=-m 755 INSTALL_OPTS=-m 755 -s MAN_OPTS =-m 644 @@ -26,7 +27,7 @@ install: all install $(INSTALL_OPTS) as/as86 $(BINDIR)/as$(SUF) - install $(INSTALL_OPTS) as/as86_encap $(BINDIR)/as$(SUF)_encap + install $(INSTALL_OPT) as/as86_encap $(BINDIR)/as$(SUF)_encap install $(INSTALL_OPTS) ld/ld86 $(BINDIR)/ld$(SUF) install $(INSTALL_OPTS) ld/objdump86 $(BINDIR)/objdump$(SUF) install $(MAN_OPTS) man/*.1 $(MANDIR) diff -Nurd linux86.old/bootblocks/Makefile linux86/bootblocks/Makefile --- linux86.old/bootblocks/Makefile Fri Jun 18 17:09:43 1999 +++ linux86/bootblocks/Makefile Sat May 12 09:17:53 2001 @@ -4,7 +4,7 @@ BCC=bcc CC=$(BCC) -CFLAGS=-ansi -Ms -Oi -O -s $(MONDEFS) +CFLAGS=-ansi -Ms -Oi -O -s # CFLAGS=-ansi -Ms ASFLAGS=-0 -w MINIXDEFS=-DDOTS @@ -12,15 +12,17 @@ # LST=-l $*.lst # CLST=-A-l -A$*.lst -default: makeboot makeboot.com monitor.out minix_elks.bin +default: makeboot makeboot.com monitor.out minix_elks.bin lsys.com -all: default tgz bin minix_elks.bin +all: bootbin bootsys default tgz + +bootsys: bootfile.sys boottar.sys bootminix.sys CSRC=minix.c SSRC=sysboot.s tarboot.s skip.s com_bcc.s tich.s mbr.s msdos.s noboot.s encap: $(SSRC:s=v) $(CSRC:c=v) minixhd.v msdos16.v -bin: $(SSRC:s=bin) $(CSRC:c=bin) minixhd.bin msdos16.bin +bootbin: $(SSRC:s=bin) $(CSRC:c=bin) minixhd.bin msdos16.bin minix_elks.bin MOBJ=monitor.o commands.o i86_funcs.o relocate.o help.o bzimage.o \ trk_buf.o min_buf.o unix.o fs.o fs_tar.o fs_min.o fs_dos.o cprintf.o @@ -37,14 +39,32 @@ install: monitor.out: $(MOBJ) - $(CC) $(CFLAGS) -H0x10000 $(MOBJ) -o monitor.out -M > monitor.sym + $(CC) $(CFLAGS) $(MONDEFS) -H0x10000 $(MOBJ) -o monitor.out -M > monitor.sym $(MOBJ): $(MINC) version.h fs_min.o: minix.h +bootfile.sys: $(MSRC) $(MINC) + @rm -f $(MOBJ) + make 'CFLAGS=$(CFLAGS) -DDOSFLOPPY -i-' monitor.out + mv monitor.out bootfile.sys + @rm -f $(MOBJ) + +boottar.sys: $(MSRC) $(MINC) tarboot.bin + @rm -f $(MOBJ) + make 'CFLAGS=$(CFLAGS) -DTARFLOPPY -i-' monitor.out + mv monitor.out boottar.sys + @rm -f $(MOBJ) + +bootminix.sys: $(MSRC) $(MINC) tarboot.bin + @rm -f $(MOBJ) + make 'CFLAGS=$(CFLAGS) -DMINFLOPPY -i-' monitor.out + mv monitor.out bootminix.sys + @rm -f $(MOBJ) + monitor: $(MSRC) $(MINC) @rm -f $(MOBJ) - make 'CFLAGS=-ansi -H0x8000 $(MONDEFS)' monitor.out + make 'CFLAGS=-ansi -H0x8000' monitor.out mv monitor.out monitor @rm -f $(MOBJ) @@ -76,6 +96,7 @@ sed 's/\(.*\)/#define VERSION "\1"/' > version.h clean realclean: + rm -f bootfile.sys boottar.sys bootminix.sys rm -f monitor makeboot bootblocks.tar.gz rm -f minix.s minixhd.s minix_elks.s version.h msdos16.s rm -f *.com *.o *.bin *.out *.lst *.sym *.v *.tmp diff -Nurd linux86.old/bootblocks/bzimage.c linux86/bootblocks/bzimage.c --- linux86.old/bootblocks/bzimage.c Mon Jun 14 14:05:27 1999 +++ linux86/bootblocks/bzimage.c Sun Jun 18 19:55:44 2000 @@ -3,6 +3,7 @@ * friends use. */ +#define __MINI_MALLOC__ #include "monitor.h" int auto_flag = 1; @@ -105,6 +106,10 @@ } if( main_mem_top < 3072 ) printf("RTFM warning: Linux needs at least 4MB of memory.\n"); + + len = (len+1023)/1024+1; /* Where to load the RD image (Mb) */ + if (len<6) len=6; /* Default to 6Mb mark */ + initrd_start = len * 4096; /* 256 bytes pages. */ #endif low_sects = buffer[497] + 1; /* setup sects + boot sector */ @@ -551,6 +556,15 @@ if( strncasecmp(s+4, "ask", 3) == 0 ) vga_mode = -3; else + if( strncasecmp(s+4, "ext", 3) == 0 ) + vga_mode = -2; + else + if( strncasecmp(s+4, "nor", 3) == 0 ) + vga_mode = -1; + else + if( strncasecmp(s+4, "cur", 3) == 0 ) + vga_mode = 0x0f04; + else { s+=4; getnum(&s, &vga_mode); } @@ -662,6 +676,8 @@ rd_start = address - rd_len*4; rd_start &= -16; /* Page boundry */ + if (initrd_start && initrd_startfstype) { case FS_NONE: /* override */ - break; - case FS_DOS: case FS_STAT: + case FS_ADOS: + break; + case FS_DOS: check_msdos(); if(ptr->fsmod) check_simpledos(ptr->fsmod); break; @@ -145,12 +152,14 @@ switch(ptr->fstype) { case FS_STAT: - print_super(buffer); if( strcmp(ptr->name, "copy") == 0 ) save_super(buffer); + else + print_super(buffer); close_disk(); exit(0); case FS_DOS: + case FS_ADOS: for(i=0; idata[i]; for(i=sysboot_codestart; i<512; i++) @@ -186,7 +195,7 @@ set_asciz(ptr->boot_name); break; default: - fprintf(stderr, "Cannot specify boot file for this block\n"); + fprintf(stderr, "Cannot specify boot name for this block\n"); exit(1); } @@ -212,11 +221,12 @@ progname = "makeboot"; #ifdef __MSDOS__ - fprintf(stderr, "Usage: %s [-f] bootblock[=bootname] a:\n", progname); + fprintf(stderr, "Usage: %s [-f] bootblock[=bootname] a:\n\n", progname); + fprintf(stderr, "The 'a:' can be any drive or file or @: for the MBR.\n"); #else - fprintf(stderr, "Usage: %s [-f] bootblock[=bootname] /dev/fd0\n", progname); + fprintf(stderr, "Usage: %s [-f] bootblock[=bootname] /dev/fd0\n\n", progname); #endif - fprintf(stderr, "\nThe bootname is a filename to use with the block,\n"); + fprintf(stderr, "The bootname is a filename or message to use with the block,\n"); fprintf(stderr, "the blocks are:\n"); for(;ptr->name; ptr++) fprintf(stderr, "\t%s\t%s\n", ptr->name, ptr->desc); @@ -233,14 +243,22 @@ /* Freedos fix */ if( diskname[2] == '\r' ) diskname[2] = 0; - if( strcmp("a:", diskname) == 0 ) { disktype = 1; return 0; } - if( strcmp("b:", diskname) == 0 ) { disktype = 2; return 0; } - if( strcmp("A:", diskname) == 0 ) { disktype = 1; return 0; } - if( strcmp("B:", diskname) == 0 ) { disktype = 2; return 0; } + if( diskname[2] == 0 && diskname[1] == ':' ) + { + if (isalpha(diskname[0])) { + disktype = toupper(diskname[0])-'A'+1; + return 0; + } + if (diskname[0] =='@') { + disktype = 129; + return 0; + } + } #endif disktype = 0; - diskfd = fopen(diskname, "r+"); - if( diskfd == 0 ) diskfd = fopen(diskname, "r"); + diskfd = fopen(diskname, "r+b"); + if( diskfd == 0 ) diskfd = fopen(diskname, "rb"); + if( diskfd == 0 && force ) diskfd = fopen(diskname, "w+b"); if( diskfd == 0 ) { fprintf(stderr, "Cannot open '%s'\n", diskname); @@ -262,7 +280,7 @@ char * loadaddr; { #ifdef __MSDOS__ - if( disktype == 1 || disktype == 2 ) + if( disktype == 1 || disktype == 2 || disktype == 129 ) { int tries, rv; int s,h,c; @@ -271,11 +289,29 @@ c = sectno/disk_sect/disk_head; for(tries=0; tries<6; tries++) - if( (rv = dos_sect_write(disktype-1, c, h, s, loadaddr)) == 0 ) + if( (rv = bios_sect_write(disktype-1, c, h, s, loadaddr)) == 0 ) break; if( rv ) { - fprintf(stderr, "Error writing sector %d, (%d)\n", sectno, rv/256); + if (rv/256 == 3) + fprintf(stderr, "Write protect error writing sector %d\n", sectno); + else + fprintf(stderr, "Error writing sector %d, (%d)\n", sectno, rv/256); + return -1; + } + return 0; + } + if( disktype ) + { + int tries, rv; + + for(tries=0; tries<6; tries++) + if( (rv = dos_sect_write(disktype-1, sectno, loadaddr)) == 0 ) + break; + if( rv ) + { + fprintf(stderr, "Error writing sector %d, (0x%04d)\n", sectno, rv); + memset(loadaddr, '\0', 512); return -1; } return 0; @@ -303,7 +339,7 @@ { int cc; #ifdef __MSDOS__ - if( disktype == 1 || disktype == 2 ) + if( disktype == 1 || disktype == 2 || disktype == 129 ) { int tries, rv; int s,h,c; @@ -312,7 +348,7 @@ c = sectno/disk_sect/disk_head; for(tries=0; tries<6; tries++) - if( (rv = dos_sect_read(disktype-1, c, h, s, loadaddr)) == 0 ) + if( (rv = bios_sect_read(disktype-1, c, h, s, loadaddr)) == 0 ) break; if( rv ) { @@ -322,6 +358,21 @@ } return 0; } + if( disktype ) + { + int tries, rv; + + for(tries=0; tries<6; tries++) + if( (rv = dos_sect_read(disktype-1, sectno, loadaddr)) == 0 ) + break; + if( rv ) + { + fprintf(stderr, "Error reading sector %d, (0x%04d)\n", sectno, rv); + memset(loadaddr, '\0', 512); + return -1; + } + return 0; + } #endif if( disktype ) { @@ -337,10 +388,11 @@ } return 0; } + /**************************************************************************/ #ifdef __MSDOS__ -dos_sect_read(drv, track, head, sector, loadaddr) +bios_sect_read(drv, track, head, sector, loadaddr) { #asm push bp @@ -349,26 +401,24 @@ push ds pop es - mov dh,[bp+2+_dos_sect_read.head] - mov dl,[bp+2+_dos_sect_read.drv] - mov cl,[bp+2+_dos_sect_read.sector] - mov ch,[bp+2+_dos_sect_read.track] + mov dh,[bp+2+_bios_sect_read.head] + mov dl,[bp+2+_bios_sect_read.drv] + mov cl,[bp+2+_bios_sect_read.sector] + mov ch,[bp+2+_bios_sect_read.track] - mov bx,[bp+2+_dos_sect_read.loadaddr] + mov bx,[bp+2+_bios_sect_read.loadaddr] mov ax,#$0201 int $13 - jc read_err + jc bios_read_err mov ax,#0 -read_err: +bios_read_err: pop bp #endasm } -#endif -#ifdef __MSDOS__ -dos_sect_write(drv, track, head, sector, loadaddr) +bios_sect_write(drv, track, head, sector, loadaddr) { #asm push bp @@ -377,18 +427,18 @@ push ds pop es - mov dh,[bp+2+_dos_sect_write.head] - mov dl,[bp+2+_dos_sect_write.drv] - mov cl,[bp+2+_dos_sect_write.sector] - mov ch,[bp+2+_dos_sect_write.track] + mov dh,[bp+2+_bios_sect_write.head] + mov dl,[bp+2+_bios_sect_write.drv] + mov cl,[bp+2+_bios_sect_write.sector] + mov ch,[bp+2+_bios_sect_write.track] - mov bx,[bp+2+_dos_sect_write.loadaddr] + mov bx,[bp+2+_bios_sect_write.loadaddr] mov ax,#$0301 int $13 - jc write_err + jc bios_write_err mov ax,#0 -write_err: +bios_write_err: pop bp #endasm @@ -397,6 +447,112 @@ /**************************************************************************/ +#ifdef __MSDOS__ + +/* All this mess just to read one sector!! */ + +struct disk_packet { + long sector; + int count; + long addr; +} disk_packet; + +dos_sect_read(drv, sector, loadaddr) +{ +#asm + push bp + mov bp,sp + + mov al,[bp+2+_dos_sect_read.drv] + mov cx,#1 + mov dx,[bp+2+_dos_sect_read.sector] + mov bx,[bp+2+_dos_sect_read.loadaddr] + + int $25 + pop bx + jnc dos_read_ok + + mov bp,sp + + ! Fill the disk packet + mov ax,[bp+2+_dos_sect_read.sector] + mov [_disk_packet],ax + xor ax,ax + mov [_disk_packet+2],ax + inc ax + mov [_disk_packet+4],ax + mov ax,[bp+2+_dos_sect_read.loadaddr] + mov [_disk_packet+6],ax + mov ax,ds + mov [_disk_packet+8],ax + + mov dl,[bp+2+_dos_sect_read.drv] + inc dl + mov bx,#_disk_packet + mov cx,#0xFFFF + mov si,#0 + mov ax,#0x7305 + + int $21 + + jc dos_read_err +dos_read_ok: + mov ax,#0 +dos_read_err: + + pop bp +#endasm +} + +dos_sect_write(drv, sector, loadaddr) +{ +#asm + push bp + mov bp,sp + + mov al,[bp+2+_dos_sect_write.drv] + mov cx,#1 + mov dx,[bp+2+_dos_sect_write.sector] + mov bx,[bp+2+_dos_sect_write.loadaddr] + + int $26 + pop bx + jnc dos_write_ok + + mov bp,sp + + ! Fill the disk packet + mov ax,[bp+2+_dos_sect_write.sector] + mov [_disk_packet],ax + xor ax,ax + mov [_disk_packet+2],ax + inc ax + mov [_disk_packet+4],ax + mov ax,[bp+2+_dos_sect_write.loadaddr] + mov [_disk_packet+6],ax + mov ax,ds + mov [_disk_packet+8],ax + + mov dl,[bp+2+_dos_sect_write.drv] + inc dl + mov bx,#_disk_packet + mov cx,#0xFFFF + mov si,#1 + mov ax,#0x7305 + + int $21 + + jc dos_write_err +dos_write_ok: + mov ax,#0 +dos_write_err: + + pop bp +#endasm +} +#endif +/**************************************************************************/ + check_zapped() { int i; @@ -551,12 +707,21 @@ #define DOS_SPT 9 #define DOS_HEADS 10 #define DOS_HIDDEN 11 + #define DOS4_MAXSECT 12 #define DOS4_PHY_DRIVE 13 #define DOS4_SERIAL 14 #define DOS4_LABEL 15 #define DOS4_FATTYPE 16 +#define DOS7_MAXSECT 17 +#define DOS7_FAT32LEN 18 +#define DOS7_FLAGS 19 +#define DOS7_VERSION 20 +#define DOS7_ROOT_CLUST 21 +#define DOS7_INFO_SECT 22 +#define DOS7_BOOT2 23 + struct bootfields { int offset; int length; @@ -577,11 +742,21 @@ { 0x18, 2, 0}, { 0x1A, 2, 0}, { 0x1C, 4, 0}, - { 0x20, 4, 0}, + + { 0x20, 4, 0}, /* DOS4+ */ { 0x24, 1, 0}, { 0x27, 4, 0}, { 0x2B, 11, 0}, { 0x36, 8, 0}, + + { 0x20, 4, 0}, /* DOS7 FAT32 */ + { 0x24, 4, 0}, + { 0x28, 2, 0}, + { 0x2A, 2, 0}, + { 0x2C, 4, 0}, + { 0x30, 2, 0}, + { 0x32, 2, 0}, + { -1,0,0} }; @@ -595,24 +770,39 @@ "Reserved sectors", "FAT count", "Root dir entries", - "Sector count (=0 if large FS)", + "Sector count", "Media code", "FAT length", "Sect/Track", "Heads", "Hidden sectors (Partition offset)", + "Large FS sector count", "Phys drive", "Serial number", "Disk Label (DOS 4+)", "FAT type", + + "FAT32 FS sector count", + "FAT32 FAT length", + "FAT32 Flags", + "FAT32 version", + "FAT32 Root Cluster", + "FAT32 Info Sector", + "FAT32 Backup Boot", + 0 }; int i; + long numclust = 0xFFFF; + int fatbits = 0; + int fat_len = -1; for(i=0; dosflds[i].offset >= 0; i++) { - printf("%-35s", fieldnames[i]); + if( i>= DOS4_MAXSECT && (fat_len==0) != (i>=DOS7_MAXSECT) ) + continue; + if( dosflds[i].length <= 4 ) { long v = 0; int j; @@ -620,11 +810,23 @@ { v = v*256 + (0xFF&( bootsect[dosflds[i].offset+j] )); } - printf("%ld\n", v); + + if( i==DOS_FATLEN ) + fat_len = v; + + if (v==0 && + (i==DOS_FATLEN || i==DOS_MAXSECT || i==DOS4_MAXSECT || i==DOS_NROOT)) + continue; + + printf("%-35s%ld\n", fieldnames[i], v); + + if (i==DOS_SECT && v!=512 && v!=1024 && v!=2048) + break; } else { int ch, j; + printf("%-35s", fieldnames[i]); for(j=0; j= 0; i++) { + if( i>= DOS4_MAXSECT && + (dosflds[DOS_FATLEN].value==0) != (i>=DOS7_MAXSECT) ) + { + dosflds[i].lvalue = dosflds[i].value = 0; + continue; + } + if( dosflds[i].length <= 4 ) { long v = 0; int j; @@ -654,7 +863,7 @@ dosflds[i].lvalue = v; } else - dosflds[i].value = 0; + dosflds[i].lvalue = dosflds[i].value = 0; } } @@ -680,7 +889,10 @@ dosflds[DOS_CLUST].value = 1; if( dosflds[DOS_MEDIA].value < 0xF0 ) - fprintf(stderr, "Dos media descriptor is invalid\n"); + { + if (!force) + fprintf(stderr, "Dos media descriptor is invalid\n"); + } else if( dosflds[DOS_MEDIA].value != (0xFF&buffer[512]) && dosflds[DOS_RESV].value == 1 ) fprintf(stderr, "Dos media descriptor check failed\n"); @@ -728,7 +940,7 @@ check_simpledos(bb_fatbits) int bb_fatbits; { - unsigned numclust = 0xFFFF; + long numclust = 0xFFFF; char * err = 0; int fatbits = 0; @@ -739,19 +951,24 @@ - dosflds[DOS_NFAT].value * dosflds[DOS_FATLEN].value - ((dosflds[DOS_NROOT].value+15)/16) ) / dosflds[DOS_CLUST].value + 2; - else + else if( dosflds[DOS4_MAXSECT].value > 0 ) numclust = ( dosflds[DOS4_MAXSECT].lvalue - dosflds[DOS_RESV].value - dosflds[DOS_NFAT].value * dosflds[DOS_FATLEN].value - ((dosflds[DOS_NROOT].value+15)/16) ) / dosflds[DOS_CLUST].value + 2; + else + numclust = ( dosflds[DOS7_MAXSECT].lvalue + - dosflds[DOS_RESV].value + - dosflds[DOS_NFAT].value * dosflds[DOS7_FAT32LEN].value + ) / dosflds[DOS_CLUST].value; if( memcmp(buffer+dosflds[DOS4_FATTYPE].offset, "FAT12", 5) == 0 ) fatbits=12; else if( memcmp(buffer+dosflds[DOS4_FATTYPE].offset, "FAT16", 5) == 0 ) fatbits=16; else - fatbits=12+4*(numclust > 0xFF0); + fatbits=12+4*(numclust > 0xFF0) + 16*(numclust > 0xFFF0L); if( dosflds[DOS_NFAT].value > 2 ) err = "Too many fat copies on disk"; @@ -759,15 +976,19 @@ err = "Root directory has unreasonable size."; else if( dosflds[DOS_SECT].value != 512 ) err = "Drive sector size isn't 512 bytes sorry no-go."; + else if( fatbits == 16 && numclust < 0xFF0 ) + err = "Weirdness, FAT16 but less than $FF0 clusters"; else if( fatbits != bb_fatbits ) err = "Filesystem has the wrong fat type for this bootblock."; else if( numclust * dosflds[DOS_CLUST].lvalue / dosflds[DOS_SPT].value > 65535 ) - err = "Maximum of 65535 tracks allowed, sorry"; + err = "Boot sector untested with more than 65535 tracks"; if( !err && bb_fatbits == 12 ) { - if( (0x7C00-msdos_start-512)/512 < dosflds[DOS_FATLEN].value ) + if( dosflds[DOS4_PHY_DRIVE].value != 0 ) + err = "This boot sector is only for floppies"; + else if( (0x7C00-msdos_start-512)/512 < dosflds[DOS_FATLEN].value ) err = "The FAT is too large to load in the available space."; else if( dosflds[DOS_RESV].value + dosflds[DOS_FATLEN].value > dosflds[DOS_SPT].value ) @@ -819,7 +1040,7 @@ if( strlen(boot_id) > i ) { - fprintf(stderr, "Filename '%s' is too long for bootblock\n"); + fprintf(stderr, "Name '%s' is too long for bootblock\n"); exit(1); } else @@ -840,6 +1061,10 @@ default: buffer[j++] = boot_id[i]; break; } } +#ifdef __MSDOS__ + else if(boot_id[i] == '_') buffer[j++] = ' '; + else if(boot_id[i] == '^') { buffer[j++] = '\r'; buffer[j++] = '\n'; } +#endif else buffer[j++] = boot_id[i]; } buffer[j] = 0; @@ -857,28 +1082,37 @@ if( buffer[i] ) break; + /* Check for Disk Manager partition tables */ + if( buffer[252] == 0xAA && buffer[253] == 0x55 ) + { + if( (unsigned char)mbr_data[252] != 0xAA || mbr_data[253] != 0x55 ) + i = 252; + } + if( i != 512 ) { if(force) - fprintf(stderr, "That doesn't look like an MBR zapping\n"); + fprintf(stderr, "That doesn't look like a compatible MBR but ...\n"); else { - fprintf(stderr, "That doesn't look like an MBR, -f will zap\n"); + fprintf(stderr, "That doesn't look like a compatible MBR\n"); exit(1); } - - memset(buffer, '\0', 512); } } copy_mbr(mbr_data) char * mbr_data; { - if( buffer[252] != 0xAA || buffer[253] != 0x55 ) + if( buffer[252] != 0xAA || buffer[253] != 0x55 || + (unsigned char)mbr_data[252] != 0xAA || mbr_data[253] != 0x55 ) memcpy(buffer, mbr_data, 446); else memcpy(buffer, mbr_data, 254); - memcpy(buffer+510, mbr_data+510, 2); + + buffer[510] = 0x55; + buffer[511] = 0xAA; + write_zero = 1; } /**************************************************************************/ @@ -1142,7 +1376,7 @@ #ifdef HAS_2M20 else if( disk_trck != 82 || disk_sect != 22 ) { - fprintf(stderr, "To be bootable a 2M disk must be 22 sectors 82 tracks or formatted with 2m20.\n"); + fprintf(stderr, "To be bootable a 2M disk must be 22 sectors 82 tracks or formatted with DOS 2m.\n"); if( !force ) exit(1); fprintf(stderr, "But I'll try it\n"); } @@ -1166,7 +1400,7 @@ write_sector(bs_offset+i/512+1, program_2m_vsn_20+i); } #else - fprintf(stderr, "To be bootable a 2M disk must be formatted with the 2m20 device driver.\n"); + fprintf(stderr, "To be bootable a 2M disk must be formatted with the DOS 2m driver.\n"); exit(1); #endif } diff -Nurd linux86.old/bootblocks/mbr.s linux86/bootblocks/mbr.s --- linux86.old/bootblocks/mbr.s Mon Dec 28 14:40:57 1998 +++ linux86/bootblocks/mbr.s Tue Sep 26 20:20:18 2000 @@ -3,37 +3,38 @@ ! This BB successfully boots MSDOS or Linux. ! ! In addition it has the facility to load and execute a small program -! (of 8 extents) before the boot blocks are checked. +! before the boot blocks are checked. ! ! Or ! -! Space for 12 extra partitions in a form that Linux _does_ understand. +! Space for 12 extra partitions in the 'DiskManager' form that Linux +! _does_ understand. ! +! NB: This needs Dev86 0.15.2 or later ! Lowest available is $0500, MSDOS appears to use $0600 ... I wonder why? ORGADDR=$0500 preboot=0 ! Include the pre-boot loader. -diskman=1 ! Disk manager partitions, allows 16 partitions but +mbrkey=0 ! Option to choose the boot record base on keystroke +message=0 ! Display boot message +diskman=0 ! Disk manager partitions, allows 16 partitions but ! don't overwrite this with a LILO BB. -! Include standard layout -org ORGADDR -include sysboot.s - -public partition_1 -public partition_2 -public partition_3 -public partition_4 +linear=0 ! Use the linear addresses not the CHS ones - if diskman=0 -org ORGADDR+$3 -.ascii "ELKS MBR Copyright 1996, Robert de Bath" +partition_start=ORGADDR+0x1BE +partition_size=0x10 +partition_end=ORGADDR+0x1FE -! Start after dos fsstat data, not strictly required. -org codestart + if diskman + ! Partition table start ... + table_start=ORGADDR+0xFC + low_partition=table_start+2 else -org ORGADDR + table_start=partition_start endif + +org ORGADDR cli ! Assume _nothing_! cld mov bx,#$7C00 ! Pointer to start of BB. @@ -51,52 +52,38 @@ cont: sti ! Let the interrupts back in. -! -! Next check for a pre-boot load. - +! Next check for a pre-boot load or a keypress + if message + call disp_message + endif if preboot - push bx - mov si,#pre_boot_table - lodsw - mov di,ax ! First word is execute address -more_boot: - lodsw - test ax,ax - jz load_done - mov bx,ax ! word 1 address - lodsw - mov cx,ax ! word 2 CX, head/sector - lodsw - mov dx,ax ! word 3 DX, drive, cylinder - lodsw ! word 4 AX, $02, sector count - int $13 - jnc more_boot ! This doesn't retry, with a HD it shouldn't be bad. - jc disk_error -load_done: - call di -exec_done: - pop bx + call preboot_code + endif + if mbrkey + call key_wait endif ! Now check the partition table, must use SI as pointer cause that's what the ! partition boot blocks expect. - mov si,#partition_1 + mov si,#partition_start check_active: cmp byte [si],#$80 ! Flag for activated partition jz found_active + if mbrkey=0 bad_boot: - add si,#partition_2-partition_1 - cmp si,#bootblock_magic + endif + add si,#partition_size + cmp si,#partition_end jnz check_active - ! Check for Disk manager partitions (12 more!) + ! Check for Disk manager partitions in the order that Linux numbers them. if diskman cmp word ptr diskman_magic,#$55AA jnz no_diskman - mov si,#partition_1 + mov si,#partition_start check_next: - sub si,#partition_2-partition_1 + sub si,#partition_size cmp byte [si],#$80 ! Flag for activated partition jz found_active cmp si,#low_partition @@ -109,10 +96,14 @@ jmp no_boot found_active: + if linear + call linearise + else mov di,#6 ! Max retries, int list says 3 ... double it mov dx,[si] ! dh = Drive head, dl = $80 ie HD drive 0 mov cx,[si+2] ! cx = Sector & head encoded for int $13 - ! bx is correct + ! bx is correct at $7C00 + endif retry: movb [$7DFE],#0 ! Clear magic for dosemu mov ax,#$0201 ! Read 1 sector @@ -126,9 +117,8 @@ dec di jnz retry ! Try again -disk_error: mov si,#disk_read_error - jmp no_boot ! Sorry it ain't gonna work. + jmp no_boot ! Sorry it ain't gonna work. sector_loaded: mov di,#$7DFE ! End of sector loaded @@ -139,6 +129,19 @@ jmpi #$7C00,#0 ! Go! ! Fatal errors ........... + if mbrkey +bad_boot: + mov si,#no_bootpart +no_boot: ! SI now has pointer to error message + call puts + mov si,#crlf + call puts +tick: + call key_wait + j tick + + else + no_boot: ! SI now has pointer to error message lodsb cmp al,#0 @@ -156,65 +159,242 @@ keyboot: ! Wait for a key then reboot xor ax,ax int $16 - int $19 ! This should be OK as we haven't touched anything. +! int $19 ! This rarely does anything useful... jmpi $0,$FFFF ! Wam! Try or die! -no_bootpart: - .asciz "No bootable partition" -disk_read_error: - .asciz "Error loading system" press_key: - .asciz "\r\nPress a key to reboot" + .asciz "\r\nPress return:" press_end: + endif + +no_bootpart: + .asciz "No active partition" +disk_read_error: + .asciz "Disk read error" + +!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +! Instead of loading using the CHS data in the ptbl use the linear addr +! + if linear +linearise: + mov di,#6 ! Max retries, int list says 3 ... double it + mov dx,[si] ! dh = Drive head, dl = $80 ie HD drive 0 + mov cx,[si+2] ! cx = Sector & head encoded for int $13 + ! bx is correct at $7C00 + + fail! Todo ... + ret + endif + +!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +! Choose the partition based on a pressed key ... + + if mbrkey +key_wait: + mov si,#Prompt + call puts + mov di,#19 ! Wait for 18-19 ticks + +next_loop: + mov ah,#1 + int $16 + jnz Got_key + mov ah,#0 + int $1A ! Get current tick + cmp dx,si ! If changed DEC our counter. + jz next_loop + mov si,dx + dec di + jnz next_loop + + mov si,#Unprompt ! Nothing has happened, return. + call puts + +bad_key: + ret + +Got_key: + cmp al,#$20 + jnz not_space + mov si,#Pause + j showit +not_space: + mov Showkey,al + mov si,#Showkey +showit: + call puts + + mov ah,#0 ! Clean the kbd buffer. + int $16 + + ! ... Now we use our key ... + ! 0 => Floppy + ! 1 .. 4 => Hard disk partition. + + mov di,#-1 + cmp al,#$20 + jz next_loop + + and ax,#0xF + + jnz not_floppy + mov si,#floppy_part + br found_active + +not_floppy: + dec ax + test ax,#0xC + jnz bad_key + + mov cl,#4 + shl ax,cl + add ax,#partition_start + mov si,ax + +! Set active flag for disk interrupt. + or byte [si],#$80 + + br found_active + +puts: + lodsb + cmp al,#0 + jz EOS + push bx + mov bx,#7 + mov ah,#$E ! Can't use $13 cause that's AT+ only! + int $10 + pop bx + jmp puts +EOS: + ret + +Prompt: + .asciz "MBR: " +Unprompt: + .asciz "\b\b\b\b\b \b\b\b\b\b" +Pause: + .asciz "\b\b> " +Showkey: + .ascii " " +crlf: + .asciz "\r\n" +floppy_part: + .word 0,1 + + endif + +!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +! + if message +disp_message: + mov si,#Banner + if mbrkey + br puts + else + +puts: + lodsb + cmp al,#0 + jz .EOS + push bx + mov bx,#7 + mov ah,#$E ! Can't use $13 cause that's AT+ only! + int $10 + pop bx + jmp puts +.EOS: + ret + endif +export Banner +Banner: + .asciz "" + endif +!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +! This is the pre-boot loader it uses CHS but that's ok for track 0 +! if preboot +public preboot_code +preboot_code: + push bx + mov si,#pre_boot_table + lodsw + mov di,ax ! First word is execute address +more_boot: + lodsw + test ah,ah + jz load_done + mov bx,ax ! word 1 address + lodsw + mov cx,ax ! word 2 CX, head/sector + lodsw + mov dx,ax ! word 3 DX, drive, cylinder + lodsw ! word 4 AX, $02, sector count + int $13 + jnc more_boot ! This doesn't retry, with a HD it shouldn't be bad. + + mov si,#disk_read_error + br no_boot ! Sorry it ain't gonna work. +load_done: + call di +exec_done: + pop bx + return: ret export pre_boot_table pre_boot_table: + ! Example: Do nothing. + .word return,0 + + ! Labels + ! .word + ! Then repeat .. + ! .word , , , + ! Finally + ! .word 0 + ! Example: Load rest of H0,C0 into mem at $7C00 (8k). - ! .word $7C00, $7C00,$0002,$0000,$0210, $0000 - .word return - .word 0 + ! .word $7C00, $7C00,$0002,$8000,$0210, $0000 + + ! Example: Use single LBA call + ! .word + ! .word 0,0,$8000,$4200, $0010 + ! .word + ! .long + ! .long + ! .long endif - if diskman +!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +! Now make sure this isn't too big! + if *>table_start + fail! Partition table overlaps + endif +!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +! The diskman magic number and empty DM partitions. + if diskman org ORGADDR+0xFC public diskman_magic diskman_magic: .word 0xAA55 -low_partition: -public partition_16 -partition_16 = low_partition+0x00 -public partition_15 -partition_15 = low_partition+0x10 -public partition_14 -partition_14 = low_partition+0x20 -public partition_13 -partition_13 = low_partition+0x30 -public partition_12 -partition_12 = low_partition+0x40 -public partition_11 -partition_11 = low_partition+0x50 -public partition_10 -partition_10 = low_partition+0x60 -public partition_9 -partition_9 = low_partition+0x70 -public partition_8 -partition_8 = low_partition+0x80 -public partition_7 -partition_7 = low_partition+0x90 -public partition_6 -partition_6 = low_partition+0xA0 -public partition_5 -partition_5 = low_partition+0xB0 + .blkb 12*partition_size-1 + .byte 0 + endif + +!-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +! And finally a copyright message if there's room. + if *partition_1 - fail! Partition overlap - endif !THE END diff -Nurd linux86.old/bootblocks/min_buf.c linux86/bootblocks/min_buf.c --- linux86.old/bootblocks/min_buf.c Fri Jun 4 13:31:39 1999 +++ linux86/bootblocks/min_buf.c Sun Feb 20 07:58:00 2000 @@ -14,7 +14,7 @@ static int track_no = -1; static int buf_len = 0; -static char buffer[MAXTRK*512]; +static char buffer[MAXTRK*512]; /* WARNING: This must be DMAable */ void reset_disk() { diff -Nurd linux86.old/bootblocks/msdos.s linux86/bootblocks/msdos.s --- linux86.old/bootblocks/msdos.s Tue Aug 3 16:52:37 1999 +++ linux86/bootblocks/msdos.s Sat Sep 2 22:16:06 2000 @@ -19,10 +19,9 @@ ! ! All these are true for mtools created floppies on normal PC drives. ! -! In addition this now has a compile time option for 16 bit FAT floppies -! TODO: Hard partition (dos_hidden != 0) -! Zip disks (floppy with dos_hidden != 0) -! Auto detect disk type +! In addition this now has a compile time option for FAT16 partitions. +! TODO: Auto detect disk type +! FAT32 ! !--------------------------------------------------------------------------- ORGADDR=$0500 @@ -37,6 +36,13 @@ export heads heads=0 ! This can be 0,1 or 2. 0 is dynamic. +export harddisk + if fatbits=12 +harddisk=0 + else +harddisk=1 ! Allow for hard disks, but will only work with + endif ! disks formatted >= MSDOS 4.0 + !--------------------------------------------------------------------------- ! Absolute position macro, fails if code before it is too big. macro locn @@ -185,6 +191,9 @@ and al,#$C0 or cl,al endif + if harddisk + mov dl,[dos4_phy_drive] + endif ret !--------------------------------------------------------------------------- @@ -332,13 +341,18 @@ !--------------------------------------------------------------------------- ! File is now loaded, execute it. maincode: + if harddisk=0 mov bx,#7 mov ax,#$0E3E int $10 ! Marker printed to say bootblock succeeded. + endif xor dx,dx ! DX=0 => floppy drive + if harddisk + mov dl,[dos4_phy_drive] + endif push dx ! CX=0 => partition offset = 0 - mov si,[dos_spt] ! SI=Sectors pet track + mov si,[dos_spt] ! SI=Sectors per track mov bx,#LOADSEG mov ds,bx ! DS = loadaddress @@ -390,12 +404,9 @@ name_end: ! NNNNNNNNEEE -if fatbits =16 locn(510) - .word 0 ! This is a floppy so it should not need the magic _but_ + .word $AA55 ! This is a floppy so it should not need the magic _but_ ! the debian MBR requires the magic even on floppies - ! so only clear on a superfloppy (LS-120). -endif fat_table: ! This is the location that the fat table is loaded. ! Note: The fat must be entirely on track zero if 12 bit. diff -Nurd linux86.old/bootblocks/sysboot.s linux86/bootblocks/sysboot.s --- linux86.old/bootblocks/sysboot.s Sun Jun 7 19:58:20 1998 +++ linux86/bootblocks/sysboot.s Sat Sep 2 22:13:32 2000 @@ -35,12 +35,13 @@ dos_hidden: .blkw 2 ! Hidden sectors ! Here down is DOS 4+ and probably not needed for floppy boots. -floppy_temp: dos4_maxsect: .blkw 2 ! Large FS sector count dos4_phy_drive: .blkb 1 ! Phys drive .blkb 1 ! Reserved .blkb 1 ! DOS 4 + +floppy_temp: dos4_serial: .blkw 2 ! Serial number dos4_label: .blkb 11 ! Disk Label (DOS 4+) dos4_fattype: .blkb 8 ! FAT type diff -Nurd linux86.old/copt/Makefile linux86/copt/Makefile --- linux86.old/copt/Makefile Fri Jul 23 11:45:52 1999 +++ linux86/copt/Makefile Sat Jan 6 12:35:38 2001 @@ -1,6 +1,6 @@ copt: copt.c - $(CC) $(CFLAGS) $(LDFLAGS) -o copt copt.c + $(CC) $(ANSI) $(CFLAGS) $(LDFLAGS) -o $@ $< realclean clean: rm -f *.o copt diff -Nurd linux86.old/elksemu/Kernel_patch linux86/elksemu/Kernel_patch --- linux86.old/elksemu/Kernel_patch Wed Oct 9 06:46:40 1996 +++ linux86/elksemu/Kernel_patch Mon May 21 13:48:50 2001 @@ -3,6 +3,7 @@ It requires V0.0.2 or better of elksemu in the file "/lib/elksemu". If you are using kernel 1.3.* or later try the module: binfmt_elks.o +If you are using 2.0.36, 2.1.43 or 2.2.0 and later use binfmt_misc. --- orig-13/fs/exec.c Sun Sep 24 13:22:37 1995 +++ linux/fs/exec.c Sun Feb 11 20:11:47 1996 diff -Nurd linux86.old/elksemu/Makefile linux86/elksemu/Makefile --- linux86.old/elksemu/Makefile Fri Jan 15 22:36:44 1999 +++ linux86/elksemu/Makefile Sat Jan 6 12:33:39 2001 @@ -10,11 +10,6 @@ CFLAGS=-Ml -ansi -s $(DEFS) endif -# For gcc -ifeq ($(CC),gcc) -CFLAGS=-O2 -fno-strength-reduce -Wall -idirafter . $(DEFS) -endif - # Default ifeq ($(CFLAGS),) CFLAGS=-O @@ -29,7 +24,7 @@ OBJ=elks.o elks_sys.o elks_signal.o minix.o elksemu: $(OBJ) - $(CC) $(CFLAGS) -o elksemu $(OBJ) + $(CC) $(CFLAGS) -o $@ $^ elks_sys.o: call_tab.v $(OBJ): elks.h @@ -40,13 +35,14 @@ dummy: -# The kernel patch or module _requires_ this location. +# The kernel patch or module _requires_ this location but binfmt-misc is easy +# to redirect. install: elksemu install -d $(DIST)/lib install -s -o root -g root -m 4555 elksemu $(DIST)/lib/elksemu clean realclean: - rm -f $(OBJ) elksemu call_tab.v defn_tab.v + rm -f $(OBJ) binfmt_elks.o elksemu call_tab.v defn_tab.v module: binfmt_elks.o diff -Nurd linux86.old/elksemu/binfmt_elks.c linux86/elksemu/binfmt_elks.c --- linux86.old/elksemu/binfmt_elks.c Wed Oct 9 06:41:48 1996 +++ linux86/elksemu/binfmt_elks.c Fri Jan 15 23:25:58 1999 @@ -5,7 +5,6 @@ * original #!-checking implemented by tytso. * ELKS hack added by Chad Page... * Cleaned up some more by Robert de Bath - * I can't make it work with 1.2.13 tho! :-( */ #include diff -Nurd linux86.old/elksemu/linux/vm86.h linux86/elksemu/linux/vm86.h --- linux86.old/elksemu/linux/vm86.h Sun Jun 30 09:06:05 1996 +++ linux86/elksemu/linux/vm86.h Thu Jan 1 01:00:00 1970 @@ -1,8 +0,0 @@ -/* - * Since 1.3.99 vm86.h has moved from it's original position, this file - * redirects sys/vm86.h to the correct location if it hasn't been updated - * yet. - * - * Use "-idirafter . " on the command line. - */ -#include diff -Nurd linux86.old/ld/Makefile linux86/ld/Makefile --- linux86.old/ld/Makefile Fri Jul 31 10:01:01 1998 +++ linux86/ld/Makefile Sat Jan 6 10:02:20 2001 @@ -21,11 +21,11 @@ all: ld86 objchop catimage objdump86 ld86: $(OBJS) - $(CC) $(LDFLAGS) $(OBJS) -o $@ + $(CC) $(LDFLAGS) $^ -o $@ install: ld86 install -d $(LIBDIR) - install -m 755 ld86 $(LIBDIR) + install -m 755 $^ $(LIBDIR) clean realclean clobber: rm -f *.o ld86 ld86r objchop catimage objdump86 @@ -39,7 +39,7 @@ ln ../libc/include/ar.h . writebin.o: writebin.c - $(CC) $(CFLAGS) $(DEFS) $(NATIVE) -c writebin.c + $(CC) $(CFLAGS) $(DEFS) $(NATIVE) -c $< writerel.o: writebin.c diff -Nurd linux86.old/libc/Config.dflt linux86/libc/Config.dflt --- linux86.old/libc/Config.dflt Sat Oct 18 13:29:22 1997 +++ linux86/libc/Config.dflt Sun Dec 3 09:29:07 2000 @@ -5,11 +5,11 @@ gtermcap:+: i386fp:+: i386sys:+: -malloc1:+: +malloc:+: misc:+: msdos:+: regexp:+: -stdio2:+: +stdio:+: string:+: syscall:+: termios:+: diff -Nurd linux86.old/libc/Makefile linux86/libc/Makefile --- linux86.old/libc/Makefile Fri Dec 17 18:06:02 1999 +++ linux86/libc/Makefile Mon May 21 14:02:37 2001 @@ -10,7 +10,7 @@ endif VERMAJOR=0 -VERMINOR=15 +VERMINOR=16 VERPATCH=0 VER=$(VERMAJOR).$(VERMINOR).$(VERPATCH) diff -Nurd linux86.old/libc/bios/Makefile linux86/libc/bios/Makefile --- linux86.old/libc/bios/Makefile Thu Dec 3 19:57:56 1998 +++ linux86/libc/bios/Makefile Sat May 12 10:11:00 2001 @@ -5,7 +5,7 @@ ifeq ($(LIB_OS),BIOS) ASRC=bios.c AOBJ=bios_start.o bios_isatty.o bios_nofiles.o \ - bios_open.o bios_read.o bios_write.o bios_lseek.o bios_close.o + bios_read.o bios_write.o bios_lseek.o bios_close.o BSRC=bios_vid.c BOBJ=bios_putc.o bios_getc.o bios_khit.o bios_rdline.o diff -Nurd linux86.old/libc/bios/bios.c linux86/libc/bios/bios.c --- linux86.old/libc/bios/bios.c Mon Nov 23 08:23:42 1998 +++ linux86/libc/bios/bios.c Sat May 12 10:14:37 2001 @@ -211,21 +211,6 @@ /****************************************************************************/ -#ifdef L_bios_open -extern int __fileops(); - -open(name, flags, mode) -char * name; -int flags, mode; -{ - __files = __fileops; - return (*__files)(CMD_OPEN, flags, name, mode); -} - -#endif - -/****************************************************************************/ - #endif #endif #endif diff -Nurd linux86.old/libc/bios/cprintf.c linux86/libc/bios/cprintf.c --- linux86.old/libc/bios/cprintf.c Thu Dec 31 11:12:46 1998 +++ linux86/libc/bios/cprintf.c Sat Jan 29 15:23:20 2000 @@ -55,8 +55,9 @@ switch(c) { - case 'x': base=16; if(0) { - case 'o': base= 8; } if(0) { + case 'x': base=16; type|=4; if(0) { + case 'o': base= 8; type|=4; } if(0) { + case 'u': base=10; type|=4; } if(0) { case 'd': base=10; } val=0; switch(type) @@ -64,6 +65,9 @@ case 0: val=va_arg(ap, short); break; case 1: val=va_arg(ap, int); break; case 2: val=va_arg(ap, long); break; + case 4: val=va_arg(ap, unsigned short); break; + case 5: val=va_arg(ap, unsigned int); break; + case 6: val=va_arg(ap, unsigned long); break; } cp = __numout(val,base); if(0) { diff -Nurd linux86.old/libc/bios/fileops.c linux86/libc/bios/fileops.c --- linux86.old/libc/bios/fileops.c Thu Dec 3 19:59:04 1998 +++ linux86/libc/bios/fileops.c Sat May 12 10:37:59 2001 @@ -11,9 +11,19 @@ static int op_read(); static int op_write(); static long op_lseek(); +static int fileops(); int -__fileops(cmd, fd, buf, len) +open(name, flags, mode) +char * name; +int flags, mode; +{ + __files = fileops; + return (*__files)(CMD_OPEN, flags, name, mode); +} + +static int +fileops(cmd, fd, buf, len) int cmd, fd, len; char * buf; { @@ -48,7 +58,7 @@ int amount_left_in_buffer; int amount_to_copy; - if (fd >= MAX_OPEN_FILES || _iob[fd].block_read == 0) + if (fd < 0 || fd >= MAX_OPEN_FILES || _iob[fd].block_read == 0) { errno = EBADF; return -1; @@ -147,7 +157,7 @@ op_close(fd) int fd; { - if (fd >= MAX_OPEN_FILES || _iob[0].flags == 0) + if (fd < 0 || fd >= MAX_OPEN_FILES || _iob[0].flags == 0) { errno = EBADF; return -1; diff -Nurd linux86.old/libc/malloc/Config linux86/libc/malloc/Config --- linux86.old/libc/malloc/Config Thu Jan 1 01:00:00 1970 +++ linux86/libc/malloc/Config Sun Dec 3 09:32:15 2000 @@ -0,0 +1 @@ +malloc: Malloc routines diff -Nurd linux86.old/libc/malloc/Makefile linux86/libc/malloc/Makefile --- linux86.old/libc/malloc/Makefile Thu Jan 1 01:00:00 1970 +++ linux86/libc/malloc/Makefile Sat Mar 8 20:14:11 1997 @@ -0,0 +1,22 @@ +# Copyright (C) 1995,1996 Robert de Bath +# This file is part of the Linux-8086 C library and is distributed +# under the GNU Library General Public License. + +ASRC=malloc.c +AOBJ=malloc.o alloca.o free.o calloc.o realloc.o + +CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS) + +all: $(LIBC)($(AOBJ)) + @$(RM) $(OBJ) + +$(LIBC)($(AOBJ)): $(ASRC) + $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o + $(AR) $(ARFLAGS) $@ $*.o + +clean: + rm -f *.o libc.a + +transfer: + -@rm ../include/malloc.h + cp -p malloc.h ../include/. diff -Nurd linux86.old/libc/malloc/README linux86/libc/malloc/README --- linux86.old/libc/malloc/README Thu Jan 1 01:00:00 1970 +++ linux86/libc/malloc/README Sat Jan 6 11:31:55 1996 @@ -0,0 +1,9 @@ +Copyright (C) 1995,1996 Robert de Bath +This file is part of the Linux-8086 C library and is distributed +under the GNU Library General Public License. + +This is a combined alloca/malloc package. It uses a classic algorithm +and so may be seen to be quite slow compared to more modern routines +with 'nasty' distributions of allocation. + +-Robert diff -Nurd linux86.old/libc/malloc/malloc.c linux86/libc/malloc/malloc.c --- linux86.old/libc/malloc/malloc.c Thu Jan 1 01:00:00 1970 +++ linux86/libc/malloc/malloc.c Tue Oct 22 21:29:10 1996 @@ -0,0 +1,546 @@ +/* Copyright (C) 1995,1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* + * This is a combined alloca/malloc package. It uses a classic algorithm + * and so may be seen to be quite slow compared to more modern routines + * with 'nasty' distributions. + */ + +#include +#include + +#define MCHUNK 2048 /* Allocation unit in 'mem' elements */ +#define XLAZY_FREE /* If set frees can be infinitly defered */ +#define XMINALLOC 32 /* Smallest chunk to alloc in 'mem's */ +#define XVERBOSE /* Lots of noise, debuging ? */ + +#undef malloc +#define MAX_INT ((int)(((unsigned)-1)>>1)) + +#ifdef VERBOSE +#define noise __noise +#else +#define noise(y,x) +#endif + +typedef union mem_cell +{ + union mem_cell *next; /* A pointer to the next mem */ + unsigned int size; /* An int >= sizeof pointer */ + char *depth; /* For the alloca hack */ +} +mem; + +#define m_size(p) ((p) [0].size) /* For malloc */ +#define m_next(p) ((p) [1].next) /* For malloc and alloca */ +#define m_deep(p) ((p) [0].depth) /* For alloca */ + +extern void *__mini_malloc __P ((size_t)); +extern void *(*__alloca_alloc) __P ((size_t)); +extern mem *__freed_list; + +#ifdef L_free +/* Start the alloca with just the dumb version of malloc */ + +void *(*__alloca_alloc) __P ((size_t)) = __mini_malloc; +mem *__freed_list = 0; + +#ifdef VERBOSE +/* NB: Careful here, stdio may use malloc - so we can't */ +static +phex(val) +{ + static char hex[] = "0123456789ABCDEF"; + int i; + for (i = sizeof(int)*8-4; i >= 0; i -= 4) + write(2, hex + ((val >> i) & 0xF), 1); +} + +noise(y, x) +char *y; +mem *x; +{ + write(2, "Malloc ", 7); + phex(x); + write(2, " sz ", 4); + if(x) phex(m_size(x)); else phex(0); + write(2, " nxt ", 5); + if(x) phex(m_next(x)); else phex(0); + write(2, " is ", 4); + write(2, y, strlen(y)); + write(2, "\n", 1); +} +#endif + +#endif + +#ifdef L_alloca +static mem *alloca_stack = 0; + +void * +alloca(size) +size_t size; +{ + auto char probe; /* Probes stack depth: */ + register mem *hp; + + /* + * Reclaim garbage, defined as all alloca'd storage that was allocated + * from deeper in the stack than currently. + */ + + for (hp = alloca_stack; hp != 0;) + if (m_deep(hp) < &probe) + { + register mem *np = m_next(hp); + free((void *) hp); /* Collect garbage. */ + hp = np; /* -> next header. */ + } + else + break; /* Rest are not deeper. */ + + alloca_stack = hp; /* -> last valid storage. */ + if (size == 0) + return 0; /* No allocation required. */ + + hp = (mem *) (*__alloca_alloc) (sizeof(mem)*2 + size); + if (hp == 0) + return hp; + + m_next(hp) = alloca_stack; + m_deep(hp) = &probe; + alloca_stack = hp; + + /* User storage begins just after header. */ + return (void *) (hp + 2); +} +#endif /* L_alloca */ + +#ifdef L_free +void +free(ptr) +void *ptr; +{ + register mem *top; + register mem *chk = (mem *) ptr; + + if (chk == 0) + return; /* free(NULL) - be nice */ + chk--; + + try_this:; + top = (mem *) sbrk(0); + if (chk + m_size(chk) == top) + { + noise("FREE brk", chk); + brk(top-m_size(chk)); + /* + * Adding this code allow free to release blocks in any order; they + * can still only be allocated from the top of the heap tho. + */ +#ifdef __MINI_MALLOC__ + if (__alloca_alloc == __mini_malloc && __freed_list) + { + mem *prev, *curr; + chk = __freed_list; + __freed_list = m_next(__freed_list); + goto try_this; + } +#endif + } + else + { /* Nope, not sure where this goes, leave + * it for malloc to deal with */ +#ifdef __MINI_MALLOC__ + if( __freed_list || chk > __freed_list ) + { m_next(chk) = __freed_list; __freed_list = chk; } + else + { + register mem *prev; + prev=__freed_list; + for(top=__freed_list; top && top > chk; prev=top, top=m_next(top)) + ; + m_next(chk) = top; + m_next(prev) = chk; + } +#else + m_next(chk) = __freed_list; + __freed_list = chk; +#endif + noise("ADD LIST", chk); + } +} + +void * +__mini_malloc(size) +size_t size; +{ + register mem *ptr; + register unsigned int sz; + + /* First time round this _might_ be odd, But we won't do that! */ + sz = (unsigned int) sbrk(0); + if (sz & (sizeof(mem) - 1)) + sbrk(4 - (sz & (sizeof(mem) - 1))); + + if (size <= 0) + return 0; + /* Minor oops here, sbrk has a signed argument */ + if( size > (((unsigned)-1)>>1)-sizeof(mem)*3 ) + { + errno = ENOMEM; + return 0; + } + + size += sizeof(mem) * 2 - 1; /* Round up and leave space for size field */ + size /= sizeof(mem); + + ptr = (mem *) sbrk(size * sizeof(mem)); + if ((int) ptr == -1) + return 0; + + m_size(ptr) = size; + noise("CREATE", ptr); + return ptr + 1; +} +#endif /* L_free */ + +#ifdef L_malloc + +/* + * The chunk_list pointer is either NULL or points to a chunk in a + * circular list of all the free blocks in memory + */ + +#define Static static + +static mem *chunk_list = 0; +Static void __insert_chunk(); +Static mem *__search_chunk(); + +void * +malloc(size) +size_t size; +{ + register mem *ptr = 0; + register unsigned int sz; + + if (size == 0) + return 0; /* ANSI STD */ + + sz = size + sizeof(mem) * 2 - 1; + sz /= sizeof(mem); + +#ifdef MINALLOC + if (sz < MINALLOC) + sz = MINALLOC; +#endif + +#ifdef VERBOSE + { + static mem arr[2]; + m_size(arr) = sz; + noise("WANTED", arr); + } +#endif + + __alloca_alloc = malloc; /* We'll be messing with the heap now TVM */ + +#ifdef LAZY_FREE + ptr = __search_chunk(sz); + if (ptr == 0) + { +#endif + + /* First deal with the freed list */ + if (__freed_list) + { + while (__freed_list) + { + ptr = __freed_list; + __freed_list = m_next(__freed_list); + + if (m_size(ptr) == sz) /* Oh! Well that's lucky ain't it + * :-) */ + { + noise("LUCKY MALLOC", ptr); + return ptr + 1; + } + + __insert_chunk(ptr); + } + ptr = m_next(chunk_list); + if (ptr + m_size(ptr) == (void *) sbrk(0)) + { + /* Time to free for real */ + m_next(chunk_list) = m_next(ptr); + if (ptr == m_next(ptr)) + chunk_list = 0; + free(ptr + 1); + } +#ifdef LAZY_FREE + ptr = __search_chunk(sz); +#endif + } +#ifndef LAZY_FREE + ptr = __search_chunk(sz); +#endif + if (ptr == 0) + { +#ifdef MCHUNK + unsigned int alloc; + alloc = sizeof(mem) * (MCHUNK * ((sz + MCHUNK - 1) / MCHUNK) - 1); + ptr = __mini_malloc(alloc); + if (ptr) + __insert_chunk(ptr - 1); + else /* Oooo, near end of RAM */ + { + unsigned int needed = alloc; + for(alloc/=2; alloc>256 && needed; ) + { + ptr = __mini_malloc(alloc); + if (ptr) + { + if( alloc > needed ) needed = 0; else needed -= alloc; + __insert_chunk(ptr - 1); + } + else alloc/=2; + } + } + ptr = __search_chunk(sz); + if (ptr == 0) +#endif + { +#ifndef MCHUNK + ptr = __mini_malloc(size); +#endif +#ifdef VERBOSE + if( ptr == 0 ) + noise("MALLOC FAIL", 0); + else + noise("MALLOC NOW", ptr - 1); +#endif + return ptr; + } + } +#ifdef LAZY_FREE + } +#endif + +#ifdef VERBOSE + ptr[1].size = 0x55555555; +#endif + noise("MALLOC RET", ptr); + return ptr + 1; +} + +/* + * This function takes a pointer to a block of memory and inserts it into + * the chain of memory chunks + */ + +Static void +__insert_chunk(mem_chunk) +mem *mem_chunk; +{ + register mem *p1, *p2; + if (chunk_list == 0) /* Simple case first */ + { + m_next(mem_chunk) = chunk_list = mem_chunk; + noise("FIRST CHUNK", mem_chunk); + return; + } + p1 = mem_chunk; + p2 = chunk_list; + + do + { + if (p1 > p2) + { + if (m_next(p2) <= p2) + { /* We're at the top of the chain, p1 is + * higher */ + + if (p2 + m_size(p2) == p1) + { /* Good, stick 'em together */ + noise("INSERT CHUNK", mem_chunk); + m_size(p2) += m_size(p1); + noise("JOIN 1", p2); + } + else + { + m_next(p1) = m_next(p2); + m_next(p2) = p1; + noise("INSERT CHUNK", mem_chunk); + noise("FROM", p2); + } + return; + } + if (m_next(p2) > p1) + { + /* In chain, p1 between p2 and next */ + + m_next(p1) = m_next(p2); + m_next(p2) = p1; + noise("INSERT CHUNK", mem_chunk); + noise("FROM", p2); + + /* Try to join above */ + if (p1 + m_size(p1) == m_next(p1)) + { + m_size(p1) += m_size(m_next(p1)); + m_next(p1) = m_next(m_next(p1)); + noise("JOIN 2", p1); + } + /* Try to join below */ + if (p2 + m_size(p2) == p1) + { + m_size(p2) += m_size(p1); + m_next(p2) = m_next(p1); + noise("JOIN 3", p2); + } + chunk_list = p2; /* Make sure it's valid */ + return; + } + } + else if (p1 < p2) + { + if (m_next(p2) <= p2 && p1 < m_next(p2)) + { + /* At top of chain, next is bottom of chain, p1 is below next */ + + m_next(p1) = m_next(p2); + m_next(p2) = p1; + noise("INSERT CHUNK", mem_chunk); + noise("FROM", p2); + chunk_list = p2; + + if (p1 + m_size(p1) == m_next(p1)) + { + if (p2 == m_next(p1)) + chunk_list = p1; + m_size(p1) += m_size(m_next(p1)); + m_next(p1) = m_next(m_next(p1)); + noise("JOIN 4", p1); + } + return; + } + } + chunk_list = p2; /* Save for search */ + p2 = m_next(p2); + } + while (p2 != chunk_list); + + /* If we get here we have a problem, ignore it, maybe it'll go away */ + noise("DROPPED CHUNK", mem_chunk); +} + +/* + * This function will search for a chunk in memory of at least 'mem_size' + * when found, if the chunk is too big it'll be split, and pointer to the + * chunk returned. If none is found NULL is returned. + */ + +Static mem * +__search_chunk(mem_size) +unsigned int mem_size; +{ + register mem *p1, *p2; + if (chunk_list == 0) /* Simple case first */ + return 0; + + /* Search for a block >= the size we want */ + p1 = m_next(chunk_list); + p2 = chunk_list; + do + { + noise("CHECKED", p1); + if (m_size(p1) >= mem_size) + break; + + p2 = p1; + p1 = m_next(p1); + } + while (p2 != chunk_list); + + /* None found, exit */ + if (m_size(p1) < mem_size) + return 0; + + /* If it's exactly right remove it */ + if (m_size(p1) < mem_size + 2) + { + noise("FOUND RIGHT", p1); + chunk_list = m_next(p2) = m_next(p1); + if (chunk_list == p1) + chunk_list = 0; + return p1; + } + + noise("SPLIT", p1); + /* Otherwise split it */ + m_next(p2) = p1 + mem_size; + chunk_list = p2; + + p2 = m_next(p2); + m_size(p2) = m_size(p1) - mem_size; + m_next(p2) = m_next(p1); + m_size(p1) = mem_size; + if (chunk_list == p1) + chunk_list = p2; +#ifdef VERBOSE + p1[1].size = 0xAAAAAAAA; +#endif + noise("INSERT CHUNK", p2); + noise("FOUND CHUNK", p1); + noise("LIST IS", chunk_list); + return p1; +} + +#endif /* L_malloc */ + +#ifdef L_calloc +void * +calloc(elm, sz) +unsigned int elm, sz; +{ + register unsigned int v; + register void *ptr; + ptr = malloc(v = elm * sz); + if (ptr) + memset(ptr, 0, v); + return ptr; +} +#endif /* L_calloc */ + +#ifdef L_realloc +void * +realloc(ptr, size) +void *ptr; +size_t size; +{ + void *nptr; + unsigned int osize; + if (ptr == 0) + return malloc(size); + + osize = (m_size(((mem *) ptr) - 1) - 1) * sizeof(mem); + if (size <= osize) + { + return ptr; + } + + nptr = malloc(size); + + if (nptr == 0) + return 0; + + memcpy(nptr, ptr, osize); + free(ptr); + + return nptr; +} +#endif /* L_realloc */ diff -Nurd linux86.old/libc/malloc/malloc.h linux86/libc/malloc/malloc.h --- linux86.old/libc/malloc/malloc.h Thu Jan 1 01:00:00 1970 +++ linux86/libc/malloc/malloc.h Tue Jul 23 22:03:28 1996 @@ -0,0 +1,30 @@ + +#ifndef __MALLOC_H +#define __MALLOC_H +#include +#include + +/* + * Mini malloc allows you to use a less efficient but smaller malloc the + * cost is about 100 bytes of code in free but malloc (700bytes) doesn't + * have to be linked. Unfortunatly memory can only be reused if everything + * above it has been freed + * + */ + +extern void free __P((void *)); +extern void *malloc __P((size_t)); +extern void *realloc __P((void *, size_t)); +extern void *alloca __P((size_t)); + +extern void *(*__alloca_alloc) __P((size_t)); + +#ifdef __LIBC__ +#define __MINI_MALLOC__ +#endif + +#ifdef __MINI_MALLOC__ +#define malloc(x) ((*__alloca_alloc)(x)) +#endif + +#endif diff -Nurd linux86.old/libc/malloc1/Config linux86/libc/malloc1/Config --- linux86.old/libc/malloc1/Config Sun Feb 11 11:31:34 1996 +++ linux86/libc/malloc1/Config Thu Jan 1 01:00:00 1970 @@ -1 +0,0 @@ -malloc: Robert's malloc routines diff -Nurd linux86.old/libc/malloc1/Makefile linux86/libc/malloc1/Makefile --- linux86.old/libc/malloc1/Makefile Sat Mar 8 20:14:11 1997 +++ linux86/libc/malloc1/Makefile Thu Jan 1 01:00:00 1970 @@ -1,22 +0,0 @@ -# Copyright (C) 1995,1996 Robert de Bath -# This file is part of the Linux-8086 C library and is distributed -# under the GNU Library General Public License. - -ASRC=malloc.c -AOBJ=malloc.o alloca.o free.o calloc.o realloc.o - -CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS) - -all: $(LIBC)($(AOBJ)) - @$(RM) $(OBJ) - -$(LIBC)($(AOBJ)): $(ASRC) - $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o - $(AR) $(ARFLAGS) $@ $*.o - -clean: - rm -f *.o libc.a - -transfer: - -@rm ../include/malloc.h - cp -p malloc.h ../include/. diff -Nurd linux86.old/libc/malloc1/README linux86/libc/malloc1/README --- linux86.old/libc/malloc1/README Sat Jan 6 11:31:55 1996 +++ linux86/libc/malloc1/README Thu Jan 1 01:00:00 1970 @@ -1,9 +0,0 @@ -Copyright (C) 1995,1996 Robert de Bath -This file is part of the Linux-8086 C library and is distributed -under the GNU Library General Public License. - -This is a combined alloca/malloc package. It uses a classic algorithm -and so may be seen to be quite slow compared to more modern routines -with 'nasty' distributions of allocation. - --Robert diff -Nurd linux86.old/libc/malloc1/malloc.c linux86/libc/malloc1/malloc.c --- linux86.old/libc/malloc1/malloc.c Tue Oct 22 21:29:10 1996 +++ linux86/libc/malloc1/malloc.c Thu Jan 1 01:00:00 1970 @@ -1,546 +0,0 @@ -/* Copyright (C) 1995,1996 Robert de Bath - * This file is part of the Linux-8086 C library and is distributed - * under the GNU Library General Public License. - */ - -/* - * This is a combined alloca/malloc package. It uses a classic algorithm - * and so may be seen to be quite slow compared to more modern routines - * with 'nasty' distributions. - */ - -#include -#include - -#define MCHUNK 2048 /* Allocation unit in 'mem' elements */ -#define XLAZY_FREE /* If set frees can be infinitly defered */ -#define XMINALLOC 32 /* Smallest chunk to alloc in 'mem's */ -#define XVERBOSE /* Lots of noise, debuging ? */ - -#undef malloc -#define MAX_INT ((int)(((unsigned)-1)>>1)) - -#ifdef VERBOSE -#define noise __noise -#else -#define noise(y,x) -#endif - -typedef union mem_cell -{ - union mem_cell *next; /* A pointer to the next mem */ - unsigned int size; /* An int >= sizeof pointer */ - char *depth; /* For the alloca hack */ -} -mem; - -#define m_size(p) ((p) [0].size) /* For malloc */ -#define m_next(p) ((p) [1].next) /* For malloc and alloca */ -#define m_deep(p) ((p) [0].depth) /* For alloca */ - -extern void *__mini_malloc __P ((size_t)); -extern void *(*__alloca_alloc) __P ((size_t)); -extern mem *__freed_list; - -#ifdef L_free -/* Start the alloca with just the dumb version of malloc */ - -void *(*__alloca_alloc) __P ((size_t)) = __mini_malloc; -mem *__freed_list = 0; - -#ifdef VERBOSE -/* NB: Careful here, stdio may use malloc - so we can't */ -static -phex(val) -{ - static char hex[] = "0123456789ABCDEF"; - int i; - for (i = sizeof(int)*8-4; i >= 0; i -= 4) - write(2, hex + ((val >> i) & 0xF), 1); -} - -noise(y, x) -char *y; -mem *x; -{ - write(2, "Malloc ", 7); - phex(x); - write(2, " sz ", 4); - if(x) phex(m_size(x)); else phex(0); - write(2, " nxt ", 5); - if(x) phex(m_next(x)); else phex(0); - write(2, " is ", 4); - write(2, y, strlen(y)); - write(2, "\n", 1); -} -#endif - -#endif - -#ifdef L_alloca -static mem *alloca_stack = 0; - -void * -alloca(size) -size_t size; -{ - auto char probe; /* Probes stack depth: */ - register mem *hp; - - /* - * Reclaim garbage, defined as all alloca'd storage that was allocated - * from deeper in the stack than currently. - */ - - for (hp = alloca_stack; hp != 0;) - if (m_deep(hp) < &probe) - { - register mem *np = m_next(hp); - free((void *) hp); /* Collect garbage. */ - hp = np; /* -> next header. */ - } - else - break; /* Rest are not deeper. */ - - alloca_stack = hp; /* -> last valid storage. */ - if (size == 0) - return 0; /* No allocation required. */ - - hp = (mem *) (*__alloca_alloc) (sizeof(mem)*2 + size); - if (hp == 0) - return hp; - - m_next(hp) = alloca_stack; - m_deep(hp) = &probe; - alloca_stack = hp; - - /* User storage begins just after header. */ - return (void *) (hp + 2); -} -#endif /* L_alloca */ - -#ifdef L_free -void -free(ptr) -void *ptr; -{ - register mem *top; - register mem *chk = (mem *) ptr; - - if (chk == 0) - return; /* free(NULL) - be nice */ - chk--; - - try_this:; - top = (mem *) sbrk(0); - if (chk + m_size(chk) == top) - { - noise("FREE brk", chk); - brk(top-m_size(chk)); - /* - * Adding this code allow free to release blocks in any order; they - * can still only be allocated from the top of the heap tho. - */ -#ifdef __MINI_MALLOC__ - if (__alloca_alloc == __mini_malloc && __freed_list) - { - mem *prev, *curr; - chk = __freed_list; - __freed_list = m_next(__freed_list); - goto try_this; - } -#endif - } - else - { /* Nope, not sure where this goes, leave - * it for malloc to deal with */ -#ifdef __MINI_MALLOC__ - if( __freed_list || chk > __freed_list ) - { m_next(chk) = __freed_list; __freed_list = chk; } - else - { - register mem *prev; - prev=__freed_list; - for(top=__freed_list; top && top > chk; prev=top, top=m_next(top)) - ; - m_next(chk) = top; - m_next(prev) = chk; - } -#else - m_next(chk) = __freed_list; - __freed_list = chk; -#endif - noise("ADD LIST", chk); - } -} - -void * -__mini_malloc(size) -size_t size; -{ - register mem *ptr; - register unsigned int sz; - - /* First time round this _might_ be odd, But we won't do that! */ - sz = (unsigned int) sbrk(0); - if (sz & (sizeof(mem) - 1)) - sbrk(4 - (sz & (sizeof(mem) - 1))); - - if (size <= 0) - return 0; - /* Minor oops here, sbrk has a signed argument */ - if( size > (((unsigned)-1)>>1)-sizeof(mem)*3 ) - { - errno = ENOMEM; - return 0; - } - - size += sizeof(mem) * 2 - 1; /* Round up and leave space for size field */ - size /= sizeof(mem); - - ptr = (mem *) sbrk(size * sizeof(mem)); - if ((int) ptr == -1) - return 0; - - m_size(ptr) = size; - noise("CREATE", ptr); - return ptr + 1; -} -#endif /* L_free */ - -#ifdef L_malloc - -/* - * The chunk_list pointer is either NULL or points to a chunk in a - * circular list of all the free blocks in memory - */ - -#define Static static - -static mem *chunk_list = 0; -Static void __insert_chunk(); -Static mem *__search_chunk(); - -void * -malloc(size) -size_t size; -{ - register mem *ptr = 0; - register unsigned int sz; - - if (size == 0) - return 0; /* ANSI STD */ - - sz = size + sizeof(mem) * 2 - 1; - sz /= sizeof(mem); - -#ifdef MINALLOC - if (sz < MINALLOC) - sz = MINALLOC; -#endif - -#ifdef VERBOSE - { - static mem arr[2]; - m_size(arr) = sz; - noise("WANTED", arr); - } -#endif - - __alloca_alloc = malloc; /* We'll be messing with the heap now TVM */ - -#ifdef LAZY_FREE - ptr = __search_chunk(sz); - if (ptr == 0) - { -#endif - - /* First deal with the freed list */ - if (__freed_list) - { - while (__freed_list) - { - ptr = __freed_list; - __freed_list = m_next(__freed_list); - - if (m_size(ptr) == sz) /* Oh! Well that's lucky ain't it - * :-) */ - { - noise("LUCKY MALLOC", ptr); - return ptr + 1; - } - - __insert_chunk(ptr); - } - ptr = m_next(chunk_list); - if (ptr + m_size(ptr) == (void *) sbrk(0)) - { - /* Time to free for real */ - m_next(chunk_list) = m_next(ptr); - if (ptr == m_next(ptr)) - chunk_list = 0; - free(ptr + 1); - } -#ifdef LAZY_FREE - ptr = __search_chunk(sz); -#endif - } -#ifndef LAZY_FREE - ptr = __search_chunk(sz); -#endif - if (ptr == 0) - { -#ifdef MCHUNK - unsigned int alloc; - alloc = sizeof(mem) * (MCHUNK * ((sz + MCHUNK - 1) / MCHUNK) - 1); - ptr = __mini_malloc(alloc); - if (ptr) - __insert_chunk(ptr - 1); - else /* Oooo, near end of RAM */ - { - unsigned int needed = alloc; - for(alloc/=2; alloc>256 && needed; ) - { - ptr = __mini_malloc(alloc); - if (ptr) - { - if( alloc > needed ) needed = 0; else needed -= alloc; - __insert_chunk(ptr - 1); - } - else alloc/=2; - } - } - ptr = __search_chunk(sz); - if (ptr == 0) -#endif - { -#ifndef MCHUNK - ptr = __mini_malloc(size); -#endif -#ifdef VERBOSE - if( ptr == 0 ) - noise("MALLOC FAIL", 0); - else - noise("MALLOC NOW", ptr - 1); -#endif - return ptr; - } - } -#ifdef LAZY_FREE - } -#endif - -#ifdef VERBOSE - ptr[1].size = 0x55555555; -#endif - noise("MALLOC RET", ptr); - return ptr + 1; -} - -/* - * This function takes a pointer to a block of memory and inserts it into - * the chain of memory chunks - */ - -Static void -__insert_chunk(mem_chunk) -mem *mem_chunk; -{ - register mem *p1, *p2; - if (chunk_list == 0) /* Simple case first */ - { - m_next(mem_chunk) = chunk_list = mem_chunk; - noise("FIRST CHUNK", mem_chunk); - return; - } - p1 = mem_chunk; - p2 = chunk_list; - - do - { - if (p1 > p2) - { - if (m_next(p2) <= p2) - { /* We're at the top of the chain, p1 is - * higher */ - - if (p2 + m_size(p2) == p1) - { /* Good, stick 'em together */ - noise("INSERT CHUNK", mem_chunk); - m_size(p2) += m_size(p1); - noise("JOIN 1", p2); - } - else - { - m_next(p1) = m_next(p2); - m_next(p2) = p1; - noise("INSERT CHUNK", mem_chunk); - noise("FROM", p2); - } - return; - } - if (m_next(p2) > p1) - { - /* In chain, p1 between p2 and next */ - - m_next(p1) = m_next(p2); - m_next(p2) = p1; - noise("INSERT CHUNK", mem_chunk); - noise("FROM", p2); - - /* Try to join above */ - if (p1 + m_size(p1) == m_next(p1)) - { - m_size(p1) += m_size(m_next(p1)); - m_next(p1) = m_next(m_next(p1)); - noise("JOIN 2", p1); - } - /* Try to join below */ - if (p2 + m_size(p2) == p1) - { - m_size(p2) += m_size(p1); - m_next(p2) = m_next(p1); - noise("JOIN 3", p2); - } - chunk_list = p2; /* Make sure it's valid */ - return; - } - } - else if (p1 < p2) - { - if (m_next(p2) <= p2 && p1 < m_next(p2)) - { - /* At top of chain, next is bottom of chain, p1 is below next */ - - m_next(p1) = m_next(p2); - m_next(p2) = p1; - noise("INSERT CHUNK", mem_chunk); - noise("FROM", p2); - chunk_list = p2; - - if (p1 + m_size(p1) == m_next(p1)) - { - if (p2 == m_next(p1)) - chunk_list = p1; - m_size(p1) += m_size(m_next(p1)); - m_next(p1) = m_next(m_next(p1)); - noise("JOIN 4", p1); - } - return; - } - } - chunk_list = p2; /* Save for search */ - p2 = m_next(p2); - } - while (p2 != chunk_list); - - /* If we get here we have a problem, ignore it, maybe it'll go away */ - noise("DROPPED CHUNK", mem_chunk); -} - -/* - * This function will search for a chunk in memory of at least 'mem_size' - * when found, if the chunk is too big it'll be split, and pointer to the - * chunk returned. If none is found NULL is returned. - */ - -Static mem * -__search_chunk(mem_size) -unsigned int mem_size; -{ - register mem *p1, *p2; - if (chunk_list == 0) /* Simple case first */ - return 0; - - /* Search for a block >= the size we want */ - p1 = m_next(chunk_list); - p2 = chunk_list; - do - { - noise("CHECKED", p1); - if (m_size(p1) >= mem_size) - break; - - p2 = p1; - p1 = m_next(p1); - } - while (p2 != chunk_list); - - /* None found, exit */ - if (m_size(p1) < mem_size) - return 0; - - /* If it's exactly right remove it */ - if (m_size(p1) < mem_size + 2) - { - noise("FOUND RIGHT", p1); - chunk_list = m_next(p2) = m_next(p1); - if (chunk_list == p1) - chunk_list = 0; - return p1; - } - - noise("SPLIT", p1); - /* Otherwise split it */ - m_next(p2) = p1 + mem_size; - chunk_list = p2; - - p2 = m_next(p2); - m_size(p2) = m_size(p1) - mem_size; - m_next(p2) = m_next(p1); - m_size(p1) = mem_size; - if (chunk_list == p1) - chunk_list = p2; -#ifdef VERBOSE - p1[1].size = 0xAAAAAAAA; -#endif - noise("INSERT CHUNK", p2); - noise("FOUND CHUNK", p1); - noise("LIST IS", chunk_list); - return p1; -} - -#endif /* L_malloc */ - -#ifdef L_calloc -void * -calloc(elm, sz) -unsigned int elm, sz; -{ - register unsigned int v; - register void *ptr; - ptr = malloc(v = elm * sz); - if (ptr) - memset(ptr, 0, v); - return ptr; -} -#endif /* L_calloc */ - -#ifdef L_realloc -void * -realloc(ptr, size) -void *ptr; -size_t size; -{ - void *nptr; - unsigned int osize; - if (ptr == 0) - return malloc(size); - - osize = (m_size(((mem *) ptr) - 1) - 1) * sizeof(mem); - if (size <= osize) - { - return ptr; - } - - nptr = malloc(size); - - if (nptr == 0) - return 0; - - memcpy(nptr, ptr, osize); - free(ptr); - - return nptr; -} -#endif /* L_realloc */ diff -Nurd linux86.old/libc/malloc1/malloc.h linux86/libc/malloc1/malloc.h --- linux86.old/libc/malloc1/malloc.h Tue Jul 23 22:03:28 1996 +++ linux86/libc/malloc1/malloc.h Thu Jan 1 01:00:00 1970 @@ -1,30 +0,0 @@ - -#ifndef __MALLOC_H -#define __MALLOC_H -#include -#include - -/* - * Mini malloc allows you to use a less efficient but smaller malloc the - * cost is about 100 bytes of code in free but malloc (700bytes) doesn't - * have to be linked. Unfortunatly memory can only be reused if everything - * above it has been freed - * - */ - -extern void free __P((void *)); -extern void *malloc __P((size_t)); -extern void *realloc __P((void *, size_t)); -extern void *alloca __P((size_t)); - -extern void *(*__alloca_alloc) __P((size_t)); - -#ifdef __LIBC__ -#define __MINI_MALLOC__ -#endif - -#ifdef __MINI_MALLOC__ -#define malloc(x) ((*__alloca_alloc)(x)) -#endif - -#endif diff -Nurd linux86.old/libc/malloc2/Config linux86/libc/malloc2/Config --- linux86.old/libc/malloc2/Config Sun Feb 11 11:33:04 1996 +++ linux86/libc/malloc2/Config Thu Jan 1 01:00:00 1970 @@ -1 +0,0 @@ -malloc: Joel's malloc functions diff -Nurd linux86.old/libc/malloc2/Makefile linux86/libc/malloc2/Makefile --- linux86.old/libc/malloc2/Makefile Sat Mar 8 20:14:30 1997 +++ linux86/libc/malloc2/Makefile Thu Jan 1 01:00:00 1970 @@ -1,14 +0,0 @@ - -OBJ=malloc.o stack.o - -CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS) - -all: $(LIBC)($(OBJ)) - @$(RM) $(OBJ) - -clean: - rm -f *.o libc.a - -transfer: - -@rm ../include/malloc.h - cp -p malloc.h ../include/. diff -Nurd linux86.old/libc/malloc2/README linux86/libc/malloc2/README --- linux86.old/libc/malloc2/README Mon Jan 1 00:28:10 1996 +++ linux86/libc/malloc2/README Thu Jan 1 01:00:00 1970 @@ -1,19 +0,0 @@ -This is just the malloc for libc. It is untested; it won't even compile -right now. In particular, __malloc_init needs some bug fixing! - -Apparently, there is another malloc that Robert Debath wrote which probably -works by now. However, I honestly think that my malloc may be just as -good when it's finished. - -In about six months, you'll probably see something like this: - - -Linux/less-than-32-bit installation program -Do you want - 1. Chad Page's kernel - 2. Alan Cox's kernel -Enter your chioce --> 2 -Do you want - 1. Robert Debath's malloc - 2. Joel Weber's malloc -[more choices for compilers, filetools, etc] diff -Nurd linux86.old/libc/malloc2/malloc.c linux86/libc/malloc2/malloc.c --- linux86.old/libc/malloc2/malloc.c Fri Oct 25 19:55:26 1996 +++ linux86/libc/malloc2/malloc.c Thu Jan 1 01:00:00 1970 @@ -1,126 +0,0 @@ -/* simplified linux malloc.h - Copyright (C) 1995 Joel N. Weber II - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include - -typedef struct __malloc_struct malloc_struct; - -typedef union __malloc_union -{ - char *c; - malloc_struct *m; -} malloc_union; - - -struct __malloc_struct -{ - unsigned char status; -#define ALLOC 0x53 -#define FREE 0x55 -#define END_OF_WORLD 0x57 - malloc_union next; -} *malloc_start; - -extern int __STACKSIZE; - -/* WARNING: this init will only work if there is a hard limit on the - amount of RAM that can be allocated. - */ - -#ifdef __AS386_16__ -#asm - loc 1 ! Make sure the pointer is in the correct segment -auto_func: ! Label for bcc -M to work. - .word _malloc_init ! Pointer to the autorun function - .text ! So the function after is also in the correct seg. -#endasm -#endif - -malloc_init() -{ - extern unsigned int sbrk(); - - unsigned int ptr, sz, count; - - malloc_start = (malloc_struct*) ((sbrk(16)+1)&~1); - malloc_start->status = FREE; - - count=254; - for(sz=16384; sz>64; ) - { - ptr= sbrk(sz); - if( ptr == (unsigned)-1 ) sz>>=1; - else count+=sz; - } - if( __STACKSIZE > count || __STACKSIZE <= 0 ) __STACKSIZE = ((count>>1)&-2); - ptr = sbrk(-__STACKSIZE); - - malloc_start->next.m = ((malloc_struct*)ptr) - 1; - - malloc_start->next.m->status = END_OF_WORLD; -} - -char *malloc(size) -size_t size; -{ - register malloc_union tmp, tmp2; - - /* Make sure we don't lose the alignment */ - size = (size+sizeof(malloc_struct)-1)/sizeof(malloc_struct); - - tmp.m = malloc_start; - while ( ( tmp.m->next.m - tmp.m - 2 ) < size - || ( tmp.m->status == ALLOC )) - tmp.m = tmp.m->next.m; - - if (tmp.m->status == FREE){ - tmp2.m = size + tmp.m + 1; - tmp2.m->status = FREE; - tmp2.m->next.c = tmp.m->next.c; - tmp.m->status = ALLOC; - tmp.m->next.c = tmp2.c; - } - else return 0; - tmp.m++; - return tmp.c; -} - -__malloc_cleanup() /* finds consecutive free blocks and joins them */ -{ - malloc_struct *tmp; - - tmp = malloc_start; - while ((tmp->status != END_OF_WORLD)&&(tmp->next.m->status != END_OF_WORLD)){ - if ((tmp->status==FREE)&&(tmp->next.m->status==FREE)) - tmp->next.m = tmp->next.m->next.m; - else tmp = tmp->next.m; - } -} - -free(what) -char *what; -{ - malloc_union tmp; - - tmp.c = what; tmp.m--; - if( tmp.m->status == ALLOC ) - { - tmp.m->status = FREE; - __malloc_cleanup; - } -} diff -Nurd linux86.old/libc/malloc2/malloc.h linux86/libc/malloc2/malloc.h --- linux86.old/libc/malloc2/malloc.h Sat Feb 24 15:24:05 1996 +++ linux86/libc/malloc2/malloc.h Thu Jan 1 01:00:00 1970 @@ -1,21 +0,0 @@ -/* simplified linux malloc.h - Copyright (C) 1995 Joel N. Weber II - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -char *malloc(size); -void free(what); -char *realloc(what, size); diff -Nurd linux86.old/libc/malloc2/stack.c linux86/libc/malloc2/stack.c --- linux86.old/libc/malloc2/stack.c Fri Jan 5 22:40:30 1996 +++ linux86/libc/malloc2/stack.c Thu Jan 1 01:00:00 1970 @@ -1,10 +0,0 @@ - -/* - * Under Linux 8086 the stack and heap areas are at the top and bottom - * of the same area of memory, this version of malloc requires that the - * malloc area is of a fixed size this means that there must also be a - * specific amount of stack space reserved outside of this. The number - * of bytes to be reserved is specified below. - */ - -int __STACKSIZE = 2048; diff -Nurd linux86.old/libc/stdio/Config linux86/libc/stdio/Config --- linux86.old/libc/stdio/Config Thu Jan 1 01:00:00 1970 +++ linux86/libc/stdio/Config Sun Dec 3 09:32:23 2000 @@ -0,0 +1,4 @@ +# + +stdio: Stdio package + diff -Nurd linux86.old/libc/stdio/Makefile linux86/libc/stdio/Makefile --- linux86.old/libc/stdio/Makefile Thu Jan 1 01:00:00 1970 +++ linux86/libc/stdio/Makefile Sat Mar 8 20:16:05 1997 @@ -0,0 +1,49 @@ +# Copyright (C) 1995,1996 Robert de Bath +# This file is part of the Linux-8086 C library and is distributed +# under the GNU Library General Public License. + +ifneq ($(LIB_CPU),i86) +CFLAGS=$(CCFLAGS) $(LIBDEFS) -DFLOATS +endif + +ASRC=stdio.c +AOBJ=_stdio_init.o fputc.o fgetc.o fflush.o fgets.o gets.o fputs.o \ + puts.o fread.o fwrite.o fopen.o fclose.o fseek.o rewind.o ftell.o \ + setbuffer.o setvbuf.o ungetc.o + +PSRC=printf.c +POBJ=printf.o sprintf.o fprintf.o vprintf.o vsprintf.o vfprintf.o + +SSRC=scanf.c +SOBJ=scanf.o sscanf.o fscanf.o vscanf.o vsscanf.o vfscanf.o + +OBJ= $(AOBJ) $(POBJ) $(SOBJ) + +CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS) + +all: $(LIBC) + @$(RM) $(OBJ) + +$(LIBC): $(LIBC)($(OBJ)) + +$(LIBC)($(AOBJ)): $(ASRC) + $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o + $(AR) $(ARFLAGS) $@ $*.o + +$(LIBC)($(POBJ)): $(PSRC) + $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o + $(AR) $(ARFLAGS) $@ $*.o + +$(LIBC)($(SOBJ)): $(SSRC) + $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o + $(AR) $(ARFLAGS) $@ $*.o + +transfer: + -@rm -f ../include/stdio.h + cp -p stdio.h ../include/. + +clean: + rm -f *.o libc.a + +$(LIBC)($(OBJ)): stdio.h + diff -Nurd linux86.old/libc/stdio/printf.c linux86/libc/stdio/printf.c --- linux86.old/libc/stdio/printf.c Thu Jan 1 01:00:00 1970 +++ linux86/libc/stdio/printf.c Sun Oct 25 06:53:01 1998 @@ -0,0 +1,380 @@ +/* + * This file based on printf.c from 'Dlibs' on the atari ST (RdeBath) + * + * 19-OCT-88: Dale Schumacher + * > John Stanley has again been a great help in debugging, particularly + * > with the printf/scanf functions which are his creation. + * + * Dale Schumacher 399 Beacon Ave. + * (alias: Dalnefre') St. Paul, MN 55104 + * dal@syntel.UUCP United States of America + * "It's not reality that's important, but how you perceive things." + * + */ + +/* Altered to use stdarg, made the core function vfprintf. + * Hooked into the stdio package using 'inside information' + * Altered sizeof() assumptions, now assumes all integers except chars + * will be either + * sizeof(xxx) == sizeof(long) or sizeof(xxx) == sizeof(short) + * + * -RDB + */ + +#include +#include +#ifdef __STDC__ +#include +#define va_strt va_start +#else +#include +#define va_strt(p,i) va_start(p) +#endif + +#include "stdio.h" + +#ifdef L_printf + +#ifdef __STDC__ +int printf(const char * fmt, ...) +#else +int printf(fmt, va_alist) +__const char *fmt; +va_dcl +#endif +{ + va_list ptr; + int rv; + va_strt(ptr, fmt); + rv = vfprintf(stdout,fmt,ptr); + va_end(ptr); + return rv; +} +#endif + +#ifdef L_sprintf +#ifdef __STDC__ +int sprintf(char * sp, const char * fmt, ...) +#else +int sprintf(sp, fmt, va_alist) +char * sp; +__const char *fmt; +va_dcl +#endif +{ +static FILE string[1] = +{ + {0, 0, (char*)(unsigned) -1, 0, (char*) (unsigned) -1, -1, + _IOFBF | __MODE_WRITE} +}; + + va_list ptr; + int rv; + va_strt(ptr, fmt); + string->bufpos = sp; + rv = vfprintf(string,fmt,ptr); + va_end(ptr); + *(string->bufpos) = 0; + return rv; +} +#endif + +#ifdef L_fprintf +#ifdef __STDC__ +int fprintf(FILE * fp, const char * fmt, ...) +#else +int fprintf(fp, fmt, va_alist) +FILE * fp; +__const char *fmt; +va_dcl +#endif +{ + va_list ptr; + int rv; + va_strt(ptr, fmt); + rv = vfprintf(fp,fmt,ptr); + va_end(ptr); + return rv; +} +#endif + +#ifdef L_vprintf +int vprintf(fmt, ap) +__const char *fmt; +va_list ap; +{ + return vfprintf(stdout,fmt,ap); +} +#endif + +#ifdef L_vsprintf +int vsprintf(sp, fmt, ap) +char * sp; +__const char *fmt; +va_list ap; +{ +static FILE string[1] = +{ + {0, 0, (char*)(unsigned) -1, 0, (char*) (unsigned) -1, -1, + _IOFBF | __MODE_WRITE} +}; + + int rv; + string->bufpos = sp; + rv = vfprintf(string,fmt,ap); + *(string->bufpos) = 0; + return rv; +} +#endif + +#ifdef L_vfprintf + +#ifdef FLOATS +int (*__fp_print)() = 0; +#endif + +static int +prtfld(op, buf, ljustf, sign, pad, width, preci, buffer_mode) +register FILE *op; +register unsigned char *buf; +int ljustf; +register char sign; +char pad; +register int width; +int preci; +int buffer_mode; +/* + * Output the given field in the manner specified by the arguments. Return + * the number of characters output. + */ +{ + register int cnt = 0, len; + register unsigned char ch; + + len = strlen(buf); + + if (*buf == '-') + sign = *buf++; + else if (sign) + len++; + + if ((preci != -1) && (len > preci)) /* limit max data width */ + len = preci; + + if (width < len) /* flexible field width or width overflow */ + width = len; + + /* + * at this point: width = total field width len = actual data width + * (including possible sign character) + */ + cnt = width; + width -= len; + + while (width || len) + { + if (!ljustf && width) /* left padding */ + { + if (len && sign && (pad == '0')) + goto showsign; + ch = pad; + --width; + } + else if (len) + { + if (sign) + { + showsign:ch = sign; /* sign */ + sign = '\0'; + } + else + ch = *buf++; /* main field */ + --len; + } + else + { + ch = pad; /* right padding */ + --width; + } + putc(ch, op); + if( ch == '\n' && buffer_mode == _IOLBF ) fflush(op); + } + + return (cnt); +} + +int +vfprintf(op, fmt, ap) +FILE *op; +register __const char *fmt; +register va_list ap; +{ + register int i, cnt = 0, ljustf, lval; + int preci, dpoint, width; + char pad, sign, radix, hash; + register char *ptmp; + char tmp[64], *ltostr(), *ultostr(); + int buffer_mode; + + /* This speeds things up a bit for unbuffered */ + buffer_mode = (op->mode&__MODE_BUF); + op->mode &= (~__MODE_BUF); + + while (*fmt) + { + if (*fmt == '%') + { + if( buffer_mode == _IONBF ) fflush(op); + ljustf = 0; /* left justify flag */ + sign = '\0'; /* sign char & status */ + pad = ' '; /* justification padding char */ + width = -1; /* min field width */ + dpoint = 0; /* found decimal point */ + preci = -1; /* max data width */ + radix = 10; /* number base */ + ptmp = tmp; /* pointer to area to print */ + hash = 0; + lval = (sizeof(int)==sizeof(long)); /* long value flaged */ + fmtnxt: + i = 0; + for(;;) + { + ++fmt; + if(*fmt < '0' || *fmt > '9' ) break; + i = (i * 10) + (*fmt - '0'); + if (dpoint) + preci = i; + else if (!i && (pad == ' ')) + { + pad = '0'; + goto fmtnxt; + } + else + width = i; + } + + switch (*fmt) + { + case '\0': /* early EOS */ + --fmt; + goto charout; + + case '-': /* left justification */ + ljustf = 1; + goto fmtnxt; + + case ' ': + case '+': /* leading sign flag */ + sign = *fmt; + goto fmtnxt; + + case '*': /* parameter width value */ + i = va_arg(ap, int); + if (dpoint) + preci = i; + else + width = i; + goto fmtnxt; + + case '.': /* secondary width field */ + dpoint = 1; + goto fmtnxt; + + case 'l': /* long data */ + lval = 1; + goto fmtnxt; + + case 'h': /* short data */ + lval = 0; + goto fmtnxt; + + case 'd': /* Signed decimal */ + case 'i': + ptmp = ltostr((long) ((lval) + ? va_arg(ap, long) + : va_arg(ap, short)), + 10); + goto printit; + + case 'b': /* Unsigned binary */ + radix = 2; + goto usproc; + + case 'o': /* Unsigned octal */ + radix = 8; + goto usproc; + + case 'p': /* Pointer */ + lval = (sizeof(char*) == sizeof(long)); + pad = '0'; + width = 6; + preci = 8; + /* fall thru */ + + case 'x': /* Unsigned hexadecimal */ + case 'X': + radix = 16; + /* fall thru */ + + case 'u': /* Unsigned decimal */ + usproc: + ptmp = ultostr((unsigned long) ((lval) + ? va_arg(ap, unsigned long) + : va_arg(ap, unsigned short)), + radix); + if( hash && radix == 8 ) { width = strlen(ptmp)+1; pad='0'; } + goto printit; + + case '#': + hash=1; + goto fmtnxt; + + case 'c': /* Character */ + ptmp[0] = va_arg(ap, int); + ptmp[1] = '\0'; + goto nopad; + + case 's': /* String */ + ptmp = va_arg(ap, char*); + nopad: + sign = '\0'; + pad = ' '; + printit: + cnt += prtfld(op, ptmp, ljustf, + sign, pad, width, preci, buffer_mode); + break; + +#if FLOATS + case 'e': /* float */ + case 'f': + case 'g': + case 'E': + case 'G': + if ( __fp_print ) + { + (*__fp_print)(&va_arg(ap, double), *fmt, preci, ptmp); + preci = -1; + goto printit; + } + /* FALLTHROUGH if no floating printf available */ +#endif + + default: /* unknown character */ + goto charout; + } + } + else + { + charout: + putc(*fmt, op); /* normal char out */ + ++cnt; + if( *fmt == '\n' && buffer_mode == _IOLBF ) fflush(op); + } + ++fmt; + } + op->mode |= buffer_mode; + if( buffer_mode == _IONBF ) fflush(op); + if( buffer_mode == _IOLBF ) op->bufwrite = op->bufstart; + return (cnt); +} +#endif diff -Nurd linux86.old/libc/stdio/scanf.c linux86/libc/stdio/scanf.c --- linux86.old/libc/stdio/scanf.c Thu Jan 1 01:00:00 1970 +++ linux86/libc/stdio/scanf.c Sat Sep 19 12:20:16 1998 @@ -0,0 +1,536 @@ +/* + * This file based on scanf.c from 'Dlibs' on the atari ST (RdeBath) + * + * 19-OCT-88: Dale Schumacher + * > John Stanley has again been a great help in debugging, particularly + * > with the printf/scanf functions which are his creation. + * + * Dale Schumacher 399 Beacon Ave. + * (alias: Dalnefre') St. Paul, MN 55104 + * dal@syntel.UUCP United States of America + * "It's not reality that's important, but how you perceive things." + * + */ + +#include +#include +#include + +#ifdef __STDC__ +#include +#define va_strt va_start +#else +#include +#define va_strt(p,i) va_start(p) +#endif + +#ifdef L_scanf +#ifdef __STDC__ +int scanf(const char * fmt, ...) +#else +int scanf(fmt, va_alist) +__const char *fmt; +va_dcl +#endif +{ + va_list ptr; + int rv; + va_strt(ptr, fmt); + rv = vfscanf(stdin,fmt,ptr); + va_end(ptr); + return rv; +} +#endif + +#ifdef L_sscanf +#ifdef __STDC__ +int sscanf(char * sp, const char * fmt, ...) +#else +int sscanf(sp, fmt, va_alist) +char * sp; +__const char *fmt; +va_dcl +#endif +{ +static FILE string[1] = +{ + {0, (char*)(unsigned) -1, 0, 0, (char*) (unsigned) -1, -1, + _IOFBF | __MODE_READ} +}; + + va_list ptr; + int rv; + va_strt(ptr, fmt); + string->bufpos = sp; + rv = vfscanf(string,fmt,ptr); + va_end(ptr); + return rv; +} +#endif + +#ifdef L_fscanf +#ifdef __STDC__ +int fscanf(FILE * fp, const char * fmt, ...) +#else +int fscanf(fp, fmt, va_alist) +FILE * fp; +__const char *fmt; +va_dcl +#endif +{ + va_list ptr; + int rv; + va_strt(ptr, fmt); + rv = vfscanf(fp,fmt,ptr); + va_end(ptr); + return rv; +} +#endif + +#ifdef L_vscanf +int vscanf(fmt, ap) +__const char *fmt; +va_list ap; +{ + return vfscanf(stdin,fmt,ap); +} +#endif + +#ifdef L_vsscanf +int vsscanf(sp, fmt, ap) +char * sp; +__const char *fmt; +{ +static FILE string[1] = +{ + {0, (char*)(unsigned) -1, 0, 0, (char*) (unsigned) -1, -1, + _IOFBF | __MODE_READ} +}; + + string->bufpos = sp; + return vfscanf(string,fmt,ap); +} +#endif + +#ifdef L_vfscanf +/* #define skip() do{c=getc(fp); if (c<1) goto done;}while(isspace(c))*/ + +#define skip() while(isspace(c)) { if ((c=getc(fp))<1) goto done; } + +#if FLOATS +/* fp scan actions */ +#define F_NADA 0 /* just change state */ +#define F_SIGN 1 /* set sign */ +#define F_ESIGN 2 /* set exponent's sign */ +#define F_INT 3 /* adjust integer part */ +#define F_FRAC 4 /* adjust fraction part */ +#define F_EXP 5 /* adjust exponent part */ +#define F_QUIT 6 + +#define NSTATE 8 +#define FS_INIT 0 /* initial state */ +#define FS_SIGNED 1 /* saw sign */ +#define FS_DIGS 2 /* saw digits, no . */ +#define FS_DOT 3 /* saw ., no digits */ +#define FS_DD 4 /* saw digits and . */ +#define FS_E 5 /* saw 'e' */ +#define FS_ESIGN 6 /* saw exp's sign */ +#define FS_EDIGS 7 /* saw exp's digits */ + +#define FC_DIG 0 +#define FC_DOT 1 +#define FC_E 2 +#define FC_SIGN 3 + +/* given transition,state do what action? */ +int fp_do[][NSTATE] = { + {F_INT,F_INT,F_INT, + F_FRAC,F_FRAC, + F_EXP,F_EXP,F_EXP}, /* see digit */ + {F_NADA,F_NADA,F_NADA, + F_QUIT,F_QUIT,F_QUIT,F_QUIT,F_QUIT}, /* see '.' */ + {F_QUIT,F_QUIT, + F_NADA,F_QUIT,F_NADA, + F_QUIT,F_QUIT,F_QUIT}, /* see e/E */ + {F_SIGN,F_QUIT,F_QUIT,F_QUIT,F_QUIT, + F_ESIGN,F_QUIT,F_QUIT}, /* see sign */ +}; +/* given transition,state what is new state? */ +int fp_ns[][NSTATE] = { + {FS_DIGS,FS_DIGS,FS_DIGS, + FS_DD,FS_DD, + FS_EDIGS,FS_EDIGS,FS_EDIGS}, /* see digit */ + {FS_DOT,FS_DOT,FS_DD, + }, /* see '.' */ + {0,0, + FS_E,0,FS_E, + }, /* see e/E */ + {FS_SIGNED,0,0,0,0, + FS_ESIGN,0,0}, /* see sign */ +}; +/* which states are valid terminators? */ +int fp_sval[NSTATE] = { + 0,0,1,0,1,0,0,1 +}; +#endif + +vfscanf(fp, fmt, ap) +register FILE *fp; +register char *fmt; +va_list ap; + +{ + register long n; + register int c, width, lval, cnt = 0; + int store, neg, base, wide1, endnull, rngflag, c2; + register unsigned char *p; + unsigned char delim[128], digits[17], *q; +#if FLOATS + long frac, expo; + int eneg, fraclen, fstate, trans; + double fx, fp_scan(); +#endif + + if (!*fmt) + return (0); + + c = getc(fp); + while (c > 0) + { + store = 0; + if (*fmt == '%') + { + n = 0; + width = -1; + wide1 = 1; + base = 10; + lval = (sizeof(long) == sizeof(int)); + store = 1; + endnull = 1; + neg = -1; + + strcpy(delim, "\011\012\013\014\015 "); + strcpy(digits, "0123456789ABCDEF"); + + if (fmt[1] == '*') + { + endnull = store = 0; + ++fmt; + } + + while (isdigit(*++fmt))/* width digit(s) */ + { + if (width == -1) + width = 0; + wide1 = width = (width * 10) + (*fmt - '0'); + } + --fmt; + fmtnxt: + ++fmt; + switch (tolower(*fmt)) /* tolower() is a MACRO! */ + { + case '*': + endnull = store = 0; + goto fmtnxt; + + case 'l': /* long data */ + lval = 1; + goto fmtnxt; + case 'h': /* short data */ + lval = 0; + goto fmtnxt; + + case 'i': /* any-base numeric */ + base = 0; + goto numfmt; + + case 'b': /* unsigned binary */ + base = 2; + goto numfmt; + + case 'o': /* unsigned octal */ + base = 8; + goto numfmt; + + case 'x': /* unsigned hexadecimal */ + base = 16; + goto numfmt; + + case 'd': /* SIGNED decimal */ + neg = 0; + /* FALL-THRU */ + + case 'u': /* unsigned decimal */ + numfmt:skip(); + + if (isupper(*fmt)) + lval = 1; + + if (!base) + { + base = 10; + neg = 0; + if (c == '%') + { + base = 2; + goto skip1; + } + else if (c == '0') + { + c = getc(fp); + if (c < 1) + goto savnum; + if ((c != 'x') + && (c != 'X')) + { + base = 8; + digits[8] = '\0'; + goto zeroin; + } + base = 16; + goto skip1; + } + } + + if ((neg == 0) && (base == 10) + && ((neg = (c == '-')) || (c == '+'))) + { + skip1: + c = getc(fp); + if (c < 1) + goto done; + } + + digits[base] = '\0'; + p = ((unsigned char *) + strchr(digits, toupper(c))); + + if ((!c || !p) && width) + goto done; + + while (p && width-- && c) + { + n = (n * base) + (p - digits); + c = getc(fp); + zeroin: + p = ((unsigned char *) + strchr(digits, toupper(c))); + } + savnum: + if (store) + { + if (neg == 1) + n = -n; + if (lval) + *va_arg(ap, long*) = n; + else + *va_arg(ap, short*) = n; + ++cnt; + } + break; + +#if FLOATS + case 'e': /* float */ + case 'f': + case 'g': + skip(); + + if (isupper(*fmt)) + lval = 1; + + fstate = FS_INIT; + neg = 0; + eneg = 0; + n = 0; + frac = 0; + expo = 0; + fraclen = 0; + + while (c && width--) + { + if (c >= '0' && c <= '9') + trans = FC_DIG; + else if (c == '.') + trans = FC_DOT; + else if (c == '+' || c == '-') + trans = FC_SIGN; + else if (tolower(c) == 'e') + trans = FC_E; + else + goto fdone; + + switch (fp_do[trans][fstate]) + { + case F_SIGN: + neg = (c == '-'); + break; + case F_ESIGN: + eneg = (c == '-'); + break; + case F_INT: + n = 10 * n + (c - '0'); + break; + case F_FRAC: + frac = 10 * frac + (c - '0'); + fraclen++; + break; + case F_EXP: + expo = 10 * expo + (c - '0'); + break; + case F_QUIT: + goto fdone; + } + fstate = fp_ns[trans][fstate]; + c = getc(fp); + } + + fdone: + if (!fp_sval[fstate]) + goto done; + if (store) + { + fx = fp_scan(neg, eneg, n, frac, expo, fraclen); + if (lval) + *va_arg(ap, double *) = fx; + else + *va_arg(ap, float *) = fx; + ++cnt; + } + break; +#endif + + case 'c': /* character data */ + width = wide1; + lval = endnull = 0; + delim[0] = '\0'; + goto strproc; + + case '[': /* string w/ delimiter set */ + + /* get delimiters */ + p = delim; + + if (*++fmt == '^') + { + fmt++; + lval = 0; + } + else + lval = 1; + + rngflag = 2; + if ((*fmt == ']') || (*fmt == '-')) + { + *p++ = *fmt++; + rngflag = 0; + } + + while (*fmt != ']') + { + if (*fmt == '\0') + goto done; + switch (rngflag) + { + case 1: + c2 = *(p - 2); + if (c2 <= *fmt) + { + p -= 2; + while (c2 < *fmt) + *p++ = c2++; + rngflag = 2; + break; + } + /* fall thru intentional */ + + case 0: + rngflag = (*fmt == '-'); + break; + + case 2: + rngflag = 0; + } + + *p++ = *fmt++; + } + + *p = '\0'; + goto strproc; + + case 's': /* string data */ + lval = 0; + skip(); + strproc: + /* process string */ + p = va_arg(ap, unsigned char *); + + /* if the 1st char fails, match fails */ + if (width) + { + q = ((unsigned char *) + strchr(delim, c)); + if ((c < 1) || lval == (q==0)) + { + if (endnull) + *p = '\0'; + goto done; + } + } + + for (;;) /* FOREVER */ + { + if (store) + *p++ = c; + if (((c = getc(fp)) < 1) || + (--width == 0)) + break; + + q = ((unsigned char *) + strchr(delim, c)); + if (lval == (q==0)) + break; + } + + if (store) + { + if (endnull) + *p = '\0'; + ++cnt; + } + break; + + case '\0': /* early EOS */ + --fmt; + /* FALL THRU */ + + default: + goto cmatch; + } + } + else if (isspace(*fmt)) /* skip whitespace */ + { + skip(); + } + else + { /* normal match char */ + cmatch: + if (c != *fmt) + break; + c = getc(fp); + } + + if (!*++fmt) + break; + } + + done: /* end of scan */ + if ((c == EOF) && (cnt == 0)) + return (EOF); + + if( c != EOF ) + ungetc(c, fp); + return (cnt); +} + +#endif + diff -Nurd linux86.old/libc/stdio/stdio.c linux86/libc/stdio/stdio.c --- linux86.old/libc/stdio/stdio.c Thu Jan 1 01:00:00 1970 +++ linux86/libc/stdio/stdio.c Tue Mar 9 14:54:35 1999 @@ -0,0 +1,866 @@ +/* Copyright (C) 1996 Robert de Bath + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* This is an implementation of the C standard IO package. + */ + +#include + +#include +#include +#include +#include + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +extern FILE *__IO_list; /* For fflush at exit */ + +#ifdef __AS386_16__ +#define Inline_init +#endif + +#ifdef __AS386_32__ +#define Inline_init +#endif + +#ifndef Inline_init +#define Inline_init __io_init_vars() +#endif + +#ifdef L__stdio_init + +#define buferr (stderr->unbuf) /* Stderr is unbuffered */ + +FILE *__IO_list = 0; /* For fflush at exit */ + +static char bufin[BUFSIZ]; +static char bufout[BUFSIZ]; +#ifndef buferr +static char buferr[BUFSIZ]; +#endif + +FILE stdin[1] = +{ + {bufin, bufin, bufin, bufin, bufin + sizeof(bufin), + 0, _IOFBF | __MODE_READ | __MODE_IOTRAN} +}; + +FILE stdout[1] = +{ + {bufout, bufout, bufout, bufout, bufout + sizeof(bufout), + 1, _IOFBF | __MODE_WRITE | __MODE_IOTRAN} +}; + +FILE stderr[1] = +{ + {buferr, buferr, buferr, buferr, buferr + sizeof(buferr), + 2, _IONBF | __MODE_WRITE | __MODE_IOTRAN} +}; + +/* Call the stdio initiliser; it's main job it to call atexit */ + +#ifdef __AS386_16__ +#define STATIC static + +#asm + loc 1 ! Make sure the pointer is in the correct segment +auto_func: ! Label for bcc -M to work. + .word ___io_init_vars ! Pointer to the autorun function + .text ! So the function after is also in the correct seg. +#endasm +#endif + +#ifdef __AS386_32__ +#define STATIC static + +#asm + loc 1 ! Make sure the pointer is in the correct segment +auto_func: ! Label for bcc -M to work. + .long ___io_init_vars ! Pointer to the autorun function + .text ! So the function after is also in the correct seg. +#endasm +#endif + +#ifndef STATIC +#define STATIC +#endif + +STATIC int +__stdio_close_all() +{ + FILE *fp; + fflush(stdout); + fflush(stderr); + for (fp = __IO_list; fp; fp = fp->next) + { + fflush(fp); + close(fp->fd); + /* Note we're not de-allocating the memory */ + /* There doesn't seem to be much point :-) */ + fp->fd = -1; + } +} + +STATIC void +__io_init_vars() +{ +#ifndef __AS386_16__ +#ifndef __AS386_32__ + static int first_time = 1; + if( !first_time ) return ; + first_time = 0; +#endif +#endif + if (isatty(1)) + stdout->mode |= _IOLBF; + atexit(__stdio_close_all); +} +#endif + +#ifdef L_fputc +int +fputc(ch, fp) +int ch; +FILE *fp; +{ + register int v; + Inline_init; + + /* If last op was a read ... note fflush may change fp->mode and ret OK */ + if ((fp->mode & __MODE_READING) && fflush(fp)) + return EOF; + + v = fp->mode; + /* Can't write if there's been an EOF or error then return EOF */ + if ((v & (__MODE_WRITE | __MODE_EOF | __MODE_ERR)) != __MODE_WRITE) + return EOF; + + /* In MSDOS translation mode */ +#if __MODE_IOTRAN && !O_BINARY + if (ch == '\n' && (v & __MODE_IOTRAN) && fputc('\r', fp) == EOF) + return EOF; +#endif + + /* Buffer is full */ + if (fp->bufpos >= fp->bufend && fflush(fp)) + return EOF; + + /* Right! Do it! */ + *(fp->bufpos++) = ch; + fp->mode |= __MODE_WRITING; + + /* Unbuffered or Line buffered and end of line */ + if (((ch == '\n' && (v & _IOLBF)) || (v & _IONBF)) + && fflush(fp)) + return EOF; + + /* Can the macro handle this by itself ? */ + if (v & (__MODE_IOTRAN | _IOLBF | _IONBF)) + fp->bufwrite = fp->bufstart; /* Nope */ + else + fp->bufwrite = fp->bufend; /* Yup */ + + /* Correct return val */ + return (unsigned char) ch; +} +#endif + +#ifdef L_fgetc +int +fgetc(fp) +FILE *fp; +{ + int ch; + + if (fp->mode & __MODE_WRITING) + fflush(fp); + + try_again: + /* Can't read or there's been an EOF or error then return EOF */ + if ((fp->mode & (__MODE_READ | __MODE_EOF | __MODE_ERR)) != __MODE_READ) + return EOF; + + /* Nothing in the buffer - fill it up */ + if (fp->bufpos >= fp->bufread) + { + /* Bind stdin to stdout if it's open and line buffered */ + if( fp == stdin && stdout->fd >= 0 && (stdout->mode & _IOLBF )) + fflush(stdout); + + fp->bufpos = fp->bufread = fp->bufstart; + ch = fread(fp->bufpos, 1, fp->bufend - fp->bufstart, fp); + if (ch == 0) + return EOF; + fp->bufread += ch; + fp->mode |= __MODE_READING; + fp->mode &= ~__MODE_UNGOT; + } + ch = *(fp->bufpos++); + +#if __MODE_IOTRAN && !O_BINARY + /* In MSDOS translation mode; WARN: Doesn't work with UNIX macro */ + if (ch == '\r' && (fp->mode & __MODE_IOTRAN)) + goto try_again; +#endif + + return ch; +} +#endif + +#ifdef L_fflush +int +fflush(fp) +FILE *fp; +{ + int len, cc, rv=0; + char * bstart; + if (fp == NULL) /* On NULL flush the lot. */ + { + if (fflush(stdin)) + return EOF; + if (fflush(stdout)) + return EOF; + if (fflush(stderr)) + return EOF; + + for (fp = __IO_list; fp; fp = fp->next) + if (fflush(fp)) + return EOF; + + return 0; + } + + /* If there's output data pending */ + if (fp->mode & __MODE_WRITING) + { + len = fp->bufpos - fp->bufstart; + + if (len) + { + bstart = fp->bufstart; + /* + * The loop is so we don't get upset by signals or partial writes. + */ + do + { + cc = write(fp->fd, bstart, len); + if( cc > 0 ) + { + bstart+=cc; len-=cc; + } + } + while ( len>0 && (cc>0 || (cc == -1 && errno == EINTR))); + /* + * If we get here with len!=0 there was an error, exactly what to + * do about it is another matter ... + * + * I'll just clear the buffer. + */ + if (len) + { + fp->mode |= __MODE_ERR; + rv = EOF; + } + } + } + /* If there's data in the buffer sychronise the file positions */ + else if (fp->mode & __MODE_READING) + { + /* Humm, I think this means sync the file like fpurge() ... */ + /* Anyway the user isn't supposed to call this function when reading */ + + len = fp->bufread - fp->bufpos; /* Bytes buffered but unread */ + /* If it's a file, make it good */ + if (len > 0 && lseek(fp->fd, (long)-len, 1) < 0) + { + /* Hummm - Not certain here, I don't think this is reported */ + /* + * fp->mode |= __MODE_ERR; return EOF; + */ + } + } + + /* All done, no problem */ + fp->mode &= (~(__MODE_READING|__MODE_WRITING|__MODE_EOF|__MODE_UNGOT)); + fp->bufread = fp->bufwrite = fp->bufpos = fp->bufstart; + return rv; +} +#endif + +#ifdef L_fgets +/* Nothing special here ... */ +char * +fgets(s, count, f) +char *s; +size_t count; +FILE *f; +{ + char *ret; + register size_t i; + register int ch; + + ret = s; + for (i = count-1; i > 0; i--) + { + ch = getc(f); + if (ch == EOF) + { + if (s == ret) + return 0; + break; + } + *s++ = (char) ch; + if (ch == '\n') + break; + } + *s = 0; + + if (ferror(f)) + return 0; + return ret; +} +#endif + +#ifdef L_gets +char * +gets(str) /* BAD function; DON'T use it! */ +char *str; +{ + /* Auwlright it will work but of course _your_ program will crash */ + /* if it's given a too long line */ + register char *p = str; + register int c; + + while (((c = getc(stdin)) != EOF) && (c != '\n')) + *p++ = c; + *p = '\0'; + return (((c == EOF) && (p == str)) ? NULL : str); /* NULL == EOF */ +} +#endif + +#ifdef L_fputs +int +fputs(str, fp) +char *str; +FILE *fp; +{ + register int n = 0; + while (*str) + { + if (putc(*str++, fp) == EOF) + return (EOF); + ++n; + } + return (n); +} +#endif + +#ifdef L_puts +int +puts(str) +char *str; +{ + register int n; + + if (((n = fputs(str, stdout)) == EOF) + || (putc('\n', stdout) == EOF)) + return (EOF); + return (++n); +} +#endif + +#ifdef L_fread +/* + * fread will often be used to read in large chunks of data calling read() + * directly can be a big win in this case. Beware also fgetc calls this + * function to fill the buffer. + * + * This ignores __MODE__IOTRAN; probably exactly what you want. (It _is_ what + * fgetc wants) + */ +int +fread(buf, size, nelm, fp) +char *buf; +int size; +int nelm; +FILE *fp; +{ + int len, v; + unsigned bytes, got = 0; + Inline_init; + + v = fp->mode; + + /* Want to do this to bring the file pointer up to date */ + if (v & __MODE_WRITING) + fflush(fp); + + /* Can't read or there's been an EOF or error then return zero */ + if ((v & (__MODE_READ | __MODE_EOF | __MODE_ERR)) != __MODE_READ) + return 0; + + /* This could be long, doesn't seem much point tho */ + bytes = size * nelm; + + len = fp->bufread - fp->bufpos; + if (len >= bytes) /* Enough buffered */ + { + memcpy(buf, fp->bufpos, (unsigned) bytes); + fp->bufpos += bytes; + return nelm; + } + else if (len > 0) /* Some buffered */ + { + memcpy(buf, fp->bufpos, len); + fp->bufpos += len; + got = len; + } + + /* Need more; do it with a direct read */ + len = read(fp->fd, buf + got, (unsigned) (bytes - got)); + + /* Possibly for now _or_ later */ + if (len < 0) + { + fp->mode |= __MODE_ERR; + len = 0; + } + else if (len == 0) + fp->mode |= __MODE_EOF; + + return (got + len) / size; +} +#endif + +#ifdef L_fwrite +/* + * Like fread, fwrite will often be used to write out large chunks of + * data; calling write() directly can be a big win in this case. + * + * But first we check to see if there's space in the buffer. + * + * Again this ignores __MODE__IOTRAN. + */ +int +fwrite(buf, size, nelm, fp) +char *buf; +int size; +int nelm; +FILE *fp; +{ + register int v; + int len; + unsigned bytes, put; + + /* If last op was a read ... note fflush may change fp->mode and ret OK */ + if ((fp->mode & __MODE_READING) && fflush(fp)) + return 0; + + v = fp->mode; + /* Can't write or there's been an EOF or error then return 0 */ + if ((v & (__MODE_WRITE | __MODE_EOF | __MODE_ERR)) != __MODE_WRITE) + return 0; + + /* This could be long, doesn't seem much point tho */ + bytes = size * nelm; + + len = fp->bufend - fp->bufpos; + + /* Flush the buffer if not enough room */ + if (bytes > len) + if (fflush(fp)) + return 0; + + len = fp->bufend - fp->bufpos; + if (bytes <= len) /* It'll fit in the buffer ? */ + { + register int do_flush=0; + fp->mode |= __MODE_WRITING; + memcpy(fp->bufpos, buf, bytes); + if (v & _IOLBF) + { + if(memchr(fp->bufpos, '\n', bytes)) + do_flush=1; + } + fp->bufpos += bytes; + + /* If we're unbuffered or line buffered and have seen nl */ + if (do_flush || (v & _IONBF) != 0) + fflush(fp); + + return nelm; + } + else + /* Too big for the buffer */ + { + put = bytes; + do + { + len = write(fp->fd, buf, bytes); + if( len > 0 ) + { + buf+=len; bytes-=len; + } + } + while (len > 0 || (len == -1 && errno == EINTR)); + + if (len < 0) + fp->mode |= __MODE_ERR; + + put -= bytes; + } + + return put / size; +} +#endif + +#ifdef L_rewind +void +rewind(fp) +FILE * fp; +{ + fseek(fp, (long)0, 0); + clearerr(fp); +} +#endif + +#ifdef L_fseek +int +fseek(fp, offset, ref) +FILE *fp; +long offset; +int ref; +{ +#if 1 + /* if __MODE_READING and no ungetc ever done can just move pointer */ + + if ( (fp->mode &(__MODE_READING | __MODE_UNGOT)) == __MODE_READING && + ( ref == SEEK_SET || ref == SEEK_CUR )) + { + long fpos = lseek(fp->fd, 0L, SEEK_CUR); + if( fpos == -1 ) return EOF; + + if( ref == SEEK_CUR ) + { + ref = SEEK_SET; + offset = fpos + offset + fp->bufpos - fp->bufread; + } + if( ref == SEEK_SET ) + { + if ( offset < fpos && offset >= fpos + fp->bufstart - fp->bufread ) + { + fp->bufpos = offset - fpos + fp->bufread; + return 0; + } + } + } +#endif + + /* Use fflush to sync the pointers */ + + if (fflush(fp) == EOF) + return EOF; + if (lseek(fp->fd, offset, ref) < 0) + return EOF; + return 0; +} +#endif + +#ifdef L_ftell +long ftell(fp) +FILE * fp; +{ + long rv; + if (fflush(fp) == EOF) + return EOF; + return lseek(fp->fd, 0L, SEEK_CUR); +} +#endif + +#ifdef L_fopen +/* + * This Fopen is all three of fopen, fdopen and freopen. The macros in + * stdio.h show the other names. + */ +FILE * +__fopen(fname, fd, fp, mode) +char *fname; +int fd; +FILE *fp; +char *mode; +{ + int open_mode = 0; +#if __MODE_IOTRAN && !O_BINARY + int do_iosense = 1; +#endif + int fopen_mode = 0; + FILE *nfp = 0; + + /* If we've got an fp close the old one (freopen) */ + if (fp) + { + /* Careful, don't de-allocate it */ + fopen_mode |= (fp->mode & (__MODE_BUF | __MODE_FREEFIL | __MODE_FREEBUF)); + fp->mode &= ~(__MODE_FREEFIL | __MODE_FREEBUF); + fclose(fp); + } + + /* decode the new open mode */ + while (*mode) + switch (*mode++) + { + case 'r': + fopen_mode |= __MODE_READ; + break; + case 'w': + fopen_mode |= __MODE_WRITE; + open_mode = (O_CREAT | O_TRUNC); + break; + case 'a': + fopen_mode |= __MODE_WRITE; + open_mode = (O_CREAT | O_APPEND); + break; + case '+': + fopen_mode |= __MODE_RDWR; + break; +#if __MODE_IOTRAN || O_BINARY + case 'b': /* Binary */ + fopen_mode &= ~__MODE_IOTRAN; + open_mode |= O_BINARY; +#if __MODE_IOTRAN && !O_BINARY + do_iosense=0; +#endif + break; + case 't': /* Text */ + fopen_mode |= __MODE_IOTRAN; +#if __MODE_IOTRAN && !O_BINARY + do_iosense=0; +#endif + break; +#endif + } + + /* Add in the read/write options to mode for open() */ + switch (fopen_mode & (__MODE_READ | __MODE_WRITE)) + { + case 0: + return 0; + case __MODE_READ: + open_mode |= O_RDONLY; + break; + case __MODE_WRITE: + open_mode |= O_WRONLY; + break; + default: + open_mode |= O_RDWR; + break; + } + + /* Allocate the (FILE) before we do anything irreversable */ + if (fp == 0) + { + nfp = malloc(sizeof(FILE)); + if (nfp == 0) + return 0; + } + + /* Open the file itself */ + if (fname) + fd = open(fname, open_mode, 0666); + if (fd < 0) /* Grrrr */ + { + if (nfp) + free(nfp); + if (fp) + { + fp->mode |= fopen_mode; + fclose(fp); /* Deallocate if required */ + } + return 0; + } + + /* If this isn't freopen create a (FILE) and buffer for it */ + if (fp == 0) + { + fp = nfp; + fp->next = __IO_list; + __IO_list = fp; + + fp->mode = __MODE_FREEFIL; + if( isatty(fd) ) + { + fp->mode |= _IOLBF; +#if __MODE_IOTRAN && !O_BINARY + if( do_iosense ) fopen_mode |= __MODE_IOTRAN; +#endif + } + else + fp->mode |= _IOFBF; + fp->bufstart = malloc(BUFSIZ); + if (fp->bufstart == 0) /* Oops, no mem */ + { /* Humm, full buffering with a two(!) byte + * buffer. */ + fp->bufstart = fp->unbuf; + fp->bufend = fp->unbuf + sizeof(fp->unbuf); + } + else + { + fp->bufend = fp->bufstart + BUFSIZ; + fp->mode |= __MODE_FREEBUF; + } + } + + /* Ok, file's ready clear the buffer and save important bits */ + fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart; + fp->mode |= fopen_mode; + fp->fd = fd; + + return fp; +} +#endif + +#ifdef L_fclose +int +fclose(fp) +FILE *fp; +{ + int rv = 0; + + if (fp == 0) + { + errno = EINVAL; + return EOF; + } + if (fp->fd != -1) + { + if (fflush(fp)) + return EOF; + + if (close(fp->fd)) + rv = EOF; + fp->fd = -1; + } + + if (fp->mode & __MODE_FREEBUF) + { + free(fp->bufstart); + fp->mode &= ~__MODE_FREEBUF; + fp->bufstart = fp->bufend = 0; + } + + if (fp->mode & __MODE_FREEFIL) + { + FILE *prev = 0, *ptr; + fp->mode = 0; + + for (ptr = __IO_list; ptr && ptr != fp; ptr = ptr->next) + ; + if (ptr == fp) + { + if (prev == 0) + __IO_list = fp->next; + else + prev->next = fp->next; + } + free(fp); + } + else + fp->mode = 0; + + return rv; +} +#endif + +#ifdef L_setbuffer +void +setbuffer(fp, buf, size) +FILE * fp; +char * buf; +int size; +{ + fflush(fp); + if( fp->mode & __MODE_FREEBUF ) free(fp->bufstart); + fp->mode &= ~(__MODE_FREEBUF|__MODE_BUF); + + if( buf == 0 ) + { + fp->bufstart = fp->unbuf; + fp->bufend = fp->unbuf + sizeof(fp->unbuf); + fp->mode |= _IONBF; + } + else + { + fp->bufstart = buf; + fp->bufend = buf+size; + fp->mode |= _IOFBF; + } + fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart; +} +#endif + +#ifdef L_setvbuf +int setvbuf(fp, buf, mode, size) +FILE * fp; +char * buf; +int mode; +size_t size; +{ + int rv = 0; + fflush(fp); + if( fp->mode & __MODE_FREEBUF ) free(fp->bufstart); + fp->mode &= ~(__MODE_FREEBUF|__MODE_BUF); + fp->bufstart = fp->unbuf; + fp->bufend = fp->unbuf + sizeof(fp->unbuf); + fp->mode |= _IONBF; + + if( mode == _IOFBF || mode == _IOLBF ) + { + if( size <= 0 ) size = BUFSIZ; + if( buf == 0 ) + { + if( (buf = malloc(size)) != 0 ) + fp->mode |= __MODE_FREEBUF; + else rv = EOF; + } + if( buf ) + { + fp->bufstart = buf; + fp->bufend = buf+size; + fp->mode &= ~__MODE_BUF; + fp->mode |= mode; + } + } + fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart; + return rv; +} +#endif + +#ifdef L_ungetc +int +ungetc(c, fp) +int c; +FILE *fp; +{ + if (fp->mode & __MODE_WRITING) + fflush(fp); + + /* Can't read or there's been an error then return EOF */ + if ((fp->mode & (__MODE_READ | __MODE_ERR)) != __MODE_READ) + return EOF; + + /* Can't do fast fseeks */ + fp->mode |= __MODE_UNGOT; + + if( fp->bufpos > fp->bufstart ) + return *--fp->bufpos = (unsigned char) c; + else if( fp->bufread == fp->bufstart ) + return *fp->bufread++ = (unsigned char) c; + else + return EOF; +} +#endif + diff -Nurd linux86.old/libc/stdio/stdio.h linux86/libc/stdio/stdio.h --- linux86.old/libc/stdio/stdio.h Thu Jan 1 01:00:00 1970 +++ linux86/libc/stdio/stdio.h Mon Feb 1 08:36:35 1999 @@ -0,0 +1,129 @@ + +#ifndef __STDIO_H +#define __STDIO_H + +#include +#include + +#ifndef SEEK_SET +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#define _IOFBF 0x00 /* full buffering */ +#define _IOLBF 0x01 /* line buffering */ +#define _IONBF 0x02 /* no buffering */ +#define __MODE_BUF 0x03 /* Modal buffering dependent on isatty */ + +#define __MODE_FREEBUF 0x04 /* Buffer allocated with malloc, can free */ +#define __MODE_FREEFIL 0x08 /* FILE allocated with malloc, can free */ + +#define __MODE_READ 0x10 /* Opened in read only */ +#define __MODE_WRITE 0x20 /* Opened in write only */ +#define __MODE_RDWR 0x30 /* Opened in read/write */ + +#define __MODE_READING 0x40 /* Buffer has pending read data */ +#define __MODE_WRITING 0x80 /* Buffer has pending write data */ + +#define __MODE_EOF 0x100 /* EOF status */ +#define __MODE_ERR 0x200 /* Error status */ +#define __MODE_UNGOT 0x400 /* Buffer has been polluted by ungetc */ + +#ifdef __MSDOS__ +#define __MODE_IOTRAN 0x1000 /* MSDOS nl <-> cr,nl translation */ +#else +#define __MODE_IOTRAN 0 +#endif + +/* when you add or change fields here, be sure to change the initialization + * in stdio_init and fopen */ +struct __stdio_file { + unsigned char *bufpos; /* the next byte to write to or read from */ + unsigned char *bufread; /* the end of data returned by last read() */ + unsigned char *bufwrite; /* highest address writable by macro */ + unsigned char *bufstart; /* the start of the buffer */ + unsigned char *bufend; /* the end of the buffer; ie the byte after the last + malloc()ed byte */ + + int fd; /* the file descriptor associated with the stream */ + int mode; + + char unbuf[8]; /* The buffer for 'unbuffered' streams */ + + struct __stdio_file * next; +}; + +#define EOF (-1) +#ifndef NULL +#define NULL ((void*)0) +#endif + +typedef struct __stdio_file FILE; + +#ifdef __AS386_16__ +#define BUFSIZ (256) +#else +#define BUFSIZ (2048) +#endif + +extern FILE stdin[1]; +extern FILE stdout[1]; +extern FILE stderr[1]; + +#ifdef __MSDOS__ +#define putc(c, fp) fputc(c, fp) +#define getc(fp) fgetc(fp) +#else +#define putc(c, stream) \ + (((stream)->bufpos >= (stream)->bufwrite) ? fputc((c), (stream)) \ + : (unsigned char) (*(stream)->bufpos++ = (c)) ) + +#define getc(stream) \ + (((stream)->bufpos >= (stream)->bufread) ? fgetc(stream): \ + (*(stream)->bufpos++)) +#endif + +#define putchar(c) putc((c), stdout) +#define getchar() getc(stdin) + +#define ferror(fp) (((fp)->mode&__MODE_ERR) != 0) +#define feof(fp) (((fp)->mode&__MODE_EOF) != 0) +#define clearerr(fp) ((fp)->mode &= ~(__MODE_EOF|__MODE_ERR),0) +#define fileno(fp) ((fp)->fd) + +/* declare functions; not like it makes much difference without ANSI */ +/* RDB: The return values _are_ important, especially if we ever use + 8086 'large' model + */ + +/* These two call malloc */ +#define setlinebuf(__fp) setvbuf((__fp), (char*)0, _IOLBF, 0) +extern int setvbuf __P((FILE*, char*, int, size_t)); + +/* These don't */ +#define setbuf(__fp, __buf) setbuffer((__fp), (__buf), BUFSIZ) +extern void setbuffer __P((FILE*, char*, int)); + +extern int fgetc __P((FILE*)); +extern int fputc __P((int, FILE*)); + +extern int fclose __P((FILE*)); +extern int fflush __P((FILE*)); +extern char *fgets __P((char*, size_t, FILE*)); +extern FILE *__fopen __P((char*, int, FILE*, char*)); + +#define fopen(__file, __mode) __fopen((__file), -1, (FILE*)0, (__mode)) +#define freopen(__file, __mode, __fp) __fopen((__file), -1, (__fp), (__mode)) +#define fdopen(__file, __mode) __fopen((char*)0, (__file), (FILE*)0, (__mode)) + +extern int fputs __P((char*, FILE*)); +extern int puts __P((char*)); + +extern int printf __P ((__const char*, ...)); +extern int fprintf __P ((FILE*, __const char*, ...)); +extern int sprintf __P ((char*, __const char*, ...)); + +#define stdio_pending(fp) ((fp)->bufread>(fp)->bufpos) + +#endif /* __STDIO_H */ diff -Nurd linux86.old/libc/stdio1/BUGS linux86/libc/stdio1/BUGS --- linux86.old/libc/stdio1/BUGS Mon Jan 1 03:38:49 1996 +++ linux86/libc/stdio1/BUGS Thu Jan 1 01:00:00 1970 @@ -1,15 +0,0 @@ -Error checking is known to be wanting. However the author just wants to -get it working right now. - -fread() and fwrite() are not supported. open(), read(), write(), and close() -work very well for binary data. - -fopen() is the only way to open a file. None of the temp stuff is supported, -and frepon() is unsupported. - -GNU extensions are unsupported. - -Some printf specifications may not work. Read the code for details of what -IS supported. - -Other than that, this should be a perfectly normal stdio lib when it's finished. diff -Nurd linux86.old/libc/stdio1/Config linux86/libc/stdio1/Config --- linux86.old/libc/stdio1/Config Tue Feb 13 22:39:59 1996 +++ linux86/libc/stdio1/Config Thu Jan 1 01:00:00 1970 @@ -1,3 +0,0 @@ - - -stdio: Joel's stdio package altered by Nat diff -Nurd linux86.old/libc/stdio1/NOTICE linux86/libc/stdio1/NOTICE --- linux86.old/libc/stdio1/NOTICE Mon Jan 1 03:18:44 1996 +++ linux86/libc/stdio1/NOTICE Thu Jan 1 01:00:00 1970 @@ -1,17 +0,0 @@ -/* - Copyright (C) 1996 Joel N. Weber II - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ diff -Nurd linux86.old/libc/stdio1/README linux86/libc/stdio1/README --- linux86.old/libc/stdio1/README Sat Dec 14 15:38:00 1996 +++ linux86/libc/stdio1/README Thu Jan 1 01:00:00 1970 @@ -1,8 +0,0 @@ -I found that it was helpful to have the extern stuff actually defined in -one file as not external... - -Still trying to find the other problems - -Whether it is desireable to list stdio.h as a dependency is debateable - --Joel diff -Nurd linux86.old/libc/stdio1/TODO linux86/libc/stdio1/TODO --- linux86.old/libc/stdio1/TODO Tue Jan 23 01:49:11 1996 +++ linux86/libc/stdio1/TODO Thu Jan 1 01:00:00 1970 @@ -1,33 +0,0 @@ -Sun Jan 21 18:16:03 EST 1996 -- Nat Friedman -============================================ -I've made a load of changes to this code, but there's still a lot to be done. -- scanf, fscanf - - - - -input, file positioning, eof, declarations of functions, printf - -look for unsigned char references - -specifically -fix printf and figure out what's going on in there. -write idealgetline, scanf, other stuff -then deal with above stuff... - - -LATEST LIST: -printf, fprintf -scanf, fscanf -feof -seek support -error handling (not too hard since system calls only in a few places) -atexit stuff (close files; will need to add a linked list of files) -setvbuf if desired -check that fopen() and stdio_init() fill in ALL the fields -testing! - -rm NOTICE - - - diff -Nurd linux86.old/libc/stdio1/__ffillbuf.c linux86/libc/stdio1/__ffillbuf.c --- linux86.old/libc/stdio1/__ffillbuf.c Sun Jan 21 22:39:34 1996 +++ linux86/libc/stdio1/__ffillbuf.c Thu Jan 1 01:00:00 1970 @@ -1,55 +0,0 @@ -/* simplified linux __ffillbuf.c - Copyright (C) 1995 Joel N. Weber II - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include -#include "stdio.h" - -/* this function makes the mistake of assuming the buffer really DOES -need to be filled. */ - -/* RDB: - * Added simple processing for EOF and errors - * As this is _only_ called from getc() the memory footprint is smaller - * if it pretends to be getc in the complex case. - */ - -int -__ffillbuf(stream) -FILE *stream; -{ - int stat; - - if( stream->fd < 0 || ferror(stream) ) return EOF; - - stat = read(stream->fd, (char *) stream->bufstart, stream->bufend - stream->bufstart); - if( stat > 0 ) - stream->bufread = stream->bufstart + stat; - else if( stat == 0 ) - { - stream->fc_eof = 1; - return EOF; - } - else - { - stream->fc_err = 1; - return EOF; - } - - stream->bufpos = stream->bufstart; - - return getc(stream); -} diff -Nurd linux86.old/libc/stdio1/__stdio_init.c linux86/libc/stdio1/__stdio_init.c --- linux86.old/libc/stdio1/__stdio_init.c Mon Jan 8 23:42:47 1996 +++ linux86/libc/stdio1/__stdio_init.c Thu Jan 1 01:00:00 1970 @@ -1,66 +0,0 @@ -/* simplified linux __stdio_init.c - Copyright (C) 1995 Joel N. Weber II - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include "stdio.h" - -/* - OK, Complete hackup here, I've removed the need for the init function. - Not also I've make the types into 'unsigned char' this is so it doesn't - return EOF when it really means '\377' - */ - -static unsigned char __stdinbuf[BUFSIZ], __stdoutbuf[BUFSIZ], __stderrbuf[80]; - -static FILE __the_stdin = { - 0, - __stdinbuf, - __stdinbuf, - __stdinbuf, - __stdinbuf+sizeof(__stdinbuf), - _IOLBF, - _MODE_READ, - 0, 0, - 0, 0, 1 -}; - -static FILE __the_stdout = { - 1, - __stdoutbuf, - __stdoutbuf, - __stdoutbuf, - __stdoutbuf+sizeof(__stdoutbuf), - _IOLBF, - _MODE_WRITE, - 0, 0, - 0, 0, 1 -}; - -static FILE __the_stderr = { - 2, - __stderrbuf, - __stderrbuf, - __stderrbuf, - __stderrbuf+sizeof(__stderrbuf), - _IOLBF, - _MODE_WRITE, - 0, 0, - 0, 0, 1 -}; - -FILE *stdin = &__the_stdin, - *stdout = &__the_stdout, - *stderr = &__the_stderr; diff -Nurd linux86.old/libc/stdio1/fclose.c linux86/libc/stdio1/fclose.c --- linux86.old/libc/stdio1/fclose.c Sun Jan 21 22:36:52 1996 +++ linux86/libc/stdio1/fclose.c Thu Jan 1 01:00:00 1970 @@ -1,41 +0,0 @@ -/* simplified linux fclose.c - Copyright (C) 1995 Joel N. Weber II - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include -#include "stdio.h" - -int fclose (stream) -FILE *stream; -{ - /* only allow fclose() on what was fopen()ed. */ - /* - This isn't right, there's nothing wrong with fclosing stdin - but the next fopen/open will be given fd 0 and so become stdin - Of course you do have to be a little careful :-) - RDB - */ - - if ((stream == stdin) || (stream == stdout) || (stream == stderr)) return EOF; - - if (fflush(stream)) return EOF; - - if (close(stream->fd)) return EOF; - - free(stream->bufstart); - free(stream); - return 0; -} diff -Nurd linux86.old/libc/stdio1/fcntl.h linux86/libc/stdio1/fcntl.h --- linux86.old/libc/stdio1/fcntl.h Mon Jan 1 22:47:03 1996 +++ linux86/libc/stdio1/fcntl.h Thu Jan 1 01:00:00 1970 @@ -1,72 +0,0 @@ -#ifndef __FCNTL_H -#define __FCNTL_H - -/* - * Definitions taken from the i386 Linux kernel. - */ - -/* open/fcntl */ - -#define O_ACCMODE 0003 -#define O_RDONLY 00 -#define O_WRONLY 01 -#define O_RDWR 02 -#define O_CREAT 0100 /* not fcntl */ -#define O_EXCL 0200 /* not fcntl */ -#define O_NOCTTY 0400 /* not fcntl */ -#define O_TRUNC 01000 /* not fcntl */ -#define O_APPEND 02000 -#define O_NONBLOCK 04000 -#define O_NDELAY O_NONBLOCK -#if 0 -#define O_SYNC 010000 /* Not supported */ -#define FASYNC 020000 /* Not supported */ -#endif - -#define F_DUPFD 0 /* dup */ -#define F_GETFD 1 /* get f_flags */ -#define F_SETFD 2 /* set f_flags */ -#define F_GETFL 3 /* more flags (cloexec) */ -#define F_SETFL 4 -#define F_GETLK 5 -#define F_SETLK 6 -#define F_SETLKW 7 - -#define F_SETOWN 8 /* for sockets. */ -#define F_GETOWN 9 /* for sockets. */ - -/* for F_[GET|SET]FL */ -#define FD_CLOEXEC 1 /* actually anything with low bit set goes */ - -/* for posix fcntl() and lockf() */ -#define F_RDLCK 0 -#define F_WRLCK 1 -#define F_UNLCK 2 - -/* for old implementation of bsd flock () */ -#define F_EXLCK 4 /* or 3 */ -#define F_SHLCK 8 /* or 4 */ - -/* operations for bsd flock(), also used by the kernel implementation */ -#define LOCK_SH 1 /* shared lock */ -#define LOCK_EX 2 /* exclusive lock */ -#define LOCK_NB 4 /* or'd with one of the above to prevent - blocking */ -#define LOCK_UN 8 /* remove lock */ - -#ifdef __KERNEL__ -#define F_POSIX 1 -#define F_FLOCK 2 -#endif /* __KERNEL__ */ - -#if 0 -struct flock { - short l_type; - short l_whence; - off_t l_start; - off_t l_len; - pid_t l_pid; -}; -#endif - -#endif diff -Nurd linux86.old/libc/stdio1/fflush.c linux86/libc/stdio1/fflush.c --- linux86.old/libc/stdio1/fflush.c Sun Jan 21 22:39:56 1996 +++ linux86/libc/stdio1/fflush.c Thu Jan 1 01:00:00 1970 @@ -1,36 +0,0 @@ -/* simplified linux fflush.c - Copyright (C) 1995 Joel N. Weber II - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include "stdio.h" - -int fflush(stream) -FILE *stream; -{ - if (stream == 0) return 0; - if ((stream->file_mode == _MODE_WRITE) - ||(stream->file_mode == (_MODE_WRITE & _MODE_RDWR))){ - write(stream->fd, (char *) stream->bufstart, - stream->bufpos - stream->bufstart); - stream->bufpos = stream->bufstart; - } - return 0; -} -/* TODO: return EOF or 0; support NULL stream */ -/* The only place an error can come from is the write; you're not checking RDB - */ diff -Nurd linux86.old/libc/stdio1/fgetc.c linux86/libc/stdio1/fgetc.c --- linux86.old/libc/stdio1/fgetc.c Fri Jan 5 20:38:43 1996 +++ linux86/libc/stdio1/fgetc.c Thu Jan 1 01:00:00 1970 @@ -1,39 +0,0 @@ -/* - Copyright (C) 1996 Joel N. Weber II - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "stdio.h" - -/* - * Make this not dependent on getc() then we can: - #define getc(fp) fgetc(fp) - * if memory is _really_ tight. - */ - -int fgetc(stream) -FILE *stream; -{ - if( stream->ungetted ) - { - stream->ungetted = 0; - return stream->ungetchar; - } - if( stream->bufpos == stream->bufread ) - return __ffillbuf(stream); - else - return *stream->bufpos++; -} diff -Nurd linux86.old/libc/stdio1/fgets.c linux86/libc/stdio1/fgets.c --- linux86.old/libc/stdio1/fgets.c Sun Jan 14 17:50:09 1996 +++ linux86/libc/stdio1/fgets.c Thu Jan 1 01:00:00 1970 @@ -1,50 +0,0 @@ -/* fgets.c for limited linux stdio - Copyright (C) 1996 Joel N. Weber II - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "stdio.h" - -/* - RDB BZZZT! This should only read upto and including any newline! -*/ - -char *fgets(s, count, f) -char *s; -size_t count; -FILE *f; -{ - char *ret; - register size_t i; - register int ch; - - ret = s; - for(i=count; i>0; i--) - { - ch = getc(f); - if( ch == EOF ) - { - if(s==ret) return 0; - break; - } - *s++ = (char) ch; - if( ch == '\n' ) break; - } - *s = 0; - - if( ferror(f) ) return 0; - return ret; -} diff -Nurd linux86.old/libc/stdio1/fopen.c linux86/libc/stdio1/fopen.c --- linux86.old/libc/stdio1/fopen.c Mon Jan 8 23:55:34 1996 +++ linux86/libc/stdio1/fopen.c Thu Jan 1 01:00:00 1970 @@ -1,80 +0,0 @@ -/* simplified linux fopen.c - Copyright (C) 1995 Joel N. Weber II - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include "stdio.h" -#include - -FILE * fopen(name, openmode) -char *name; -char *openmode; -{ - FILE *new; - int openplus=0; - char basemode; - - basemode = openmode[0]; - while (openmode[0] != 0){ - switch(openmode[0]){ - case '+': openplus=1; break; - } - openmode++; - } - - new = malloc(sizeof(new)); - if( new == 0 ) return 0; - new->bufread = new->bufpos = new->bufstart = malloc(BUFSIZ); - if( new->bufstart == 0 ) { free(new) ; return 0; } - - new->bufend = new->bufstart + BUFSIZ; - new->buffer_mode = _IOFBF; - new->iotrans = 0; - new->fd = -1; - if (openplus){ - new->file_mode = _MODE_RDWR; - switch (basemode){ - case 'a': - new->fd = open(name, O_RDWR | O_APPEND | O_CREAT); - break; - case 'r': - new->fd = open(name, O_RDWR); - break; - case 'w': - new->fd = open(name, O_RDWR | O_TRUNC | O_CREAT); - break; - } - } else switch (basemode){ - case 'a': - new->fd = open(name, O_WRONLY | O_APPEND | O_CREAT); - new->file_mode = _MODE_WRITE; - break; - case 'r': - new->fd = open(name, O_RDONLY); - new->file_mode = _MODE_READ; - break; - case 'w': - new->fd = open(name, O_WRONLY | O_TRUNC | O_CREAT); - new->file_mode = _MODE_WRITE; - break; - } - if( new->fd < 0 ) - { - free(new->bufstart); - free(new); - return 0; - } - return new; -} diff -Nurd linux86.old/libc/stdio1/fputc.c linux86/libc/stdio1/fputc.c --- linux86.old/libc/stdio1/fputc.c Mon Jan 22 07:51:19 1996 +++ linux86/libc/stdio1/fputc.c Thu Jan 1 01:00:00 1970 @@ -1,53 +0,0 @@ -/* simplified linux fputc.c - Copyright (C) 1995 Joel N. Weber II - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include "stdio.h" - -/* - * Make this not dependent on putc() then we can: - #define putc(c, fp) fputc(c, fp) - * if memory is _really_ tight. - */ - -#undef putc -#define putc(c, stream) \ - (((stream)->bufpos[0] = (c)), \ - ((stream)->bufpos++), \ - ((((stream)->bufpos == (stream)->bufend) \ - ||((stream)->buffer_mode == _IONBF) \ - ||(((stream)->buffer_mode == _IOLBF) \ - && ((stream)->bufpos != (stream)->bufstart) \ - && ((stream)->bufpos[-1] == '\n'))) \ - ? fflush(stream):0)) - -#define new_putc(c, stream) \ - ((unsigned char)( \ - ((stream)->bufpos>=(stream)->bufread) ? fputc((c), (stream)) \ - : *(stream)->bufpos++ = (c) \ - )) - -int -fputc(int c, FILE * stream) -{ -#ifdef __MSDOS__ - if( c == '\n' && stream->iotrans ) fputc('\r', stream); -#endif - return putc(c, stream); -} - - - diff -Nurd linux86.old/libc/stdio1/fputs.c linux86/libc/stdio1/fputs.c --- linux86.old/libc/stdio1/fputs.c Sun Jan 21 23:18:52 1996 +++ linux86/libc/stdio1/fputs.c Thu Jan 1 01:00:00 1970 @@ -1,32 +0,0 @@ -/* simplified linux fputs.c - Copyright (C) 1995 Joel N. Weber II - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include -#include -#include "stdio.h" - -int -fputs(__const char * string, FILE * stream) -{ - if (stream->buffer_mode != _IONBF){ - while (string[0] != 0){ - putc(string[0], stream); - string++; - } - } else write(stream->fd, string, strlen(string)); - return 0; -} diff -Nurd linux86.old/libc/stdio1/idealgetline.c linux86/libc/stdio1/idealgetline.c --- linux86.old/libc/stdio1/idealgetline.c Fri Jan 5 20:49:51 1996 +++ linux86/libc/stdio1/idealgetline.c Thu Jan 1 01:00:00 1970 @@ -1,67 +0,0 @@ -/* idealgetline.c -- my idea of an ideal getline function for stdio - Copyright (C) 1996 Joel N. Weber II - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* I actually intend to use this in 32 bit programs, unlike the other stuff - in this lib. IMHO GNU getline is broken. It is too hard to use. - - Just pass this function a FILE * and it will retrieve a line for you using - getc(). It will realloc() exactly the amount of memory needed, and will - generate error messages for non-ascii characters on stderr. - - This may not be your ideal. It probably generates far too many errors. - It doesn't work well for those who don't use English (but since - Linux-less-than-32 libc and kernels are each being produced by one - person in the US and one in the UK, this isn't a problem). It probably - is not what you (or I) want for interactive input. - - You're welcome to modify this routine to meet your needs. However, if - you change the semantics significantly, please change the name. - - (Maybe I should have put my own name on it so there will be no confusion - about who thought it was ideal). */ - -#include -#include - -char *idealgetline(f) -FILE *f; -{ - char c; - char *ret; - int size = 0, bufsize = 256; - - ret = malloc(256); - c = getc(f); - while ((c != EOF) && (c != '\n')){ - if ((c >= ' ') && (c <= 126)){ - ret[size] = c; - size++; - if (size == bufsize){ - bufsize += 256; - ret = realloc(ret, bufsize); - } - } else { - fprintf(stderr, "Unexpected character 0x%x encountered in input", c); - free(ret); - return 0; - } - } - ret[size] = '\0'; - size++; - return realloc(ret, size); -} diff -Nurd linux86.old/libc/stdio1/makefile linux86/libc/stdio1/makefile --- linux86.old/libc/stdio1/makefile Wed Mar 20 21:12:07 1996 +++ linux86/libc/stdio1/makefile Thu Jan 1 01:00:00 1970 @@ -1,36 +0,0 @@ -TOP=.. -include $(TOP)/Make.defs -OBJ = __ffillbuf.o __stdio_init.o fflush.o fgetc.o fgets.o \ - fputc.o fputs.o puts.o printf.o fopen.o fclose.o scanf.o - -#missing functions from above: printf etc, scanf etc, idealgetline -#seek - -#fopen.c, fclose.c removed because of malloc() use - -CFLAGS+=$(WALL) - -ifeq ($(PLATFORM),i86-ELKS) -CFLAGS=$(CCFLAGS) $(DEFS) -ansi -endif - -all: $(OBJ) - -libc.a: $(OBJ) - ar r ../$(LIBC) $(OBJ) - @touch libc.a - -$(OBJ): stdio.h - -test: test.o $(OBJ) - $(CC) -o test test.o $(OBJ) - -%.o: %.c - $(CC) $(CFLAGS) -o $@ $< -c - -clean: - rm -f *.o test libc.a - -transfer: - -@rm -f ../include/stdio.h - cp -p stdio.h ../include/. diff -Nurd linux86.old/libc/stdio1/old_printf.c linux86/libc/stdio1/old_printf.c --- linux86.old/libc/stdio1/old_printf.c Tue Feb 13 06:43:07 1996 +++ linux86/libc/stdio1/old_printf.c Thu Jan 1 01:00:00 1970 @@ -1,230 +0,0 @@ -/* fprintf.c for limited Linux libc - Copyright (C) 1996 Joel N. Weber II - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -/* Thanks Alan for writing the hard routine for me :-) - * Alan said that this works "most of the time". Something tells me I'm making - * it even worse! */ -/* The basic idea here is to make fprintf the core routine. printf obviously - can just call fprintf with stdout followed by all of its arguments. - sprintf() works using the fake file &the_sprintf. It's marked as fully - buffered, so that it will only write(2) when &the_sprintf->bufpos == - &the_sprintf->bufend, which I doubt will happen since &the_sprintf->bufend - = 0. The trick is that sprintf must set &the_sprintf->bufstart = - &the_sprintf->bufpos = its first argument. Not as orthagonal (is that - the right word?) as glibc's facilities for non-files, but this isn't a - library for people who have unlimited RAM budgets. (not like the libc - I use on linux/i586 enjoys an unlimited RAM budget either; I only have - 8 MB - - I'm not sure what the "correct" way to pass the variable arguments - from one function to the next is. Rather than pass the arguments - themselves, I'm passing a pointer to them. However, the following - explaination from Alan is probably a polite way of saying it will not - work on a 386 anyway. - Joel Weber - - [ I've migrated all of this code over to the ELKS stdarg that I wrote. - The accepted way to do it is for the wrapper function to accept a - variable number of arguments, use stdarg to make an argument pointer, - and then pass the argument pointer on to the core function, as I've - done here. This should definitely work on a 386, as the arguments - are still passed in the stack, and stack order is maintained. -Nat ] - */ - -/* - * This is NOT stunningly portable, but works - * for pretty dumb non ANSI compilers and is - * tight. Adjust the sizes to taste. - * - * Illegal format strings will break it. Only the - * following simple subset is supported - * - * %x - hex - * %d - decimal - * %s - string - * %c - char - * - * And the h/l length specifiers for %d/%x - * - * Alan Cox. - */ - -#include -#include "stdio.h" - -/* 17 to make sure that there's room for the trailing newline. - I'm not really sure if this is ideal... */ -static char nstring[17]="0123456789ABCDEF"; - -static unsigned char * -__numout(long i, int base) -{ - static unsigned char out[16]; - int n; - int flg = 0; - unsigned long val; - - if (i<0 && base==10) - { - flg = 1; - i = -i; - } - val = i; - - for (n = 0; n < 15; n++) - out[n] = ' '; - out[15] = '\0'; - n = 14; - do{ - out[n] = nstring[val % base]; - n--; - val /= base; - } - while(val); - if(flg) out[n--] = '-'; - return &out[n+1]; -} - -static int -internal_fprintf(FILE * stream, __const char * fmt, va_list ap) -{ - register int c; - int count = 0; - int type, base; - - while(c=*fmt++) - { - if(c!='%') - { - putc(c, stream); - count++; - } - else - { - type=1; - do { c=*fmt++; } while( c=='.' || (c>='0' && c<='9')); - if( c == 0 ) break; - if(c=='h') - { - c=*fmt++; - type = 0; - } - else if(c=='l') - { - c=*fmt++; - type = 2; - } - - switch(c) - { - case 'x': - case 'o': - case 'd': - if (c=='x') base=16; - if (c=='o') base=8; - if (c=='d') base=10; - { - long val=0; - switch(type) - { - case 0: - val=va_arg(ap, short); - break; - case 1: - val=va_arg(ap, int); - break; - case 2: - val=va_arg(ap, long); - break; - } - fputs((__const char *)__numout(val,base),stream); - } - break; - case 's': - { - char *cp; - cp=va_arg(ap, char *); - while(*cp) - putc(*cp++, stream); - break; - } - case 'c': - putc(va_arg(ap, int), stream); - break; - default: - putc(c, stream); - } - } - } - return count; -} - - -int -fprintf(FILE * stream, __const char * fmt, ...) -{ - va_list ap; - int retval; - va_start(ap, fmt); - retval=internal_fprintf(stream, fmt, ap); - va_end(ap); - return(retval); -} - -int -printf(__const char * fmt, ...) -{ - va_list ap; - int retval; - va_start(ap, fmt); - retval=internal_fprintf(stdout, fmt, ap); - va_end(ap); - return(retval); -} - -/* This is a strange way of doing sprintf, but it should work */ -int sprintf(char * s, __const char * fmt, ...) -{ - static FILE the_sprintf = { - -1, - 0, - 0, - 0, - 0, - _IOFBF, - _MODE_WRITE, - 0, 0, - 0, 0}; - va_list ap; - int retval; - - va_start(ap, fmt); - the_sprintf.bufstart = the_sprintf.bufpos = (unsigned char *) s; - the_sprintf.fc_err = 0; - - retval = internal_fprintf(&the_sprintf, fmt, ap); - /* null-terminate the string */ - putc('\0', &the_sprintf); - - va_end(ap); - return retval; -} - - - - - diff -Nurd linux86.old/libc/stdio1/printf.c linux86/libc/stdio1/printf.c --- linux86.old/libc/stdio1/printf.c Sat Feb 24 12:56:19 1996 +++ linux86/libc/stdio1/printf.c Thu Jan 1 01:00:00 1970 @@ -1,649 +0,0 @@ -/* fprintf.c for limited Linux libc - Copyright (C) 1996 Joel N. Weber II - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -/* Thanks Alan for writing the hard routine for me :-) - * Alan said that this works "most of the time". Something tells me I'm making - * it even worse! */ -/* The basic idea here is to make fprintf the core routine. printf obviously - can just call fprintf with stdout followed by all of its arguments. - sprintf() works using the fake file &the_sprintf. It's marked as fully - buffered, so that it will only write(2) when &the_sprintf->bufpos == - &the_sprintf->bufend, which I doubt will happen since &the_sprintf->bufend - = 0. The trick is that sprintf must set &the_sprintf->bufstart = - &the_sprintf->bufpos = its first argument. Not as orthagonal (is that - the right word?) as glibc's facilities for non-files, but this isn't a - library for people who have unlimited RAM budgets. (not like the libc - I use on linux/i586 enjoys an unlimited RAM budget either; I only have - 8 MB - - I'm not sure what the "correct" way to pass the variable arguments - from one function to the next is. Rather than pass the arguments - themselves, I'm passing a pointer to them. However, the following - explaination from Alan is probably a polite way of saying it will not - work on a 386 anyway. - Joel Weber - - [ I've migrated all of this code over to the ELKS stdarg that I wrote. - The accepted way to do it is for the wrapper function to accept a - variable number of arguments, use stdarg to make an argument pointer, - and then pass the argument pointer on to the core function, as I've - done here. This should definitely work on a 386, as the arguments - are still passed in the stack, and stack order is maintained. -Nat ] - */ - -/* - * This is NOT stunningly portable, but works - * for pretty dumb non ANSI compilers and is - * tight. Adjust the sizes to taste. - * - * Illegal format strings will break it. Only the - * following simple subset is supported - * - * %x - hex - * %d - decimal - * %s - string - * %c - char - * - * And the h/l length specifiers for %d/%x - * - * Alan Cox. - */ - -#include -#include "stdio.h" - -/* 17 to make sure that there's room for the trailing newline. - I'm not really sure if this is ideal... */ -static char nstring[17]="0123456789ABCDEF"; - -static unsigned char * -__numout(long i, int base) -{ - static unsigned char out[16]; - int n; - int flg = 0; - unsigned long val; - - if (i<0 && base==10) - { - flg = 1; - i = -i; - } - val = i; - - for (n = 0; n < 15; n++) - out[n] = ' '; - out[15] = '\0'; - n = 14; - do{ - out[n] = nstring[val % base]; - n--; - val /= base; - } - while(val); - if(flg) out[n--] = '-'; - return &out[n+1]; -} - -int -fprintf(FILE * stream, __const char * fmt, ...) -{ - va_list ap; - int retval; - va_start(ap, fmt); - retval=internal_fprintf(stream, fmt, ap); - va_end(ap); - return(retval); -} - -int -printf(__const char * fmt, ...) -{ - va_list ap; - int retval; - va_start(ap, fmt); - retval=internal_fprintf(stdout, fmt, ap); - va_end(ap); - return(retval); -} - -/* This is a strange way of doing sprintf, but it should work */ -int sprintf(char * s, __const char * fmt, ...) -{ - static FILE the_sprintf = { - -1, - 0, - 0, - 0, - 0, - _IOFBF, - _MODE_WRITE, - 0, 0, - 0, 0}; - va_list ap; - int retval; - - va_start(ap, fmt); - the_sprintf.bufstart = the_sprintf.bufpos = (unsigned char *) s; - the_sprintf.fc_err = 0; - - retval = internal_fprintf(&the_sprintf, fmt, ap); - /* null-terminate the string */ - putc('\0', &the_sprintf); - - va_end(ap); - return retval; -} - - - - - -/* - * printf.c - This is the more complete fprintf() replacement for libc8086 - * Copyright (C) 1996 Steven Huang . - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include - -/* - * This decides if the little test main program gets included - */ -#undef TEST -/* - * This decides if printf() should act like standard. When undefined, - * - prints out "(err)" if a bad format is encountered - * - supports the %b (binary) format - */ -#define STANDARD - -/* - * Shut bcc up about 'const', which doesn't seem to be handled right - * by unproto. - */ -#ifdef __BCC__ -#define const -#endif - -#define BUF_SIZE 128 -#define OUTC(c) { putc(c, stream); n++; } -#define max(a, b) ((a > b) ? a : b) -/* - * if you change the ff, you need to change the order of characters in - * the string 'flagstr' defined in _printf() - */ -#define FLAG_PADZERO (1<<0) -#define FLAG_LEFTJUST (1<<1) -#define FLAG_SIGNED (1<<2) -#define FLAG_ALT (1<<3) -#define FLAG_SPACE (1<<4) - -static char *utoa(unsigned int val, char *buf, int radix) -/* - * Converts an integer to a variable-radix string representation - * - * Note: - * Does not perform sanity checking for 'radix' - * Assumes 'buf' has memory allocated to it - */ -{ - int divisor; - char *p = buf; - const char *digitstr = "0123456789abcdef"; - - for (divisor = 1; val / divisor >= radix; divisor *= radix); - do { - *p++ = digitstr[val / divisor]; - val %= divisor; - divisor /= radix; - } while (divisor >= 1); - *p = '\0'; - return(buf); -} - -static -internal_fprintf(FILE * stream, const char * fmt, char *args) - -/* static int _printf(FILE *stream, const char *fmt, char *args) */ -/* - * The one that does all the work. - * This is a fairly complete implementation of printf(), supporting - * everything EXCEPT: - * - floating point (eEDOUfg formats) - * - pointers (realizes them but doesn't understand how to print them) - * - short and long (h/l) modifiers (dunno what to do about them) - * It's even slightly faster than gcc's printf() on Linux. Can't beat - * HP-UX's printf() though ;) - * - * Supports: - * d, signed integer - * i - * o unsigned octal integer - * u unsigned integer - * x unsigned hex lowercase a-f - * X unsigned hex uppercase A-F - * c character - * s string (character pointer) - * p void pointer (ignores it) - * % % character - * n number of characters output so far - * - * Special feature: (no really, it's not a bug =) ) - * b prints an integer in binary form (i think this might come - * in handy *somewhere*) - * - * # alternate format for octal (leading 0) and hex (0x/0X) - * 0 leading zeroes for d, i, o, u, x, and X - * - left justify, overrides '0' - * ' ' (space) force a blank in front of positive numbers - * + force a sign in front of any number - * - * width.precision, including support for '*' (reads value from - * the parameter list (MUST BE INT)) - * - * h, short/long modifiers, recognized but ignored. - * l - * - * Warning: - * The way varargs is implemented in libc is evil. Don't think - * there's a better way, but misaligned or wrong parameters - * passed to printf() can break a lot of things. I've tried my - * best to handle errors in the format string, though. - * - * Each %something field cannot exceed 'BUF_SIZE' characters, - * which I set to 128 right now. %s fields are not subject to - * this limit. - * - * Note: - * The semicolon -looks- missing in a few places but that's - * because of the macro def of 'OUTC'. did it that way to - * save a few lines of source ;) - * - * Expects a 'char *' as varargs parameter, unlike libc8086's - * printf(), which takes a 'int *' then casts it to a 'char *'. - * Either has to change, but it should be trivial. - * - * This function aborts whenever it scans an illegal format, unlike - * gcc's libc which prints out the illegal format as if it's -not- - * a format string. The 'STANDARD' preprocessor flag controls if - * if just aborts (when defined) or prints out "(err)" (when undefined). - */ -{ - /* - * the "0-+# " and "dcs..." strings are listed in my idea of their - * frequency of use, with the most popular in front. not terribly - * important but strchr() might have an easier time that way. - * if you change the ordering of 'flagstr', make sure you update - * the #define FLAG_* stuff on top of this file too. - */ - char c, *s, *f; - const char *flagstr = "0-+# ", -#ifdef STANDARD - *typestr = "dcsixXuop"; -#else - *typestr = "dcsixXuopb"; -#endif - int n = 0, flags, width, actwidth, prec, bad = 0, neg, i; - static char buf[BUF_SIZE]; - - for (c = *fmt++; c && !bad;) { - if (c != '%') { /* just copy */ - OUTC(c); - c = *fmt++; - } - else { - c = *fmt++; /* chew the % sign */ - flags = width = prec = 0; - /* - * Parse the "0-+# " flags - */ - while ((f = strchr(flagstr, c)) != NULL) { - flags |= 1 << (f - flagstr); - c = *fmt++; - } - /* - * The '*' parameter says fetch width value from varargs - */ - if (c == '*') { - width = *(int *) args; - args += sizeof(int); - if (width < 0) { - width = abs(width); - flags |= FLAG_LEFTJUST; /* set '-' flag */ - } - c = *fmt++; - } - else - /* - * scan and convert the width parameter - */ - if (isdigit(c)) - while (isdigit(c)) { - width *= 10; - width += c - '0'; - c = *fmt++; - } - /* - * a '.' means there may be a precision parameter - */ - if (c == '.') { - c = *fmt++; - /* - * fetch precision value from varargs - */ - if (c == '*') { - prec = *(int *) args; - if (prec < 0) - prec = 0; - args += sizeof(int); - c = *fmt++; - } - else - /* - * scan and convert precision field - */ - if (isdigit(c)) - while (isdigit(c)) { - prec *= 10; - prec += c - '0'; - c = *fmt++; - } - } - /* - * short and long modifiers. ignored for the moment - */ - if (c == 'h') { - c = *fmt++; - } - else - if (c == 'l') { - c = *fmt++; - } - /* - * check if it's a valid type "dioux..." - */ - if (strchr(typestr, c) != NULL) { - neg = 0; - switch (c) { - case 'd': - case 'i': { - int val = *(int *) args; - args += sizeof(int); - neg = (val < 0); - val = abs(val); - actwidth = strlen(utoa(val, buf, 10)); } - /* - * if negative or '+'/' ' flags set - */ - if (neg || (flags & FLAG_SIGNED) || (flags & FLAG_SPACE)) - actwidth++; - break; - case 'u': { - unsigned int uval = *(unsigned int *) args; - args += sizeof(unsigned int); - actwidth = strlen(utoa(uval, buf, 10)); } - /* - * if '+'/' ' flags set - */ - if ((flags & FLAG_SIGNED) || (flags & FLAG_SPACE)) - actwidth++; - break; - case 'x': - case 'X': { - int val = *(int *) args; - args += sizeof(int); - actwidth = strlen(utoa(val, buf, 16)); } - if (flags & FLAG_ALT) - actwidth += 2; - break; - case 'o': { - int val = *(int *) args; - args += sizeof(int); - actwidth = strlen(utoa(val, buf, 8)); } - if (flags & FLAG_ALT) - actwidth++; - break; - case 's': - s = *(char **) args; - args += sizeof(char *); - actwidth = strlen(s); - break; - case 'c': - buf[0] = *(char *) args; - buf[1] = '\0'; - args += sizeof(char); - actwidth = 1; - break; - /* - * dunno how to handle pointers - what's the format of - * linux86 pointers?! right now just prints "(ptr)" - */ - case 'p': - strcpy(buf, "(ptr)"); - args += sizeof(void *); - actwidth = strlen(buf); - s = buf; /* pretend we're a string */ - c = 's'; - break; -#ifndef STANDARD - case 'b': { - int val = *(int *) args; - args += sizeof(int); - actwidth = strlen(utoa(val, buf, 2)); } - break; -#endif - } - /* - * strings behave differently to the width.precision - * parameters, so handle separately. besides, we avoid - * an extra 'memcpy' to 'buf' - */ - if (c == 's') { - if (prec == 0) - prec = actwidth; - width = max(width, prec); - /* - * pad to the left if not left justified - */ - if (!(flags & FLAG_LEFTJUST)) { - for (i = width; i > prec; i--) - OUTC(' '); - } - /* - * print out entire string if no precision specified, otherwise - * that's our upper limit - */ - if (prec == 0) - for (; *s; s++) - OUTC(*s) /* no semicolon here */ - else - for (i = 0; i < prec; i++) - OUTC(s[i]); - } - else { - /* - * precision is as wide as width if it's not specified and - * the leading zero '0' flag is set, and left-justify is - * -not- set. c standard says left justify overrides the - * leading 0. - */ - if (prec == 0 && (flags & FLAG_PADZERO) && !(flags & FLAG_LEFTJUST)) - prec = width; - /* - * expand width.precision to fit the actual width. printf - * width specifies the -minimum-, and aside from the - * precision of %s fields, there's no way to specify maximum - */ - prec = max(prec, actwidth); - width = max(width, prec); - /* - * pad to the left if we're not left justified - */ - if (!(flags & FLAG_LEFTJUST)) { - for (i = width; i > prec; i--) - OUTC(' '); - } - /* - * check if we might need to print the sign - */ - if (strchr("diu", c) != NULL) { - if (neg) /* print if negative */ - OUTC('-') /* yes, no ';' here =) */ - else - if (flags & FLAG_SIGNED) /* or '+' specified */ - OUTC('+') /* nor here */ - else - if (flags & FLAG_SPACE) /* or ' ' specified */ - OUTC(' ') /* nor here */ - } - /* - * the alternate '#' flag is set. doesn't affect all though - */ - if (flags & FLAG_ALT) { - switch (c) { - case 'o': - OUTC('0'); /* leading zero for octals */ - break; - case 'x': - case 'X': /* prints 0x or 0X */ - OUTC('0'); - OUTC(c); - break; - } - } - /* - * fill the precision field with either spaces or zeroes, - * depending if we're printing numbers - */ - if (strchr("diuxXo", c) != NULL) - for (i = prec; i > actwidth; i--) - OUTC('0') - else - for (i = prec; i > actwidth; i--) - OUTC(' '); - /* - * print the field, except for 'X', which we convert to caps - */ - if (c != 'X') - for (f = buf; *f; f++) - OUTC(*f) /* none here either */ - else - for (f = buf; *f; f++) - OUTC(toupper(*f)); - } - /* - * if we're left justified, we now need to pad spaces to the - * right so that width will be correct - */ - if (flags & FLAG_LEFTJUST) - for (i = width; i > prec; i--) - OUTC(' '); - } - else { - /* - * miscellaneous %thingies - */ - switch (c) { - case '%': /* %% -> % */ - OUTC('%'); - break; - case 'n': /* %n writes current output count */ - *(*(int **) args) = n; - args += sizeof(int *); - break; - default: /* oops, got a bad %thingy */ - bad = 1; - } - } - c = *fmt++; - } - } -#ifndef STANDARD - /* - * dunno what the standard wants if the format string is badly - * formed, so i print (err) if the debug flag is set - */ - if (bad) { - OUTC('('); - OUTC('e'); - OUTC('r'); - OUTC('r'); - OUTC(')'); - } -#endif - return(n); -} - -#ifdef TEST - -#include - -int main() -{ - static unsigned char xbuf[128], *x; - char *fmt = "%s, %s %d, %.*d:%.*d\n"; - int rv1, rv2, i, dt1, dt2; - clock_t t1, t2; - - x = xbuf; - *(char **) x = "Sun"; - x += sizeof(char *); - *(char **) x = "Feb"; - x += sizeof(char *); - *(int *) x = 18; - x += sizeof(int); - *(int *) x = 2; - x += sizeof(int); - *(int *) x = 10; - x += sizeof(int); - *(int *) x = 2; - x += sizeof(int); - *(int *) x = 56; - x += sizeof(int); - t1 = clock(); - for (i = 0; i < 1000; i++) - rv1 = _printf(stdout, fmt, xbuf); - t2 = clock(); - dt1 = t2 - t1; - - t1 = clock(); - for (i = 0; i < 1000; i++) - rv2 = printf(fmt, "Sun", "Feb", 18, 2, 10, 2, 56); - t2 = clock(); - dt2 = t2 - t1; - - printf("\nrv1: %d, rv2: %d, dt1: %d, dt2: %d\n", rv1, rv2, dt1, dt2); - return(0); -} - -#endif diff -Nurd linux86.old/libc/stdio1/puts.c linux86/libc/stdio1/puts.c --- linux86.old/libc/stdio1/puts.c Fri Jan 5 21:09:23 1996 +++ linux86/libc/stdio1/puts.c Thu Jan 1 01:00:00 1970 @@ -1,26 +0,0 @@ -/* simplified linux puts.c - Copyright (C) 1995 Joel N. Weber II - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include "stdio.h" - -int puts (string) -char *string; -{ - fputs(string, stdout); - putc('\n', stdout); - return 0; -} diff -Nurd linux86.old/libc/stdio1/scanf.c linux86/libc/stdio1/scanf.c --- linux86.old/libc/stdio1/scanf.c Tue Feb 13 22:21:40 1996 +++ linux86/libc/stdio1/scanf.c Thu Jan 1 01:00:00 1970 @@ -1,151 +0,0 @@ -/* scanf.c for limited Linux libc - Copyright (C) 1996 Joel N. Weber II - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* This scanf code was derived from my printf code, which in turn was - * derived from Alan Cox's printk. It was tested by [no one so far...] - */ - -/* Disclaimer: I haven't even THOUGHT about testing this. If you do decide - * to be brave and test it, and it doesn't work, you have the following - * options: - * o Send me mail telling me it doesn't work, which I will ignore - * since I already knew that. - * o Fix it yourself - * o isolate the problem and send it to the list, and maybe - * I'll fix it - */ - -/* BTW, the above comment may be destroyed once this has been tested. It's - * not nessisary for my great great grandchildren to see it when they - * take Ancient Linux History... - */ - -/* Incidentally, if it doesn't work, it may well be because I never bothered - * to learn how to use scanf()...I briefly tried it for the usaco qualification - * round, but had some wierd problems...ask me after mid February...BTW the - * problems had nothing to do with scanf(); it was still broken (hopelessly) - * when I went to getchar(). - */ - -/* Note, too that the current version probably assumes some things with - * variable argument handling that it shouldn't. Don't expect this to - * work on a 386 in 32 bit mode, don't expect this to work on a Z80, - * or anything other than an 8086. In fact, don't expect it to even - * work on an 8086 ;-) - */ - -/* One of these days the headers will work painlessly... */ -/* #include */ -/* #include */ -#include "stdio.h" - -/* note that we assume base == 10... */ -static int numin(int *num, int base, FILE *stream, int c) -{ - if ((c < '0') || (c > '9')) return 0; - *num = 0; - while ((c >= '0') && (c <= '9')) { - *num = *num * base + c - '0'; - c = getc(stream); - } - ungetc(c, stream); -} - -/* currently, the h/l specifications are ignored */ -static int internal_scanf(stream,fmt,a1) -FILE *stream; -char *fmt; -int *a1; -{ - unsigned char *p=(char *)a1; - char c; - int inc; - int count = 0; - - while(c=*fmt++) - { - do { - inc = getc(stream); - } while ((inc == ' ') || (inc == '\t') || (inc == '\n')); - - if ((c == '\n') || (c == '\t') || (c == ' ')) - ; - else if (c!='%') { - if (c != inc) { - ungetc(inc, stream); - return count; - } - } else { - int len=2; - c=*fmt++; - if(c=='h') c=*fmt++; - else if(c=='l') c=*fmt++; - - switch(c) - { - case 'x': - if (numin(p, 16, stream, inc)) count++; - else return count; - p+=2; - break; - case 'd': - if (numin(p, 10, stream, inc)) count++; - else return count; - p+=2; - break; - case 's': - { - char *cp=*((char **)p); - p+=sizeof(char *); - while(*cp) - putc(cp++, stream); - while ((inc != ' ') && (inc != '\t') - && (inc != '\n') && (inc != EOF)) { - *cp++ = inc; - inc = getc(stream); - } - ungetc(inc, stream); - break; - } - case 'c': - *p++ = inc; - p++; - break; - default: - putc('?', stream); - } - } - } - return count; -} - - -int fscanf(stream,fmt,a1) -FILE *stream; -char *fmt; -int a1; -{ - return internal_fscanf(stream,fmt,&a1); -} - -int scanf(fmt,a1) -char *fmt; -int a1; -{ - return internal_fscanf(stdout,fmt,&a1); -} diff -Nurd linux86.old/libc/stdio1/stdio.h linux86/libc/stdio1/stdio.h --- linux86.old/libc/stdio1/stdio.h Sun Feb 18 20:00:10 1996 +++ linux86/libc/stdio1/stdio.h Thu Jan 1 01:00:00 1970 @@ -1,135 +0,0 @@ -/* simplified linux stdio.h - Copyright (C) 1995 Joel N. Weber II - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include -#include -#include - -#ifndef __STDIO_H -#define __STDIO_H - -/* when you add or change fields here, be sure to change the initialization - * in stdio_init and fopen */ -struct __stdio_file { - int fd; /* the file descriptor associated with the stream */ - unsigned char *bufstart; /* the start of the buffer */ - unsigned char *bufpos; /* the next byte to write to or read from */ - unsigned char *bufread; /* the end of data returned by last read() */ - unsigned char *bufend; /* the end of the buffer; ie the byte after the last - malloc()ed byte */ - int buffer_mode; -#define _IONBF 0xB111 /* no buffering */ -#define _IOLBF 0xB112 /* line buffering */ -#define _IOFBF 0xB113 /* full buffering */ - int file_mode; -#define _MODE_READ 0xB121 -#define _MODE_WRITE 0xB122 -#define _MODE_RDWR 0xB124 /* used when a file is readwrite and is ord with - what's in the buffer now */ - unsigned char ungetted, ungetchar; - /* ungetted = 1 if there's data unread; else 0 - ungetchar contains the character */ - int fc_eof:1; - int fc_err:1; /* eof and error conditions */ - int iotrans:1; /* Translate \n -> \r\n on MSDOS */ -}; - -#define EOF (-1) - -typedef struct __stdio_file FILE; - -#define BUFSIZ 256 - -extern FILE *stdin, *stdout, *stderr, *__stdsprintf; - -/* The following macros are used for all access to the buffers. If you - * know the file is unbuffered, however, you may write to it directly, as - * fputs.c does. However, be aware that sprintf assumes that by setting - * bufend to 0, no file writing will occur. Also, since NO streams use - * unbuffered mode by default and the function to change this behavior is - * not implemented yet, I'm considering disallowing raw access at the cost - * of having each byte of a string written individually. However, that - * IS what you're asking for with non-buffered mode. - * - * RDB: It's considered very bad form to use the raw read() & write() - * calls on the same files you use the stdio functions. - */ -#ifdef __MSDOS__ -#define putc(c, fp) fputc(c, fp) -#define getc(fp) fgetc(fp) -#else -#define putc(c, stream) \ - (((stream)->bufpos[0] = (c)), \ - ((stream)->bufpos++), \ - ((((stream)->bufpos == (stream)->bufend) \ - ||((stream)->buffer_mode == _IONBF) \ - ||(((stream)->buffer_mode == _IOLBF) \ - && ((stream)->bufpos != (stream)->bufstart) \ - && ((stream)->bufpos[-1] == '\n'))) \ - ? fflush(stream):0)) - -#define getc(stream) \ - ((stream)->ungetted ? (((stream)->ungetted = 0), ((stream)->ungetchar)) : \ - (((stream)->bufpos == (stream)->bufread)?__ffillbuf(stream): \ - (*(stream)->bufpos++))) - -#endif - -#define putchar(c) putc((c), stdout) -#define getchar() getc(stdin) -#define ungetc(c, stream) (((stream)->ungetted = 1), ((stream)->ungetchar = c)) - -#define ferror(fp) ((fp)->fc_err) -#define feof(fp) ((fp)->fc_eof) - -#define fileno(fp) ((fp)->fd) -/* declare functions; not like it makes much difference without ANSI */ -/* RDB: The return values _are_ important, especially if we ever use - 8086 'large' model - */ - -#ifndef __P -#define __P(x) () -#endif - -int setvbuf __P((FILE*, char*, int, size_t)); -int __ffillbuf __P((FILE*)); -void __stdio_init __P((void)); -int fclose __P((FILE*)); -int fflush __P((FILE*)); -int fgetc __P((FILE*)); -char *fgets __P((char*, size_t, FILE*)); -FILE *fopen __P((char*, char*)); - -int fputc __P((int, FILE*)); -int fputs __P((__const char*, FILE*)); -char *idealgetline __P((FILE*)); -int puts __P((char*)); - -int printf __P ((__const char *, ...)); -int fprintf __P ((FILE *, __const char *, ...)); -int sprintf __P ((char *, __const char *, ...)); - -#ifndef SEEK_SET -#define SEEK_SET 0 -#define SEEK_CUR 1 -#define SEEK_END 2 -#endif - -#endif /* __STDIO_H */ -/* TODO: add scanf, fscanf */ diff -Nurd linux86.old/libc/stdio1/test.sh linux86/libc/stdio1/test.sh --- linux86.old/libc/stdio1/test.sh Mon Jan 22 07:18:09 1996 +++ linux86/libc/stdio1/test.sh Thu Jan 1 01:00:00 1970 @@ -1,12 +0,0 @@ -#!/bin/sh - -echo 'rm -f *.o test *.a' -rm -f *.o test *.a -echo 'make' -make -echo 'ar r libnat.a *.o' -ar r libnat.a *.o -echo 'ranlib libnat.a' -ranlib libnat.a -echo 'gcc test.c -I- -I../include -fno-builtin -o test.o -L./ -lnat' -gcc test.c -I- -I../include -fno-builtin -o test.o -L./ -lnat diff -Nurd linux86.old/libc/stdio2/Config linux86/libc/stdio2/Config --- linux86.old/libc/stdio2/Config Tue Feb 27 21:09:46 1996 +++ linux86/libc/stdio2/Config Thu Jan 1 01:00:00 1970 @@ -1,4 +0,0 @@ -# - -stdio: Robert's stdio package - diff -Nurd linux86.old/libc/stdio2/Makefile linux86/libc/stdio2/Makefile --- linux86.old/libc/stdio2/Makefile Sat Mar 8 20:16:05 1997 +++ linux86/libc/stdio2/Makefile Thu Jan 1 01:00:00 1970 @@ -1,49 +0,0 @@ -# Copyright (C) 1995,1996 Robert de Bath -# This file is part of the Linux-8086 C library and is distributed -# under the GNU Library General Public License. - -ifneq ($(LIB_CPU),i86) -CFLAGS=$(CCFLAGS) $(LIBDEFS) -DFLOATS -endif - -ASRC=stdio.c -AOBJ=_stdio_init.o fputc.o fgetc.o fflush.o fgets.o gets.o fputs.o \ - puts.o fread.o fwrite.o fopen.o fclose.o fseek.o rewind.o ftell.o \ - setbuffer.o setvbuf.o ungetc.o - -PSRC=printf.c -POBJ=printf.o sprintf.o fprintf.o vprintf.o vsprintf.o vfprintf.o - -SSRC=scanf.c -SOBJ=scanf.o sscanf.o fscanf.o vscanf.o vsscanf.o vfscanf.o - -OBJ= $(AOBJ) $(POBJ) $(SOBJ) - -CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS) - -all: $(LIBC) - @$(RM) $(OBJ) - -$(LIBC): $(LIBC)($(OBJ)) - -$(LIBC)($(AOBJ)): $(ASRC) - $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o - $(AR) $(ARFLAGS) $@ $*.o - -$(LIBC)($(POBJ)): $(PSRC) - $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o - $(AR) $(ARFLAGS) $@ $*.o - -$(LIBC)($(SOBJ)): $(SSRC) - $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o - $(AR) $(ARFLAGS) $@ $*.o - -transfer: - -@rm -f ../include/stdio.h - cp -p stdio.h ../include/. - -clean: - rm -f *.o libc.a - -$(LIBC)($(OBJ)): stdio.h - diff -Nurd linux86.old/libc/stdio2/printf.c linux86/libc/stdio2/printf.c --- linux86.old/libc/stdio2/printf.c Sun Oct 25 06:53:01 1998 +++ linux86/libc/stdio2/printf.c Thu Jan 1 01:00:00 1970 @@ -1,380 +0,0 @@ -/* - * This file based on printf.c from 'Dlibs' on the atari ST (RdeBath) - * - * 19-OCT-88: Dale Schumacher - * > John Stanley has again been a great help in debugging, particularly - * > with the printf/scanf functions which are his creation. - * - * Dale Schumacher 399 Beacon Ave. - * (alias: Dalnefre') St. Paul, MN 55104 - * dal@syntel.UUCP United States of America - * "It's not reality that's important, but how you perceive things." - * - */ - -/* Altered to use stdarg, made the core function vfprintf. - * Hooked into the stdio package using 'inside information' - * Altered sizeof() assumptions, now assumes all integers except chars - * will be either - * sizeof(xxx) == sizeof(long) or sizeof(xxx) == sizeof(short) - * - * -RDB - */ - -#include -#include -#ifdef __STDC__ -#include -#define va_strt va_start -#else -#include -#define va_strt(p,i) va_start(p) -#endif - -#include "stdio.h" - -#ifdef L_printf - -#ifdef __STDC__ -int printf(const char * fmt, ...) -#else -int printf(fmt, va_alist) -__const char *fmt; -va_dcl -#endif -{ - va_list ptr; - int rv; - va_strt(ptr, fmt); - rv = vfprintf(stdout,fmt,ptr); - va_end(ptr); - return rv; -} -#endif - -#ifdef L_sprintf -#ifdef __STDC__ -int sprintf(char * sp, const char * fmt, ...) -#else -int sprintf(sp, fmt, va_alist) -char * sp; -__const char *fmt; -va_dcl -#endif -{ -static FILE string[1] = -{ - {0, 0, (char*)(unsigned) -1, 0, (char*) (unsigned) -1, -1, - _IOFBF | __MODE_WRITE} -}; - - va_list ptr; - int rv; - va_strt(ptr, fmt); - string->bufpos = sp; - rv = vfprintf(string,fmt,ptr); - va_end(ptr); - *(string->bufpos) = 0; - return rv; -} -#endif - -#ifdef L_fprintf -#ifdef __STDC__ -int fprintf(FILE * fp, const char * fmt, ...) -#else -int fprintf(fp, fmt, va_alist) -FILE * fp; -__const char *fmt; -va_dcl -#endif -{ - va_list ptr; - int rv; - va_strt(ptr, fmt); - rv = vfprintf(fp,fmt,ptr); - va_end(ptr); - return rv; -} -#endif - -#ifdef L_vprintf -int vprintf(fmt, ap) -__const char *fmt; -va_list ap; -{ - return vfprintf(stdout,fmt,ap); -} -#endif - -#ifdef L_vsprintf -int vsprintf(sp, fmt, ap) -char * sp; -__const char *fmt; -va_list ap; -{ -static FILE string[1] = -{ - {0, 0, (char*)(unsigned) -1, 0, (char*) (unsigned) -1, -1, - _IOFBF | __MODE_WRITE} -}; - - int rv; - string->bufpos = sp; - rv = vfprintf(string,fmt,ap); - *(string->bufpos) = 0; - return rv; -} -#endif - -#ifdef L_vfprintf - -#ifdef FLOATS -int (*__fp_print)() = 0; -#endif - -static int -prtfld(op, buf, ljustf, sign, pad, width, preci, buffer_mode) -register FILE *op; -register unsigned char *buf; -int ljustf; -register char sign; -char pad; -register int width; -int preci; -int buffer_mode; -/* - * Output the given field in the manner specified by the arguments. Return - * the number of characters output. - */ -{ - register int cnt = 0, len; - register unsigned char ch; - - len = strlen(buf); - - if (*buf == '-') - sign = *buf++; - else if (sign) - len++; - - if ((preci != -1) && (len > preci)) /* limit max data width */ - len = preci; - - if (width < len) /* flexible field width or width overflow */ - width = len; - - /* - * at this point: width = total field width len = actual data width - * (including possible sign character) - */ - cnt = width; - width -= len; - - while (width || len) - { - if (!ljustf && width) /* left padding */ - { - if (len && sign && (pad == '0')) - goto showsign; - ch = pad; - --width; - } - else if (len) - { - if (sign) - { - showsign:ch = sign; /* sign */ - sign = '\0'; - } - else - ch = *buf++; /* main field */ - --len; - } - else - { - ch = pad; /* right padding */ - --width; - } - putc(ch, op); - if( ch == '\n' && buffer_mode == _IOLBF ) fflush(op); - } - - return (cnt); -} - -int -vfprintf(op, fmt, ap) -FILE *op; -register __const char *fmt; -register va_list ap; -{ - register int i, cnt = 0, ljustf, lval; - int preci, dpoint, width; - char pad, sign, radix, hash; - register char *ptmp; - char tmp[64], *ltostr(), *ultostr(); - int buffer_mode; - - /* This speeds things up a bit for unbuffered */ - buffer_mode = (op->mode&__MODE_BUF); - op->mode &= (~__MODE_BUF); - - while (*fmt) - { - if (*fmt == '%') - { - if( buffer_mode == _IONBF ) fflush(op); - ljustf = 0; /* left justify flag */ - sign = '\0'; /* sign char & status */ - pad = ' '; /* justification padding char */ - width = -1; /* min field width */ - dpoint = 0; /* found decimal point */ - preci = -1; /* max data width */ - radix = 10; /* number base */ - ptmp = tmp; /* pointer to area to print */ - hash = 0; - lval = (sizeof(int)==sizeof(long)); /* long value flaged */ - fmtnxt: - i = 0; - for(;;) - { - ++fmt; - if(*fmt < '0' || *fmt > '9' ) break; - i = (i * 10) + (*fmt - '0'); - if (dpoint) - preci = i; - else if (!i && (pad == ' ')) - { - pad = '0'; - goto fmtnxt; - } - else - width = i; - } - - switch (*fmt) - { - case '\0': /* early EOS */ - --fmt; - goto charout; - - case '-': /* left justification */ - ljustf = 1; - goto fmtnxt; - - case ' ': - case '+': /* leading sign flag */ - sign = *fmt; - goto fmtnxt; - - case '*': /* parameter width value */ - i = va_arg(ap, int); - if (dpoint) - preci = i; - else - width = i; - goto fmtnxt; - - case '.': /* secondary width field */ - dpoint = 1; - goto fmtnxt; - - case 'l': /* long data */ - lval = 1; - goto fmtnxt; - - case 'h': /* short data */ - lval = 0; - goto fmtnxt; - - case 'd': /* Signed decimal */ - case 'i': - ptmp = ltostr((long) ((lval) - ? va_arg(ap, long) - : va_arg(ap, short)), - 10); - goto printit; - - case 'b': /* Unsigned binary */ - radix = 2; - goto usproc; - - case 'o': /* Unsigned octal */ - radix = 8; - goto usproc; - - case 'p': /* Pointer */ - lval = (sizeof(char*) == sizeof(long)); - pad = '0'; - width = 6; - preci = 8; - /* fall thru */ - - case 'x': /* Unsigned hexadecimal */ - case 'X': - radix = 16; - /* fall thru */ - - case 'u': /* Unsigned decimal */ - usproc: - ptmp = ultostr((unsigned long) ((lval) - ? va_arg(ap, unsigned long) - : va_arg(ap, unsigned short)), - radix); - if( hash && radix == 8 ) { width = strlen(ptmp)+1; pad='0'; } - goto printit; - - case '#': - hash=1; - goto fmtnxt; - - case 'c': /* Character */ - ptmp[0] = va_arg(ap, int); - ptmp[1] = '\0'; - goto nopad; - - case 's': /* String */ - ptmp = va_arg(ap, char*); - nopad: - sign = '\0'; - pad = ' '; - printit: - cnt += prtfld(op, ptmp, ljustf, - sign, pad, width, preci, buffer_mode); - break; - -#if FLOATS - case 'e': /* float */ - case 'f': - case 'g': - case 'E': - case 'G': - if ( __fp_print ) - { - (*__fp_print)(&va_arg(ap, double), *fmt, preci, ptmp); - preci = -1; - goto printit; - } - /* FALLTHROUGH if no floating printf available */ -#endif - - default: /* unknown character */ - goto charout; - } - } - else - { - charout: - putc(*fmt, op); /* normal char out */ - ++cnt; - if( *fmt == '\n' && buffer_mode == _IOLBF ) fflush(op); - } - ++fmt; - } - op->mode |= buffer_mode; - if( buffer_mode == _IONBF ) fflush(op); - if( buffer_mode == _IOLBF ) op->bufwrite = op->bufstart; - return (cnt); -} -#endif diff -Nurd linux86.old/libc/stdio2/scanf.c linux86/libc/stdio2/scanf.c --- linux86.old/libc/stdio2/scanf.c Sat Sep 19 12:20:16 1998 +++ linux86/libc/stdio2/scanf.c Thu Jan 1 01:00:00 1970 @@ -1,536 +0,0 @@ -/* - * This file based on scanf.c from 'Dlibs' on the atari ST (RdeBath) - * - * 19-OCT-88: Dale Schumacher - * > John Stanley has again been a great help in debugging, particularly - * > with the printf/scanf functions which are his creation. - * - * Dale Schumacher 399 Beacon Ave. - * (alias: Dalnefre') St. Paul, MN 55104 - * dal@syntel.UUCP United States of America - * "It's not reality that's important, but how you perceive things." - * - */ - -#include -#include -#include - -#ifdef __STDC__ -#include -#define va_strt va_start -#else -#include -#define va_strt(p,i) va_start(p) -#endif - -#ifdef L_scanf -#ifdef __STDC__ -int scanf(const char * fmt, ...) -#else -int scanf(fmt, va_alist) -__const char *fmt; -va_dcl -#endif -{ - va_list ptr; - int rv; - va_strt(ptr, fmt); - rv = vfscanf(stdin,fmt,ptr); - va_end(ptr); - return rv; -} -#endif - -#ifdef L_sscanf -#ifdef __STDC__ -int sscanf(char * sp, const char * fmt, ...) -#else -int sscanf(sp, fmt, va_alist) -char * sp; -__const char *fmt; -va_dcl -#endif -{ -static FILE string[1] = -{ - {0, (char*)(unsigned) -1, 0, 0, (char*) (unsigned) -1, -1, - _IOFBF | __MODE_READ} -}; - - va_list ptr; - int rv; - va_strt(ptr, fmt); - string->bufpos = sp; - rv = vfscanf(string,fmt,ptr); - va_end(ptr); - return rv; -} -#endif - -#ifdef L_fscanf -#ifdef __STDC__ -int fscanf(FILE * fp, const char * fmt, ...) -#else -int fscanf(fp, fmt, va_alist) -FILE * fp; -__const char *fmt; -va_dcl -#endif -{ - va_list ptr; - int rv; - va_strt(ptr, fmt); - rv = vfscanf(fp,fmt,ptr); - va_end(ptr); - return rv; -} -#endif - -#ifdef L_vscanf -int vscanf(fmt, ap) -__const char *fmt; -va_list ap; -{ - return vfscanf(stdin,fmt,ap); -} -#endif - -#ifdef L_vsscanf -int vsscanf(sp, fmt, ap) -char * sp; -__const char *fmt; -{ -static FILE string[1] = -{ - {0, (char*)(unsigned) -1, 0, 0, (char*) (unsigned) -1, -1, - _IOFBF | __MODE_READ} -}; - - string->bufpos = sp; - return vfscanf(string,fmt,ap); -} -#endif - -#ifdef L_vfscanf -/* #define skip() do{c=getc(fp); if (c<1) goto done;}while(isspace(c))*/ - -#define skip() while(isspace(c)) { if ((c=getc(fp))<1) goto done; } - -#if FLOATS -/* fp scan actions */ -#define F_NADA 0 /* just change state */ -#define F_SIGN 1 /* set sign */ -#define F_ESIGN 2 /* set exponent's sign */ -#define F_INT 3 /* adjust integer part */ -#define F_FRAC 4 /* adjust fraction part */ -#define F_EXP 5 /* adjust exponent part */ -#define F_QUIT 6 - -#define NSTATE 8 -#define FS_INIT 0 /* initial state */ -#define FS_SIGNED 1 /* saw sign */ -#define FS_DIGS 2 /* saw digits, no . */ -#define FS_DOT 3 /* saw ., no digits */ -#define FS_DD 4 /* saw digits and . */ -#define FS_E 5 /* saw 'e' */ -#define FS_ESIGN 6 /* saw exp's sign */ -#define FS_EDIGS 7 /* saw exp's digits */ - -#define FC_DIG 0 -#define FC_DOT 1 -#define FC_E 2 -#define FC_SIGN 3 - -/* given transition,state do what action? */ -int fp_do[][NSTATE] = { - {F_INT,F_INT,F_INT, - F_FRAC,F_FRAC, - F_EXP,F_EXP,F_EXP}, /* see digit */ - {F_NADA,F_NADA,F_NADA, - F_QUIT,F_QUIT,F_QUIT,F_QUIT,F_QUIT}, /* see '.' */ - {F_QUIT,F_QUIT, - F_NADA,F_QUIT,F_NADA, - F_QUIT,F_QUIT,F_QUIT}, /* see e/E */ - {F_SIGN,F_QUIT,F_QUIT,F_QUIT,F_QUIT, - F_ESIGN,F_QUIT,F_QUIT}, /* see sign */ -}; -/* given transition,state what is new state? */ -int fp_ns[][NSTATE] = { - {FS_DIGS,FS_DIGS,FS_DIGS, - FS_DD,FS_DD, - FS_EDIGS,FS_EDIGS,FS_EDIGS}, /* see digit */ - {FS_DOT,FS_DOT,FS_DD, - }, /* see '.' */ - {0,0, - FS_E,0,FS_E, - }, /* see e/E */ - {FS_SIGNED,0,0,0,0, - FS_ESIGN,0,0}, /* see sign */ -}; -/* which states are valid terminators? */ -int fp_sval[NSTATE] = { - 0,0,1,0,1,0,0,1 -}; -#endif - -vfscanf(fp, fmt, ap) -register FILE *fp; -register char *fmt; -va_list ap; - -{ - register long n; - register int c, width, lval, cnt = 0; - int store, neg, base, wide1, endnull, rngflag, c2; - register unsigned char *p; - unsigned char delim[128], digits[17], *q; -#if FLOATS - long frac, expo; - int eneg, fraclen, fstate, trans; - double fx, fp_scan(); -#endif - - if (!*fmt) - return (0); - - c = getc(fp); - while (c > 0) - { - store = 0; - if (*fmt == '%') - { - n = 0; - width = -1; - wide1 = 1; - base = 10; - lval = (sizeof(long) == sizeof(int)); - store = 1; - endnull = 1; - neg = -1; - - strcpy(delim, "\011\012\013\014\015 "); - strcpy(digits, "0123456789ABCDEF"); - - if (fmt[1] == '*') - { - endnull = store = 0; - ++fmt; - } - - while (isdigit(*++fmt))/* width digit(s) */ - { - if (width == -1) - width = 0; - wide1 = width = (width * 10) + (*fmt - '0'); - } - --fmt; - fmtnxt: - ++fmt; - switch (tolower(*fmt)) /* tolower() is a MACRO! */ - { - case '*': - endnull = store = 0; - goto fmtnxt; - - case 'l': /* long data */ - lval = 1; - goto fmtnxt; - case 'h': /* short data */ - lval = 0; - goto fmtnxt; - - case 'i': /* any-base numeric */ - base = 0; - goto numfmt; - - case 'b': /* unsigned binary */ - base = 2; - goto numfmt; - - case 'o': /* unsigned octal */ - base = 8; - goto numfmt; - - case 'x': /* unsigned hexadecimal */ - base = 16; - goto numfmt; - - case 'd': /* SIGNED decimal */ - neg = 0; - /* FALL-THRU */ - - case 'u': /* unsigned decimal */ - numfmt:skip(); - - if (isupper(*fmt)) - lval = 1; - - if (!base) - { - base = 10; - neg = 0; - if (c == '%') - { - base = 2; - goto skip1; - } - else if (c == '0') - { - c = getc(fp); - if (c < 1) - goto savnum; - if ((c != 'x') - && (c != 'X')) - { - base = 8; - digits[8] = '\0'; - goto zeroin; - } - base = 16; - goto skip1; - } - } - - if ((neg == 0) && (base == 10) - && ((neg = (c == '-')) || (c == '+'))) - { - skip1: - c = getc(fp); - if (c < 1) - goto done; - } - - digits[base] = '\0'; - p = ((unsigned char *) - strchr(digits, toupper(c))); - - if ((!c || !p) && width) - goto done; - - while (p && width-- && c) - { - n = (n * base) + (p - digits); - c = getc(fp); - zeroin: - p = ((unsigned char *) - strchr(digits, toupper(c))); - } - savnum: - if (store) - { - if (neg == 1) - n = -n; - if (lval) - *va_arg(ap, long*) = n; - else - *va_arg(ap, short*) = n; - ++cnt; - } - break; - -#if FLOATS - case 'e': /* float */ - case 'f': - case 'g': - skip(); - - if (isupper(*fmt)) - lval = 1; - - fstate = FS_INIT; - neg = 0; - eneg = 0; - n = 0; - frac = 0; - expo = 0; - fraclen = 0; - - while (c && width--) - { - if (c >= '0' && c <= '9') - trans = FC_DIG; - else if (c == '.') - trans = FC_DOT; - else if (c == '+' || c == '-') - trans = FC_SIGN; - else if (tolower(c) == 'e') - trans = FC_E; - else - goto fdone; - - switch (fp_do[trans][fstate]) - { - case F_SIGN: - neg = (c == '-'); - break; - case F_ESIGN: - eneg = (c == '-'); - break; - case F_INT: - n = 10 * n + (c - '0'); - break; - case F_FRAC: - frac = 10 * frac + (c - '0'); - fraclen++; - break; - case F_EXP: - expo = 10 * expo + (c - '0'); - break; - case F_QUIT: - goto fdone; - } - fstate = fp_ns[trans][fstate]; - c = getc(fp); - } - - fdone: - if (!fp_sval[fstate]) - goto done; - if (store) - { - fx = fp_scan(neg, eneg, n, frac, expo, fraclen); - if (lval) - *va_arg(ap, double *) = fx; - else - *va_arg(ap, float *) = fx; - ++cnt; - } - break; -#endif - - case 'c': /* character data */ - width = wide1; - lval = endnull = 0; - delim[0] = '\0'; - goto strproc; - - case '[': /* string w/ delimiter set */ - - /* get delimiters */ - p = delim; - - if (*++fmt == '^') - { - fmt++; - lval = 0; - } - else - lval = 1; - - rngflag = 2; - if ((*fmt == ']') || (*fmt == '-')) - { - *p++ = *fmt++; - rngflag = 0; - } - - while (*fmt != ']') - { - if (*fmt == '\0') - goto done; - switch (rngflag) - { - case 1: - c2 = *(p - 2); - if (c2 <= *fmt) - { - p -= 2; - while (c2 < *fmt) - *p++ = c2++; - rngflag = 2; - break; - } - /* fall thru intentional */ - - case 0: - rngflag = (*fmt == '-'); - break; - - case 2: - rngflag = 0; - } - - *p++ = *fmt++; - } - - *p = '\0'; - goto strproc; - - case 's': /* string data */ - lval = 0; - skip(); - strproc: - /* process string */ - p = va_arg(ap, unsigned char *); - - /* if the 1st char fails, match fails */ - if (width) - { - q = ((unsigned char *) - strchr(delim, c)); - if ((c < 1) || lval == (q==0)) - { - if (endnull) - *p = '\0'; - goto done; - } - } - - for (;;) /* FOREVER */ - { - if (store) - *p++ = c; - if (((c = getc(fp)) < 1) || - (--width == 0)) - break; - - q = ((unsigned char *) - strchr(delim, c)); - if (lval == (q==0)) - break; - } - - if (store) - { - if (endnull) - *p = '\0'; - ++cnt; - } - break; - - case '\0': /* early EOS */ - --fmt; - /* FALL THRU */ - - default: - goto cmatch; - } - } - else if (isspace(*fmt)) /* skip whitespace */ - { - skip(); - } - else - { /* normal match char */ - cmatch: - if (c != *fmt) - break; - c = getc(fp); - } - - if (!*++fmt) - break; - } - - done: /* end of scan */ - if ((c == EOF) && (cnt == 0)) - return (EOF); - - if( c != EOF ) - ungetc(c, fp); - return (cnt); -} - -#endif - diff -Nurd linux86.old/libc/stdio2/stdio.c linux86/libc/stdio2/stdio.c --- linux86.old/libc/stdio2/stdio.c Tue Mar 9 14:54:35 1999 +++ linux86/libc/stdio2/stdio.c Thu Jan 1 01:00:00 1970 @@ -1,866 +0,0 @@ -/* Copyright (C) 1996 Robert de Bath - * This file is part of the Linux-8086 C library and is distributed - * under the GNU Library General Public License. - */ - -/* This is an implementation of the C standard IO package. - */ - -#include - -#include -#include -#include -#include - -#ifndef O_BINARY -#define O_BINARY 0 -#endif - -extern FILE *__IO_list; /* For fflush at exit */ - -#ifdef __AS386_16__ -#define Inline_init -#endif - -#ifdef __AS386_32__ -#define Inline_init -#endif - -#ifndef Inline_init -#define Inline_init __io_init_vars() -#endif - -#ifdef L__stdio_init - -#define buferr (stderr->unbuf) /* Stderr is unbuffered */ - -FILE *__IO_list = 0; /* For fflush at exit */ - -static char bufin[BUFSIZ]; -static char bufout[BUFSIZ]; -#ifndef buferr -static char buferr[BUFSIZ]; -#endif - -FILE stdin[1] = -{ - {bufin, bufin, bufin, bufin, bufin + sizeof(bufin), - 0, _IOFBF | __MODE_READ | __MODE_IOTRAN} -}; - -FILE stdout[1] = -{ - {bufout, bufout, bufout, bufout, bufout + sizeof(bufout), - 1, _IOFBF | __MODE_WRITE | __MODE_IOTRAN} -}; - -FILE stderr[1] = -{ - {buferr, buferr, buferr, buferr, buferr + sizeof(buferr), - 2, _IONBF | __MODE_WRITE | __MODE_IOTRAN} -}; - -/* Call the stdio initiliser; it's main job it to call atexit */ - -#ifdef __AS386_16__ -#define STATIC static - -#asm - loc 1 ! Make sure the pointer is in the correct segment -auto_func: ! Label for bcc -M to work. - .word ___io_init_vars ! Pointer to the autorun function - .text ! So the function after is also in the correct seg. -#endasm -#endif - -#ifdef __AS386_32__ -#define STATIC static - -#asm - loc 1 ! Make sure the pointer is in the correct segment -auto_func: ! Label for bcc -M to work. - .long ___io_init_vars ! Pointer to the autorun function - .text ! So the function after is also in the correct seg. -#endasm -#endif - -#ifndef STATIC -#define STATIC -#endif - -STATIC int -__stdio_close_all() -{ - FILE *fp; - fflush(stdout); - fflush(stderr); - for (fp = __IO_list; fp; fp = fp->next) - { - fflush(fp); - close(fp->fd); - /* Note we're not de-allocating the memory */ - /* There doesn't seem to be much point :-) */ - fp->fd = -1; - } -} - -STATIC void -__io_init_vars() -{ -#ifndef __AS386_16__ -#ifndef __AS386_32__ - static int first_time = 1; - if( !first_time ) return ; - first_time = 0; -#endif -#endif - if (isatty(1)) - stdout->mode |= _IOLBF; - atexit(__stdio_close_all); -} -#endif - -#ifdef L_fputc -int -fputc(ch, fp) -int ch; -FILE *fp; -{ - register int v; - Inline_init; - - /* If last op was a read ... note fflush may change fp->mode and ret OK */ - if ((fp->mode & __MODE_READING) && fflush(fp)) - return EOF; - - v = fp->mode; - /* Can't write if there's been an EOF or error then return EOF */ - if ((v & (__MODE_WRITE | __MODE_EOF | __MODE_ERR)) != __MODE_WRITE) - return EOF; - - /* In MSDOS translation mode */ -#if __MODE_IOTRAN && !O_BINARY - if (ch == '\n' && (v & __MODE_IOTRAN) && fputc('\r', fp) == EOF) - return EOF; -#endif - - /* Buffer is full */ - if (fp->bufpos >= fp->bufend && fflush(fp)) - return EOF; - - /* Right! Do it! */ - *(fp->bufpos++) = ch; - fp->mode |= __MODE_WRITING; - - /* Unbuffered or Line buffered and end of line */ - if (((ch == '\n' && (v & _IOLBF)) || (v & _IONBF)) - && fflush(fp)) - return EOF; - - /* Can the macro handle this by itself ? */ - if (v & (__MODE_IOTRAN | _IOLBF | _IONBF)) - fp->bufwrite = fp->bufstart; /* Nope */ - else - fp->bufwrite = fp->bufend; /* Yup */ - - /* Correct return val */ - return (unsigned char) ch; -} -#endif - -#ifdef L_fgetc -int -fgetc(fp) -FILE *fp; -{ - int ch; - - if (fp->mode & __MODE_WRITING) - fflush(fp); - - try_again: - /* Can't read or there's been an EOF or error then return EOF */ - if ((fp->mode & (__MODE_READ | __MODE_EOF | __MODE_ERR)) != __MODE_READ) - return EOF; - - /* Nothing in the buffer - fill it up */ - if (fp->bufpos >= fp->bufread) - { - /* Bind stdin to stdout if it's open and line buffered */ - if( fp == stdin && stdout->fd >= 0 && (stdout->mode & _IOLBF )) - fflush(stdout); - - fp->bufpos = fp->bufread = fp->bufstart; - ch = fread(fp->bufpos, 1, fp->bufend - fp->bufstart, fp); - if (ch == 0) - return EOF; - fp->bufread += ch; - fp->mode |= __MODE_READING; - fp->mode &= ~__MODE_UNGOT; - } - ch = *(fp->bufpos++); - -#if __MODE_IOTRAN && !O_BINARY - /* In MSDOS translation mode; WARN: Doesn't work with UNIX macro */ - if (ch == '\r' && (fp->mode & __MODE_IOTRAN)) - goto try_again; -#endif - - return ch; -} -#endif - -#ifdef L_fflush -int -fflush(fp) -FILE *fp; -{ - int len, cc, rv=0; - char * bstart; - if (fp == NULL) /* On NULL flush the lot. */ - { - if (fflush(stdin)) - return EOF; - if (fflush(stdout)) - return EOF; - if (fflush(stderr)) - return EOF; - - for (fp = __IO_list; fp; fp = fp->next) - if (fflush(fp)) - return EOF; - - return 0; - } - - /* If there's output data pending */ - if (fp->mode & __MODE_WRITING) - { - len = fp->bufpos - fp->bufstart; - - if (len) - { - bstart = fp->bufstart; - /* - * The loop is so we don't get upset by signals or partial writes. - */ - do - { - cc = write(fp->fd, bstart, len); - if( cc > 0 ) - { - bstart+=cc; len-=cc; - } - } - while ( len>0 && (cc>0 || (cc == -1 && errno == EINTR))); - /* - * If we get here with len!=0 there was an error, exactly what to - * do about it is another matter ... - * - * I'll just clear the buffer. - */ - if (len) - { - fp->mode |= __MODE_ERR; - rv = EOF; - } - } - } - /* If there's data in the buffer sychronise the file positions */ - else if (fp->mode & __MODE_READING) - { - /* Humm, I think this means sync the file like fpurge() ... */ - /* Anyway the user isn't supposed to call this function when reading */ - - len = fp->bufread - fp->bufpos; /* Bytes buffered but unread */ - /* If it's a file, make it good */ - if (len > 0 && lseek(fp->fd, (long)-len, 1) < 0) - { - /* Hummm - Not certain here, I don't think this is reported */ - /* - * fp->mode |= __MODE_ERR; return EOF; - */ - } - } - - /* All done, no problem */ - fp->mode &= (~(__MODE_READING|__MODE_WRITING|__MODE_EOF|__MODE_UNGOT)); - fp->bufread = fp->bufwrite = fp->bufpos = fp->bufstart; - return rv; -} -#endif - -#ifdef L_fgets -/* Nothing special here ... */ -char * -fgets(s, count, f) -char *s; -size_t count; -FILE *f; -{ - char *ret; - register size_t i; - register int ch; - - ret = s; - for (i = count-1; i > 0; i--) - { - ch = getc(f); - if (ch == EOF) - { - if (s == ret) - return 0; - break; - } - *s++ = (char) ch; - if (ch == '\n') - break; - } - *s = 0; - - if (ferror(f)) - return 0; - return ret; -} -#endif - -#ifdef L_gets -char * -gets(str) /* BAD function; DON'T use it! */ -char *str; -{ - /* Auwlright it will work but of course _your_ program will crash */ - /* if it's given a too long line */ - register char *p = str; - register int c; - - while (((c = getc(stdin)) != EOF) && (c != '\n')) - *p++ = c; - *p = '\0'; - return (((c == EOF) && (p == str)) ? NULL : str); /* NULL == EOF */ -} -#endif - -#ifdef L_fputs -int -fputs(str, fp) -char *str; -FILE *fp; -{ - register int n = 0; - while (*str) - { - if (putc(*str++, fp) == EOF) - return (EOF); - ++n; - } - return (n); -} -#endif - -#ifdef L_puts -int -puts(str) -char *str; -{ - register int n; - - if (((n = fputs(str, stdout)) == EOF) - || (putc('\n', stdout) == EOF)) - return (EOF); - return (++n); -} -#endif - -#ifdef L_fread -/* - * fread will often be used to read in large chunks of data calling read() - * directly can be a big win in this case. Beware also fgetc calls this - * function to fill the buffer. - * - * This ignores __MODE__IOTRAN; probably exactly what you want. (It _is_ what - * fgetc wants) - */ -int -fread(buf, size, nelm, fp) -char *buf; -int size; -int nelm; -FILE *fp; -{ - int len, v; - unsigned bytes, got = 0; - Inline_init; - - v = fp->mode; - - /* Want to do this to bring the file pointer up to date */ - if (v & __MODE_WRITING) - fflush(fp); - - /* Can't read or there's been an EOF or error then return zero */ - if ((v & (__MODE_READ | __MODE_EOF | __MODE_ERR)) != __MODE_READ) - return 0; - - /* This could be long, doesn't seem much point tho */ - bytes = size * nelm; - - len = fp->bufread - fp->bufpos; - if (len >= bytes) /* Enough buffered */ - { - memcpy(buf, fp->bufpos, (unsigned) bytes); - fp->bufpos += bytes; - return nelm; - } - else if (len > 0) /* Some buffered */ - { - memcpy(buf, fp->bufpos, len); - fp->bufpos += len; - got = len; - } - - /* Need more; do it with a direct read */ - len = read(fp->fd, buf + got, (unsigned) (bytes - got)); - - /* Possibly for now _or_ later */ - if (len < 0) - { - fp->mode |= __MODE_ERR; - len = 0; - } - else if (len == 0) - fp->mode |= __MODE_EOF; - - return (got + len) / size; -} -#endif - -#ifdef L_fwrite -/* - * Like fread, fwrite will often be used to write out large chunks of - * data; calling write() directly can be a big win in this case. - * - * But first we check to see if there's space in the buffer. - * - * Again this ignores __MODE__IOTRAN. - */ -int -fwrite(buf, size, nelm, fp) -char *buf; -int size; -int nelm; -FILE *fp; -{ - register int v; - int len; - unsigned bytes, put; - - /* If last op was a read ... note fflush may change fp->mode and ret OK */ - if ((fp->mode & __MODE_READING) && fflush(fp)) - return 0; - - v = fp->mode; - /* Can't write or there's been an EOF or error then return 0 */ - if ((v & (__MODE_WRITE | __MODE_EOF | __MODE_ERR)) != __MODE_WRITE) - return 0; - - /* This could be long, doesn't seem much point tho */ - bytes = size * nelm; - - len = fp->bufend - fp->bufpos; - - /* Flush the buffer if not enough room */ - if (bytes > len) - if (fflush(fp)) - return 0; - - len = fp->bufend - fp->bufpos; - if (bytes <= len) /* It'll fit in the buffer ? */ - { - register int do_flush=0; - fp->mode |= __MODE_WRITING; - memcpy(fp->bufpos, buf, bytes); - if (v & _IOLBF) - { - if(memchr(fp->bufpos, '\n', bytes)) - do_flush=1; - } - fp->bufpos += bytes; - - /* If we're unbuffered or line buffered and have seen nl */ - if (do_flush || (v & _IONBF) != 0) - fflush(fp); - - return nelm; - } - else - /* Too big for the buffer */ - { - put = bytes; - do - { - len = write(fp->fd, buf, bytes); - if( len > 0 ) - { - buf+=len; bytes-=len; - } - } - while (len > 0 || (len == -1 && errno == EINTR)); - - if (len < 0) - fp->mode |= __MODE_ERR; - - put -= bytes; - } - - return put / size; -} -#endif - -#ifdef L_rewind -void -rewind(fp) -FILE * fp; -{ - fseek(fp, (long)0, 0); - clearerr(fp); -} -#endif - -#ifdef L_fseek -int -fseek(fp, offset, ref) -FILE *fp; -long offset; -int ref; -{ -#if 1 - /* if __MODE_READING and no ungetc ever done can just move pointer */ - - if ( (fp->mode &(__MODE_READING | __MODE_UNGOT)) == __MODE_READING && - ( ref == SEEK_SET || ref == SEEK_CUR )) - { - long fpos = lseek(fp->fd, 0L, SEEK_CUR); - if( fpos == -1 ) return EOF; - - if( ref == SEEK_CUR ) - { - ref = SEEK_SET; - offset = fpos + offset + fp->bufpos - fp->bufread; - } - if( ref == SEEK_SET ) - { - if ( offset < fpos && offset >= fpos + fp->bufstart - fp->bufread ) - { - fp->bufpos = offset - fpos + fp->bufread; - return 0; - } - } - } -#endif - - /* Use fflush to sync the pointers */ - - if (fflush(fp) == EOF) - return EOF; - if (lseek(fp->fd, offset, ref) < 0) - return EOF; - return 0; -} -#endif - -#ifdef L_ftell -long ftell(fp) -FILE * fp; -{ - long rv; - if (fflush(fp) == EOF) - return EOF; - return lseek(fp->fd, 0L, SEEK_CUR); -} -#endif - -#ifdef L_fopen -/* - * This Fopen is all three of fopen, fdopen and freopen. The macros in - * stdio.h show the other names. - */ -FILE * -__fopen(fname, fd, fp, mode) -char *fname; -int fd; -FILE *fp; -char *mode; -{ - int open_mode = 0; -#if __MODE_IOTRAN && !O_BINARY - int do_iosense = 1; -#endif - int fopen_mode = 0; - FILE *nfp = 0; - - /* If we've got an fp close the old one (freopen) */ - if (fp) - { - /* Careful, don't de-allocate it */ - fopen_mode |= (fp->mode & (__MODE_BUF | __MODE_FREEFIL | __MODE_FREEBUF)); - fp->mode &= ~(__MODE_FREEFIL | __MODE_FREEBUF); - fclose(fp); - } - - /* decode the new open mode */ - while (*mode) - switch (*mode++) - { - case 'r': - fopen_mode |= __MODE_READ; - break; - case 'w': - fopen_mode |= __MODE_WRITE; - open_mode = (O_CREAT | O_TRUNC); - break; - case 'a': - fopen_mode |= __MODE_WRITE; - open_mode = (O_CREAT | O_APPEND); - break; - case '+': - fopen_mode |= __MODE_RDWR; - break; -#if __MODE_IOTRAN || O_BINARY - case 'b': /* Binary */ - fopen_mode &= ~__MODE_IOTRAN; - open_mode |= O_BINARY; -#if __MODE_IOTRAN && !O_BINARY - do_iosense=0; -#endif - break; - case 't': /* Text */ - fopen_mode |= __MODE_IOTRAN; -#if __MODE_IOTRAN && !O_BINARY - do_iosense=0; -#endif - break; -#endif - } - - /* Add in the read/write options to mode for open() */ - switch (fopen_mode & (__MODE_READ | __MODE_WRITE)) - { - case 0: - return 0; - case __MODE_READ: - open_mode |= O_RDONLY; - break; - case __MODE_WRITE: - open_mode |= O_WRONLY; - break; - default: - open_mode |= O_RDWR; - break; - } - - /* Allocate the (FILE) before we do anything irreversable */ - if (fp == 0) - { - nfp = malloc(sizeof(FILE)); - if (nfp == 0) - return 0; - } - - /* Open the file itself */ - if (fname) - fd = open(fname, open_mode, 0666); - if (fd < 0) /* Grrrr */ - { - if (nfp) - free(nfp); - if (fp) - { - fp->mode |= fopen_mode; - fclose(fp); /* Deallocate if required */ - } - return 0; - } - - /* If this isn't freopen create a (FILE) and buffer for it */ - if (fp == 0) - { - fp = nfp; - fp->next = __IO_list; - __IO_list = fp; - - fp->mode = __MODE_FREEFIL; - if( isatty(fd) ) - { - fp->mode |= _IOLBF; -#if __MODE_IOTRAN && !O_BINARY - if( do_iosense ) fopen_mode |= __MODE_IOTRAN; -#endif - } - else - fp->mode |= _IOFBF; - fp->bufstart = malloc(BUFSIZ); - if (fp->bufstart == 0) /* Oops, no mem */ - { /* Humm, full buffering with a two(!) byte - * buffer. */ - fp->bufstart = fp->unbuf; - fp->bufend = fp->unbuf + sizeof(fp->unbuf); - } - else - { - fp->bufend = fp->bufstart + BUFSIZ; - fp->mode |= __MODE_FREEBUF; - } - } - - /* Ok, file's ready clear the buffer and save important bits */ - fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart; - fp->mode |= fopen_mode; - fp->fd = fd; - - return fp; -} -#endif - -#ifdef L_fclose -int -fclose(fp) -FILE *fp; -{ - int rv = 0; - - if (fp == 0) - { - errno = EINVAL; - return EOF; - } - if (fp->fd != -1) - { - if (fflush(fp)) - return EOF; - - if (close(fp->fd)) - rv = EOF; - fp->fd = -1; - } - - if (fp->mode & __MODE_FREEBUF) - { - free(fp->bufstart); - fp->mode &= ~__MODE_FREEBUF; - fp->bufstart = fp->bufend = 0; - } - - if (fp->mode & __MODE_FREEFIL) - { - FILE *prev = 0, *ptr; - fp->mode = 0; - - for (ptr = __IO_list; ptr && ptr != fp; ptr = ptr->next) - ; - if (ptr == fp) - { - if (prev == 0) - __IO_list = fp->next; - else - prev->next = fp->next; - } - free(fp); - } - else - fp->mode = 0; - - return rv; -} -#endif - -#ifdef L_setbuffer -void -setbuffer(fp, buf, size) -FILE * fp; -char * buf; -int size; -{ - fflush(fp); - if( fp->mode & __MODE_FREEBUF ) free(fp->bufstart); - fp->mode &= ~(__MODE_FREEBUF|__MODE_BUF); - - if( buf == 0 ) - { - fp->bufstart = fp->unbuf; - fp->bufend = fp->unbuf + sizeof(fp->unbuf); - fp->mode |= _IONBF; - } - else - { - fp->bufstart = buf; - fp->bufend = buf+size; - fp->mode |= _IOFBF; - } - fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart; -} -#endif - -#ifdef L_setvbuf -int setvbuf(fp, buf, mode, size) -FILE * fp; -char * buf; -int mode; -size_t size; -{ - int rv = 0; - fflush(fp); - if( fp->mode & __MODE_FREEBUF ) free(fp->bufstart); - fp->mode &= ~(__MODE_FREEBUF|__MODE_BUF); - fp->bufstart = fp->unbuf; - fp->bufend = fp->unbuf + sizeof(fp->unbuf); - fp->mode |= _IONBF; - - if( mode == _IOFBF || mode == _IOLBF ) - { - if( size <= 0 ) size = BUFSIZ; - if( buf == 0 ) - { - if( (buf = malloc(size)) != 0 ) - fp->mode |= __MODE_FREEBUF; - else rv = EOF; - } - if( buf ) - { - fp->bufstart = buf; - fp->bufend = buf+size; - fp->mode &= ~__MODE_BUF; - fp->mode |= mode; - } - } - fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart; - return rv; -} -#endif - -#ifdef L_ungetc -int -ungetc(c, fp) -int c; -FILE *fp; -{ - if (fp->mode & __MODE_WRITING) - fflush(fp); - - /* Can't read or there's been an error then return EOF */ - if ((fp->mode & (__MODE_READ | __MODE_ERR)) != __MODE_READ) - return EOF; - - /* Can't do fast fseeks */ - fp->mode |= __MODE_UNGOT; - - if( fp->bufpos > fp->bufstart ) - return *--fp->bufpos = (unsigned char) c; - else if( fp->bufread == fp->bufstart ) - return *fp->bufread++ = (unsigned char) c; - else - return EOF; -} -#endif - diff -Nurd linux86.old/libc/stdio2/stdio.h linux86/libc/stdio2/stdio.h --- linux86.old/libc/stdio2/stdio.h Mon Feb 1 08:36:35 1999 +++ linux86/libc/stdio2/stdio.h Thu Jan 1 01:00:00 1970 @@ -1,129 +0,0 @@ - -#ifndef __STDIO_H -#define __STDIO_H - -#include -#include - -#ifndef SEEK_SET -#define SEEK_SET 0 -#define SEEK_CUR 1 -#define SEEK_END 2 -#endif - -#define _IOFBF 0x00 /* full buffering */ -#define _IOLBF 0x01 /* line buffering */ -#define _IONBF 0x02 /* no buffering */ -#define __MODE_BUF 0x03 /* Modal buffering dependent on isatty */ - -#define __MODE_FREEBUF 0x04 /* Buffer allocated with malloc, can free */ -#define __MODE_FREEFIL 0x08 /* FILE allocated with malloc, can free */ - -#define __MODE_READ 0x10 /* Opened in read only */ -#define __MODE_WRITE 0x20 /* Opened in write only */ -#define __MODE_RDWR 0x30 /* Opened in read/write */ - -#define __MODE_READING 0x40 /* Buffer has pending read data */ -#define __MODE_WRITING 0x80 /* Buffer has pending write data */ - -#define __MODE_EOF 0x100 /* EOF status */ -#define __MODE_ERR 0x200 /* Error status */ -#define __MODE_UNGOT 0x400 /* Buffer has been polluted by ungetc */ - -#ifdef __MSDOS__ -#define __MODE_IOTRAN 0x1000 /* MSDOS nl <-> cr,nl translation */ -#else -#define __MODE_IOTRAN 0 -#endif - -/* when you add or change fields here, be sure to change the initialization - * in stdio_init and fopen */ -struct __stdio_file { - unsigned char *bufpos; /* the next byte to write to or read from */ - unsigned char *bufread; /* the end of data returned by last read() */ - unsigned char *bufwrite; /* highest address writable by macro */ - unsigned char *bufstart; /* the start of the buffer */ - unsigned char *bufend; /* the end of the buffer; ie the byte after the last - malloc()ed byte */ - - int fd; /* the file descriptor associated with the stream */ - int mode; - - char unbuf[8]; /* The buffer for 'unbuffered' streams */ - - struct __stdio_file * next; -}; - -#define EOF (-1) -#ifndef NULL -#define NULL ((void*)0) -#endif - -typedef struct __stdio_file FILE; - -#ifdef __AS386_16__ -#define BUFSIZ (256) -#else -#define BUFSIZ (2048) -#endif - -extern FILE stdin[1]; -extern FILE stdout[1]; -extern FILE stderr[1]; - -#ifdef __MSDOS__ -#define putc(c, fp) fputc(c, fp) -#define getc(fp) fgetc(fp) -#else -#define putc(c, stream) \ - (((stream)->bufpos >= (stream)->bufwrite) ? fputc((c), (stream)) \ - : (unsigned char) (*(stream)->bufpos++ = (c)) ) - -#define getc(stream) \ - (((stream)->bufpos >= (stream)->bufread) ? fgetc(stream): \ - (*(stream)->bufpos++)) -#endif - -#define putchar(c) putc((c), stdout) -#define getchar() getc(stdin) - -#define ferror(fp) (((fp)->mode&__MODE_ERR) != 0) -#define feof(fp) (((fp)->mode&__MODE_EOF) != 0) -#define clearerr(fp) ((fp)->mode &= ~(__MODE_EOF|__MODE_ERR),0) -#define fileno(fp) ((fp)->fd) - -/* declare functions; not like it makes much difference without ANSI */ -/* RDB: The return values _are_ important, especially if we ever use - 8086 'large' model - */ - -/* These two call malloc */ -#define setlinebuf(__fp) setvbuf((__fp), (char*)0, _IOLBF, 0) -extern int setvbuf __P((FILE*, char*, int, size_t)); - -/* These don't */ -#define setbuf(__fp, __buf) setbuffer((__fp), (__buf), BUFSIZ) -extern void setbuffer __P((FILE*, char*, int)); - -extern int fgetc __P((FILE*)); -extern int fputc __P((int, FILE*)); - -extern int fclose __P((FILE*)); -extern int fflush __P((FILE*)); -extern char *fgets __P((char*, size_t, FILE*)); -extern FILE *__fopen __P((char*, int, FILE*, char*)); - -#define fopen(__file, __mode) __fopen((__file), -1, (FILE*)0, (__mode)) -#define freopen(__file, __mode, __fp) __fopen((__file), -1, (__fp), (__mode)) -#define fdopen(__file, __mode) __fopen((char*)0, (__file), (FILE*)0, (__mode)) - -extern int fputs __P((char*, FILE*)); -extern int puts __P((char*)); - -extern int printf __P ((__const char*, ...)); -extern int fprintf __P ((FILE*, __const char*, ...)); -extern int sprintf __P ((char*, __const char*, ...)); - -#define stdio_pending(fp) ((fp)->bufread>(fp)->bufpos) - -#endif /* __STDIO_H */ diff -Nurd linux86.old/makefile.in linux86/makefile.in --- linux86.old/makefile.in Fri Jul 23 08:56:41 1999 +++ linux86/makefile.in Sat Jan 6 14:20:47 2001 @@ -39,12 +39,8 @@ WALL =-Wstrict-prototypes CC =gcc -#ifdef __i386__ -CFLAGS =$(GCCFLAG) -Wall $(WALL) -O2 -m486 -g -#else CFLAGS =$(GCCFLAG) -Wall $(WALL) -O6 -g #endif -#endif #ifndef GNUMAKE MAKEC=sh makec @@ -71,9 +67,15 @@ #endif # Alter these if for some reason you don't want this done as root. +#ifdef __BCC__ +INDAT=-o root -g root -m 644 +INEXE=-o root -g root -m 755 +INSCR=-o root -g root -m 755 +#else INDAT=-o root -g root -m 644 INEXE=-o root -g root -m 755 -s INSCR=-o root -g root -m 755 +#endif #ifdef GNUMAKE all: check_config bcc unproto copt as86 ar86 ld86 objdump86 \ @@ -126,8 +128,6 @@ @ln -s ../kinclude/arch include/arch 2>/dev/null || true #endif -phony: - bcc: bindir $(MAKEC) bcc $(MAKEARG) BCCARCH='$(BCCARCH)' bcc ncc bcc-cc1 cp -p bcc/bcc bin/Bcc @@ -319,14 +319,14 @@ ############################################################################## -install-other: phony +install-other: @for i in $(OTHERS) ; do \ $(MAKEC) $$i BCC=ncc DIST=$(DIST) PREFIX=$(PREFIX) install || exit 1 ; \ done other: $(OTHERS) -$(OTHERS): phony +$(OTHERS): $(MAKEC) $@ BCC=ncc clean: diff -Nurd linux86.old/man/as86.1 linux86/man/as86.1 --- linux86.old/man/as86.1 Thu Aug 12 11:47:13 1999 +++ linux86/man/as86.1 Tue Sep 26 21:18:31 2000 @@ -83,17 +83,22 @@ only put global symbols in object or symbol file .TP .B -j -replace short jumps that don't reach with 5 byte sequences, this causes the -assembler to add an extra pass to try to determine if the long jump is -really needed. If you add a second -.B -j -the assembler will keep adding passes until the labels all stabilise (to -a maximum of 30 passes) -Don't use this with hand written assembler use the explicit +replace all short jumps with similar 16 or 32 bit jumps, the 16 bit +conditional branches are encoded as a short conditional and a long +unconditional branch. +.TP +.B -O +this causes the assembler to add extra passes to try to use forward +references to reduce the bytes needed for some instructions. +If the labels move on the last pass the assembler will keep adding passes +until the labels all stabilise (to a maximum of 30 passes) +It's probably not a good idea to use this with hand written assembler +use the explicit .B br\ bmi\ bcc style opcodes for 8086 code or the .B jmp\ near -style for conditional i386 instructions. +style for conditional i386 instructions and make sure all variables are +defined before they are used. .TP .B -l produce list file, filename may follow Binary files linux86.old/man/index.bt and linux86/man/index.bt differ diff -Nurd linux86.old/unproto/Makefile linux86/unproto/Makefile --- linux86.old/unproto/Makefile Fri Jan 24 18:53:53 1997 +++ linux86/unproto/Makefile Sat Jan 6 12:37:21 2001 @@ -89,7 +89,7 @@ #CFLAGS = -g $(PIPE) $(SKIP) $(BELL) $(MAP) $(ALIAS) -DDEBUG $(PROG): $(OBJECTS) - $(CC) $(CCFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) $(MALLOC) + $(CC) $(CCFLAGS) $(LDFLAGS) -o $@ $^ $(MALLOC) .c.o: $(CC) $(CCFLAGS) -c $< -o $@