From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10182 invoked by alias); 10 Aug 2004 12:34:30 -0000 Mailing-List: contact libc-hacker-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-hacker-owner@sources.redhat.com Received: (qmail 10164 invoked from network); 10 Aug 2004 12:34:28 -0000 Received: from unknown (HELO sunsite.ms.mff.cuni.cz) (195.113.15.26) by sourceware.org with SMTP; 10 Aug 2004 12:34:28 -0000 Received: from sunsite.ms.mff.cuni.cz (sunsite.mff.cuni.cz [127.0.0.1]) by sunsite.ms.mff.cuni.cz (8.12.8/8.12.8) with ESMTP id i7AAHY3j028413; Tue, 10 Aug 2004 12:17:34 +0200 Received: (from jakub@localhost) by sunsite.ms.mff.cuni.cz (8.12.8/8.12.8/Submit) id i7AAHXJv028411; Tue, 10 Aug 2004 12:17:33 +0200 Date: Tue, 10 Aug 2004 12:34:00 -0000 From: Jakub Jelinek To: Ulrich Drepper , Roland McGrath Cc: Glibc hackers Subject: [PATCH] Fix plus testcase Message-ID: <20040810101733.GR30497@sunsite.ms.mff.cuni.cz> Reply-To: Jakub Jelinek Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.1i X-SW-Source: 2004-08/txt/msg00026.txt.bz2 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 * 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 , 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 +#include +#include + +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