* [PATCH] Fix <bits/stdio.h> plus testcase
@ 2004-08-10 12:34 Jakub Jelinek
2004-08-10 18:13 ` Roland McGrath
0 siblings, 1 reply; 2+ messages in thread
From: Jakub Jelinek @ 2004-08-10 12:34 UTC (permalink / raw)
To: Ulrich Drepper, Roland McGrath; +Cc: Glibc hackers
Hi!
BZ #316 shows a bug in the latest libio/bits/stdio.h change.
I have added a testcase too, which revealed e.g. that
fwrite_unlocked (buf, 0, 4, f) was returning 4 if -O2 and properly 0
if -O0.
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.
--- libc/libio/bits/stdio.h.jj 2004-08-10 13:11:36.167221075 +0200
+++ libc/libio/bits/stdio.h 2004-08-10 14:17:31.051569361 +0200
@@ -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
--- libc/stdio-common/Makefile.jj 2004-08-04 14:16:16.000000000 +0200
+++ libc/stdio-common/Makefile 2004-08-10 14:22:16.054684445 +0200
@@ -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 t
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
--- libc/stdio-common/tst-unlockedio.c.jj 2004-08-10 13:17:15.362819375 +0200
+++ libc/stdio-common/tst-unlockedio.c 2004-08-10 14:16:51.585477315 +0200
@@ -0,0 +1,156 @@
+/* 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);
+ }
+}
Jakub
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] Fix <bits/stdio.h> plus testcase
2004-08-10 12:34 [PATCH] Fix <bits/stdio.h> plus testcase Jakub Jelinek
@ 2004-08-10 18:13 ` Roland McGrath
0 siblings, 0 replies; 2+ messages in thread
From: Roland McGrath @ 2004-08-10 18:13 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: Ulrich Drepper, Glibc hackers
> 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.
Applied.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2004-08-10 18:13 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-08-10 12:34 [PATCH] Fix <bits/stdio.h> plus testcase Jakub Jelinek
2004-08-10 18:13 ` Roland McGrath
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).