gnu@sun.uucp (John Gilmore) (08/15/85)
> > The printf() function CAN FAIL and if you don't test for it, > > Murphy says that it WILL fail, under the worst possible > > circumstances (e.g., while updating YOUR pay record). > > /usr/lib/news/expire uses fprintf to re-write the active file. It > didn't take the time to check the return value, and happened to run > one night when /usr was full. Result -- a 0 length active file and > a great deal of unhappy news software. printf (and fprintf) DO FAIL! Furthermore, the code in readnews/vnews that implements the "s" command (save a message to a file) does not check. The result is that a day's worth of [manually] archived net.sources stuff ended up as zero length files, when my net.sources file system filled up -- with no error messages at all. Luckily I noticed the empty files before the original messages expired. For the people asking "well what can I do if printf returns an error": how about printing an error to standard error and stopping? That's better than letting the data be thrown away without warning. (Interactive programs like vnews should, of course, not "stop" but should print a message and go back to the command interpreter.)
root@bu-cs.UUCP (Barry Shein) (08/16/85)
All this talk about printf() return values not being checked causing
various catastrophes reminds me of another system that had what might
provide a good back-door solution to this without very much re-coding,
namely the IBM/OS SYNAD=addr option. You could set up a (in unix lingo)
a signal handler and if any I/O error occurred it would interrupt to
that routine. Now this was on a per-write (actually, per I/O) basis but
what I have in mind here is to do something like:
#define printf eprintf
#define fprintf efprintf
then add to main() something like
signal(SIGIOT,myhandler) ; /* choose a signal, SIGIOT seems good*/
and something reasonable for myhandler() and finally:
eprintf(fmt,a,b,c,d,e,f,g...) /* etc or maybe use varargs */
{
int n ;
if((n = printf(fmt,a,b,...)) < 0)
kill(0,SIGIOT) ;
return(n) ;
}
and almost exactly the same for efprintf(fp,...).
(of course, the file with these routines must *not* have the #defines.
Then of course, you get to decide what to do now that you have the
error, but saves you from a lot of re-working of code.
-Barry Shein, Boston University
Just a suggestion.
dave@uwvax.UUCP (Dave Cohrs) (08/17/85)
I had an even worse problem with receiving new news recently. My /usr filesystem filled up (where /usr/lib/news lives, of course) and expire ran. What happened then? Well, log ==> olog, history ==> ohistory, etc and the active file got rebuilt. But wait, there wasn't any space left (and I mean none, root was at fault), so the log, history, and active files ended up being NULL which causes problems for people trying to read news. News, especially expire and inews, must check their files to make sure they aren't blowing everything away. -- Dave Cohrs (608) 262-1204 ...!{harvard,ihnp4,seismo,topaz}!uwvax!dave dave@wisc-romano.arpa