Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!ucbvax!hplabs!hp-ses!hpcc01!hpccc!culberts From: culberts@hpccc.HP.COM (Bruce Culbertson) Newsgroups: comp.os.minix Subject: Re: fopen (r+,w+,a+) Message-ID: <6910002@hpccc.HP.COM> Date: 21 Jul 89 02:31:42 GMT References: <18518@louie.udel.EDU> Organization: Hewlett-Packard Co. Lines: 82 I think there are some incompatibilities between the recently posted buffered I/O library routines and the ones I have used on BSD and System V Unix. In my experience, buffered files are flushed 1) when their buffers fill, 2) when explicitly flushed with a call to fflush(), 3) when the file is closed, 4) when the process calls exit(), and 5) if stdin is read, stdout is flushed. Unfortunately, I cannot seem to find a description of this in my Unix documentation. Perhaps someone else will find the documentation and comment. The new routines differ in the following ways: A) Stdout is not flushed when stdin is read. B) Stdout is flushed on all (f)printf's to stdout. C) Stdout is flushed after all newlines are written to stdout. Problem A breaks several applications which perform fine on various Unix systems. The problem is not apparent if prompts for interactive input are written with (f)printf because of B. However, if a prompt is written with (f)putc or fwrite, it never appears. B and C are merely performance issues, but perhaps are worth considering since stdio exists solely to improve performance. After implementing 5, I had no further trouble with the new routines. Having the "+" options in fopen is a nice improvement. ------------------------------------------------------------------ /* 17 Jun 89 r+,w+,a+ added RAL */ #include fgetc(iop) FILE *iop; { int ch; if ( testflag(iop, (_EOF | _ERR ))) return (EOF); if (iop == stdin && stdout->_count > 0) fflush (stdout); if ( !testflag(iop, READMODE) ) { if (!testflag(iop, RDWRMODE)) return (EOF); fflush(iop); iop->_count = 0; iop->_ptr = iop->_buf; iop->_flags &= ~WRITEMODE; iop->_flags |= READMODE; } if (iop->_count <= 0){ if ( testflag(iop, UNBUFF) ) iop->_count = read(iop->_fd,&ch,1); else iop->_count = read(iop->_fd,iop->_buf,BUFSIZ); if (iop->_count <= 0){ if (iop->_count == 0) iop->_flags |= _EOF; else iop->_flags |= _ERR; return (EOF); } else iop->_ptr = iop->_buf; } iop->_count--; /* account one char */ if (testflag(iop,UNBUFF)) return (ch & CMASK); else return (*iop->_ptr++ & CMASK); }