mj@myrias.UUCP (Michal Jaegermann) (06/13/89)
A recent posting by Dale Schumacher of a set of fixes for dLibs v1.2
uncovered a need for a continuation of his excellent work. (However this
sounds this last sentence means what is says. Thanks, Dale.)
Scenario: you are opening a file for reading and reading until
End-Of-File is reached. At this moment you are closing the file and
fclose returns EOF indicating an error (a false one)!
Reason: New-and-improved fclose checks for a status of close AND
fflush. fflush fails since _fflush tries to re-align the file pointer
executing lseek(fp->file, offset, 1). But offset, set to -(fp->_cnt) is
in this moment equal one and lseek justly complains that we are trying
to seek past the end of a file. The last call to gemdos read (0x3f)
filled _cnt location in a file buffer with 0xffff. (None of the
documentation which I have says that this will happen, so I guess that
this has to be taken as an uncalled side effect).
Fix: In file fget.c replace two lines
c = EOF;
goto _fgetc2;
with
c = EOF;
fp->_cnt = 0;
goto _fgetc2;
Is anybody aware of things which will go broke after this?
A search for this bug revealed two other things. First: a value of
errno is not always a 'sticky' one like it should be, i.e. some
error-free calls are resetting its value to zero. In the particular
case above fclose claimed that there is an error, but perror was
assuring me that everythig is OK. A value of errno was reset by a
succesful close which follows fflush. In order to restore sanity and
*nix conformance a handling of errno should be corrected in the
following files (sometimes in one place this is correct and two lines
below not): chdir.c, creat.c, dup.c, mkdir.c, open.c, remove.c,
rename.c, rmdir.c, stat.c, stime.c. Look for example into lseek.c for a
model how this should be done. Hope that I did not missed anything.
Second: Sozobon compiles EOF into a _byte_ constant, widening it almost
immediately into a word. A little bit strange for a language in which
even 'x' is an integer constant. You may nudge a compiler into doing
a better job by #define'ing EOF as (int)(-1). Such trick will not work
for any constant used in array definitions since compiler insists that
(int)5 is not a constant expression. I am not sure. Maybe it is even right.
All of this you are getting for checking return values in places
where is obvious that nothing can go wrong. :-)
Now for a bonus. The following makefile will make you library updates
much more enjoyable. Now and in the future. (Naw..., who says that we
will need it in a future, this is the last bug fix - right?)
--------------------------/ tear off here /--------------------------------
# Makefile for an automatical update of dLibs C libraries.
# Update header files before you will start this compilation!!
#
# Edit this file to your taste and hit 'make'
#
# Michal Jaegermann - 11 June 1989
#
# If you are using Sozobon compiler then execution of globs
# is not needed, but it will bring no harm
#
# Adjust to your setting and needs - $(GB) can be set to 'echo'
# if you do not want it to execute. Skip .ttp for gulam
CC = cc.ttp
GB = globs.ttp
AR = ar.ttp
CFLAGS = -O
.c.o:
$(CC) -c $(CFLAGS) $<
$(GB) $*.o
$(AR) -r dlibs.a $*.o
.s.o:
$(CC) -c $(CFLAGS) $<
$(GB) $*.o
$(AR) -r dlibs.a $*.o
# make $(SRCS) and $(OBJS) to reflect files you would like to change
# this needed in order not to make arc command line too long
SRCSA = bzero.s fdopen.c fopen.c memcpy.s perror.c write.c fclose.c
SRCSB = findfile.c lmemcpy.s open.c stat.c fgetc.c chdir.c creat.c
SRCSC = dup.c mkdir.c open.c remove.c rename.c rmdir.c stat.c stime.c
SRCS = $(SRCSA) $(SRCSB) $(SRCSC)
OBJS = bzero.o fdopen.o fopen.o memcpy.o perror.o write.o \
fclose.o findfile.o lmemcpy.o open.o stat.o fgetc.o \
chdir.o creat.o dup.o mkdir.o open.o remove.o \
rename.o rmdir.o stat.o stime.o
all: $(OBJS)
$(AR) -tv dlibs.a
# arc u src.arc $(SRCSA)
# arc u src.arc $(SRCSB)
# arc u src.arc $(SRCSC)
# doindex.prg dlibs.a
# the action of doindex needed only if you are using aln linker
--------------------------/ tear off here /--------------------------------
Michal Jaegermann
Myrias Research Corporation
Edmonton, Alberta, CANADA
...{ncc, alberta}!myrias!mj