The musl people reported that gnulib's fbuftest was testing "undefined behaviour" according to the ISO C standard: <http://www.openwall.com/lists/musl/2012/06/17/9> <http://www.openwall.com/lists/musl/2012/06/17/10> This fixes it.
2012-06-22 Bruno Haible <br...@clisp.org> fbufmode test: Don't test unportable behaviour. * tests/test-fbufmode.c (test_mode): New function, extracted from main. (main): Invoke it three times. Reported by Szabolcs Nagy <n...@port70.net> and Rich Felker <dal...@aerifal.cx>. *** tests/test-fbufmode.c.orig Fri Jun 22 11:56:48 2012 --- tests/test-fbufmode.c Fri Jun 22 11:52:27 2012 *************** *** 26,70 **** #define TESTFILE "t-fbufmode.tmp" ! int ! main () { FILE *fp; char buf[5]; - /* Create a file with some contents. */ - fp = fopen (TESTFILE, "w"); - if (fp == NULL) - goto skip; - if (fwrite ("foobarsh", 1, 8, fp) < 8) - goto skip; - if (fclose (fp)) - goto skip; - /* Open it for reading. */ fp = fopen (TESTFILE, "r"); ! if (setvbuf (fp, NULL, _IONBF, 0)) ! goto skip; ! ASSERT (fbufmode (fp) == _IONBF); ! ! /* This setvbuf call can fail, e.g. on HP-UX 11. */ ! if (setvbuf (fp, buf, _IOLBF, 5) == 0) { /* mingw's setvbuf implements _IOLBF the same way as _IOFBF. */ ASSERT (fbufmode (fp) == _IOLBF || fbufmode (fp) == _IOFBF); ! } ! /* This setvbuf call can fail, e.g. on HP-UX 11. */ ! if (setvbuf (fp, buf, _IOFBF, 5) == 0) ! { ASSERT (fbufmode (fp) == _IOFBF); } fclose (fp); return 0; skip: fprintf (stderr, "Skipping test: file operations failed.\n"); --- 26,105 ---- #define TESTFILE "t-fbufmode.tmp" ! /* ISO C99 disallows more than one setvbuf call on a given stream, ! and HP-UX 11 and musl libc indeed don't support such use of setvbuf. ! Therefore allocate a new stream for each possible mode value. */ ! static int ! test_mode (int mode) { FILE *fp; char buf[5]; /* Open it for reading. */ fp = fopen (TESTFILE, "r"); ! switch (mode) { + case _IONBF: + ASSERT (setvbuf (fp, NULL, _IONBF, 0) == 0); + ASSERT (fbufmode (fp) == _IONBF); + break; + + case _IOLBF: + ASSERT (setvbuf (fp, buf, _IOLBF, 5) == 0); /* mingw's setvbuf implements _IOLBF the same way as _IOFBF. */ ASSERT (fbufmode (fp) == _IOLBF || fbufmode (fp) == _IOFBF); ! break; ! case _IOFBF: ! ASSERT (setvbuf (fp, buf, _IOFBF, 5) == 0); ASSERT (fbufmode (fp) == _IOFBF); + break; + + default: + break; } fclose (fp); return 0; + } + + int + main () + { + int ret; + + /* Create a file with some contents. */ + { + FILE *fp; + + fp = fopen (TESTFILE, "w"); + if (fp == NULL) + goto skip; + if (fwrite ("foobarsh", 1, 8, fp) < 8) + goto skip; + if (fclose (fp)) + goto skip; + } + + ret = test_mode (_IONBF); + if (ret != 0) + goto fail; + + ret = test_mode (_IOLBF); + if (ret != 0) + goto fail; + + ret = test_mode (_IOFBF); + if (ret != 0) + goto fail; + + return 0; + + fail: + return ret; skip: fprintf (stderr, "Skipping test: file operations failed.\n");