[BZ #316]
authorRoland McGrath <roland@gnu.org>
Tue, 10 Aug 2004 18:01:40 +0000 (18:01 +0000)
committerRoland McGrath <roland@gnu.org>
Tue, 10 Aug 2004 18:01:40 +0000 (18:01 +0000)
2004-08-10  Jakub Jelinek  <jakub@redhat.com>
* libio/bits/stdio.h (fread_unlocked): Cast 0 to (size_t).
(fwrite_unlocked): When checking if size * n is <= 8, cast each
argument to size_t individually.  Cast n to (void) instead of
(size_t), surround with (), return (size_t) 0 if one of n or size
is 0.  [BZ #316]
* stdio-common/Makefile (tests): Add tst-unlockedio.
* stdio-common/tst-unlockedio.c: New test.

ChangeLog
libio/bits/stdio.h
stdio-common/Makefile
stdio-common/tst-unlockedio.c [new file with mode: 0644]

index 5ec7a28..2ea0689 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2004-08-10  Jakub Jelinek  <jakub@redhat.com>
+
+       * libio/bits/stdio.h (fread_unlocked): Cast 0 to (size_t).
+       (fwrite_unlocked): When checking if size * n is <= 8, cast each
+       argument to size_t individually.  Cast n to (void) instead of
+       (size_t), surround with (), return (size_t) 0 if one of n or size
+       is 0.  [BZ #316]
+       * stdio-common/Makefile (tests): Add tst-unlockedio.
+       * stdio-common/tst-unlockedio.c: New test.
+
 2004-08-09  Roland McGrath  <roland@frob.com>
 
        * manual/install.texi (Supported Configurations): Replace bug-glibc
index e602dbd..60c937f 100644 (file)
@@ -148,12 +148,13 @@ ferror_unlocked (FILE *__stream) __THROW
                      || (__builtin_constant_p (n) && (size_t) (n) == 0))     \
                        /* Evaluate all parameters once.  */                  \
                     ? ((void) (ptr), (void) (stream), (void) (size),         \
-                       (void) (n), 0)                                        \
+                       (void) (n), (size_t) 0)                               \
                     : fread_unlocked (ptr, size, n, stream))))
 
 # define fwrite_unlocked(ptr, size, n, stream) \
   (__extension__ ((__builtin_constant_p (size) && __builtin_constant_p (n)    \
-                  && (size_t) ((size) * (n)) <= 8 && (size_t) (size) != 0)   \
+                  && (size_t) (size) * (size_t) (n) <= 8                     \
+                  && (size_t) (size) != 0)                                   \
                  ? ({ const char *__ptr = (const char *) (ptr);              \
                       FILE *__stream = (stream);                             \
                       size_t __cnt;                                          \
@@ -167,7 +168,7 @@ ferror_unlocked (FILE *__stream) __THROW
                      || (__builtin_constant_p (n) && (size_t) (n) == 0))     \
                        /* Evaluate all parameters once.  */                  \
                     ? ((void) (ptr), (void) (stream), (void) (size),         \
-                       (size_t) n)                                           \
+                       (void) (n), (size_t) 0)                               \
                     : fwrite_unlocked (ptr, size, n, stream))))
 #endif
 
index ab573e6..3a66f1d 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 1991-2002, 2003 Free Software Foundation, Inc.
+# Copyright (C) 1991-2002, 2003, 2004 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 
 # The GNU C Library is free software; you can redistribute it and/or
@@ -53,7 +53,7 @@ tests := tstscanf test_rdwr test-popen tstgetln test-fseek \
         scanf11 scanf12 tst-tmpnam tst-cookie tst-obprintf tst-sscanf \
         tst-swprintf tst-fseek tst-fmemopen test-vfprintf tst-gets \
         tst-perror tst-sprintf tst-rndseek tst-fdopen tst-fphex bug14 bug15 \
-        tst-popen
+        tst-popen tst-unlockedio
 
 test-srcs = tst-unbputc tst-printf
 
diff --git a/stdio-common/tst-unlockedio.c b/stdio-common/tst-unlockedio.c
new file mode 100644 (file)
index 0000000..aae2998
--- /dev/null
@@ -0,0 +1,157 @@
+/* Test for some *_unlocked stdio interfaces.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+int fd;
+static void do_prepare (void);
+static int do_test (void);
+#define PREPARE(argc, argv) do_prepare ()
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
+
+static int
+do_test (void)
+{
+  const char blah[] = "BLAH";
+  char buf[strlen (blah) + 1];
+  FILE *fp, *f;
+  const char *cp;
+  char *wp;
+
+  if ((fp = fdopen (fd, "w+")) == NULL)
+    exit (1);
+
+  flockfile (fp);
+
+  f = fp;
+  cp = blah;
+  if (ftello (fp) != 0
+      || fwrite_unlocked (blah, blah - blah, strlen (blah), f++) != 0
+      || f != fp + 1
+      || fwrite_unlocked ("", 5.0, 0, --f) != 0
+      || f != fp
+      || fwrite_unlocked (cp++, 16, 0.25, fp) != 0
+      || cp != blah + 1
+      || fwrite_unlocked (--cp, 0.25, 16, fp) != 0
+      || cp != blah
+      || fwrite_unlocked (blah, 0, -0.0, fp) != 0
+      || ftello (fp) != 0)
+    {
+      puts ("One of fwrite_unlocked tests failed");
+      exit (1);
+    }
+
+  if (fwrite_unlocked (blah, 1, strlen (blah) - 2, fp) != strlen (blah) - 2)
+    {
+      puts ("Could not write string into file");
+      exit (1);
+    }
+
+  if (putc_unlocked ('A' + 0x1000000, fp) != 'A')
+    {
+      puts ("putc_unlocked failed");
+      exit (1);
+    }
+
+  f = fp;
+  cp = blah + strlen (blah) - 1;
+  if (putc_unlocked (*cp++, f++) != 'H'
+      || f != fp + 1
+      || cp != strchr (blah, '\0'))
+    {
+      puts ("fputc_unlocked failed");
+      exit (1);
+    }
+
+  if (ftello (fp) != (off_t) strlen (blah))
+    {
+      printf ("Failed to write %zd bytes to temporary file", strlen (blah));
+      exit (1);
+    }
+
+  rewind (fp);
+
+  f = fp;
+  wp = buf;
+  memset (buf, ' ', sizeof (buf));
+  if (ftello (fp) != 0
+      || fread_unlocked (buf, buf - buf, strlen (blah), f++) != 0
+      || f != fp + 1
+      || fread_unlocked (buf, 5.0, 0, --f) != 0
+      || f != fp
+      || fread_unlocked (wp++, 16, 0.25, fp) != 0
+      || wp != buf + 1
+      || fread_unlocked (--wp, 0.25, 16, fp) != 0
+      || wp != buf
+      || fread_unlocked (buf, 0, -0.0, fp) != 0
+      || ftello (fp) != 0
+      || memcmp (buf, "     ", sizeof (buf)) != 0)
+    {
+      puts ("One of fread_unlocked tests failed");
+      exit (1);
+    }
+
+  if (fread_unlocked (buf, 1, strlen (blah) - 2, fp) != strlen (blah) - 2)
+    {
+      puts ("Could not read string from file");
+      exit (1);
+    }
+
+  if (getc_unlocked (fp) != 'A')
+    {
+      puts ("getc_unlocked failed");
+      exit (1);
+    }
+
+  f = fp;
+  if (fgetc_unlocked (f++) != 'H'
+      || f != fp + 1
+      || fgetc_unlocked (--f) != EOF
+      || f != fp)
+    {
+      puts ("fgetc_unlocked failed");
+      exit (1);
+    }
+
+  if (ftello (fp) != (off_t) strlen (blah))
+    {
+      printf ("Failed to read %zd bytes from temporary file", strlen (blah));
+      exit (1);
+    }
+
+  funlockfile (fp);
+  fclose (fp);
+
+  return 0;
+}
+
+static void
+do_prepare (void)
+{
+  fd = create_temp_file ("tst-unlockedio.", NULL);
+  if (fd == -1)
+    {
+      printf ("cannot create temporary file: %m\n");
+      exit (1);
+    }
+}