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