[prev in list] [next in list] [prev in thread] [next in thread] 

List:       gnulib-bug
Subject:    fbufmode: fix test
From:       Bruno Haible <bruno () clisp ! org>
Date:       2012-06-22 10:03:39
Message-ID: 3172811.NX3WXULE7G () linuix
[Download RAW message or body]

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  <bruno@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 <nsz@port70.net>
	and Rich Felker <dalias@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");


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic