* Manoj Srivastava <[EMAIL PROTECTED]> [050708 12:11]: > Yes, this is a bug. But given the preponderance of code that > does not check each and every printf (most checks being done at fopen > time), it is safe to say that it is common assumption that partition > full errors are uncommon, and may cause silent errors, at least for > files that had been opened for writing. > > It would be nice if every printf statement return value was > paid attention to, yes, but is a lot of effort for one uncommon > corner case.
There are not only full partitions, there are hard-quotas, soft-mounted NFS-servers and all things like that. It's also quite awkward, as in a typical use case make will not recall flex once there is space again, but keep the file truncated somwhere in the middle, leading to hard to debug build problems. Also note that not every printf statement needs attention paid, as streams keep the error status for ferror, so only ferror and fclose need to be checked. Flex already does that by the way, but not in the filters actually writing to the files, and it discards the errors of its children. The attached fix changes that, causing proper errors returned. I'm lacking the overview to be sure it causes no regressions, but I'd be quite suprised and "make check" still works. Hochachtungsvoll, Bernhard R. Link
diff -u flex-2.5.31/filter.c flex-new/filter.c --- flex-2.5.31/filter.c 2005-07-09 18:04:15.000000000 +0200 +++ flex-new/filter.c 2005-07-09 16:07:02.000000000 +0200 @@ -292,12 +292,23 @@ fputs ("m4_undefine( [[M4_YY_IN_HEADER]])m4_dnl\n", to_h); fflush (to_h); - fclose (to_h); + if (ferror (to_h)) + lerrsf (_("error writing output file %s"), + (char *) chain->extra); + + else if (fclose (to_h)) + lerrsf (_("error closing output file %s"), + (char *) chain->extra); } fflush (to_c); - fclose (to_c); - + if (ferror (to_c)) + lerrsf (_("error writing output file %s"), + outfilename ? outfilename : "<stdout>"); + + else if (fclose (to_c)) + lerrsf (_("error closing output file %s"), + outfilename ? outfilename : "<stdout>"); while (wait (0) > 0) ; @@ -379,6 +390,13 @@ lineno++; } fflush (stdout); + if (ferror (stdout)) + lerrsf (_("error writing output file %s"), + outfilename ? outfilename : "<stdout>"); + + else if (fclose (stdout)) + lerrsf (_("error closing output file %s"), + outfilename ? outfilename : "<stdout>"); return 0; } diff -u flex-2.5.31/main.c flex-new/main.c --- flex-2.5.31/main.c 2005-07-09 18:04:15.000000000 +0200 +++ flex-new/main.c 2005-07-09 18:02:46.000000000 +0200 @@ -147,7 +147,7 @@ int argc; char *argv[]; { - int i, exit_status; + int i, exit_status, child_status; /* Set a longjmp target. Yes, I know it's a hack, but it gets worse: The * return value of setjmp, if non-zero, is the desired exit code PLUS ONE. @@ -160,7 +160,15 @@ if (exit_status){ fflush(stdout); fclose(stdout); - while (wait(0) > 0){ + while (wait(&child_status) > 0){ + if (!WIFEXITED (child_status) || + WEXITSTATUS (child_status) != 0){ + /* report an error of a child + */ + if( exit_status <= 1 ) + exit_status = 2; + + } } return exit_status - 1; }