msb@sq.uucp (Mark Brader) (04/15/88)
Weird. One day I find a bug in compress, and the next day we get a news posting about another form of it. Rick Perry writes: > ... while using 'zcat x.Z', if you interrupt it, > it removes the file 'x'. It turns out that no matter whether you're using it in its identity as zcat, compress, or uncompress, in each case there exists a time window when an interrupt will leave you with both x and x.Z removed. For instance, if you "uncompress x.Z" and interrupt just as it's finishing... This is because the interrupt handler is always enabled and too simple: it just assumes that ofname[] contains the name of a file it can remove. Below is my fix. It covers Rick's bug too, so you don't have to install his fix as well. I also amended the rather optimistic message in the SIGSEGV handler, as you will see. We have compress version 4.0. As we don't use RCS here, I haven't adjusted the RCS id stuff. Mark Brader, SoftQuad Inc., Toronto, utzoo!sq!msb, msb@sq.com "I'm a little worried about the bug-eater," she said. "We're embedded in bugs, have you noticed?" -- Niven, "The Integral Trees" *** /tmp/da3150 Fri Apr 15 08:03:05 1988 --- compress.c Fri Apr 15 08:02:31 1988 *************** *** 138,143 **** --- 138,147 ---- * James A. Woods (decvax!ihnp4!ames!jaw) * Joe Orost (decvax!vax135!petsd!joe) * + * Mark Brader (sq!msb) added checking so that we don't end up + * with both input and output files removed on interrupts. + * This is not in the RCS numbering. + * * $Header: compress.c,v 4.0 85/07/30 12:50:00 joe Release $ * $Log: compress.c,v $ * Revision 4.0 85/07/30 12:50:00 joe *************** *** 357,362 **** --- 361,368 ---- int force = 0; char ofname [100]; + int oktozap = 0; /* true if unlink(ofname) won't lose data */ + #ifdef DEBUG int verbose = 0; #endif /* DEBUG */ *************** *** 625,630 **** --- 631,637 ---- } } if(zcat_flg == 0) { /* Open output file */ + oktozap = 1; if (freopen(ofname, "w", stdout) == NULL) { perror(ofname); continue; *************** *** 1277,1282 **** --- 1284,1290 ---- time_t timep[2]; fclose(stdout); + oktozap = 0; if (stat(ifname, &statbuf)) { /* Get stat on input file */ perror(ifname); return; *************** *** 1334,1340 **** onintr ( ) { ! unlink ( ofname ); exit ( 1 ); } --- 1342,1349 ---- onintr ( ) { ! if (oktozap) ! unlink ( ofname ); exit ( 1 ); } *************** *** 1341,1348 **** oops ( ) /* wild pointer -- assume bad input */ { if ( do_decomp == 1 ) ! fprintf ( stderr, "uncompress: corrupt input\n" ); ! unlink ( ofname ); exit ( 1 ); } --- 1350,1359 ---- oops ( ) /* wild pointer -- assume bad input */ { if ( do_decomp == 1 ) ! fprintf ( stderr, ! "uncompress: segmentation violation - probably corrupt input\n" ); ! if (oktozap) ! unlink ( ofname ); exit ( 1 ); }