mirror of
https://git.savannah.gnu.org/git/gnulib.git
synced 2025-08-17 12:41:05 +03:00
fclose: add some tests
POSIX requires that fclose() on seekable input streams rewind back to the next byte not actually given to the application. Glibc fails this test. See: http://sourceware.org/bugzilla/show_bug.cgi?id=3746 http://sourceware.org/bugzilla/show_bug.cgi?id=12724 Likewise for FreeBSD. Cygwin 1.7.9 and Solaris 10 pass, however. * modules/fclose-tests: New test module. * tests/test-fclose.c: New file. Signed-off-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
@@ -1,5 +1,10 @@
|
||||
2011-05-02 Eric Blake <eblake@redhat.com>
|
||||
|
||||
fclose: add some tests
|
||||
* modules/fclose-tests: New test module.
|
||||
* tests/test-fclose.c: New file.
|
||||
* doc/posix-functions/fclose.texi (fclose): Document the bug.
|
||||
|
||||
fclose: reduced dependencies
|
||||
* modules/fclose (Depends-on): Switch from fflush/fseeko to
|
||||
simpler lseek.
|
||||
|
@@ -17,6 +17,10 @@ followed by @code{fdopen} do not return streams that can be closed by
|
||||
Portability problems not fixed by Gnulib:
|
||||
@itemize
|
||||
@item
|
||||
On some platforms, this function fails to set the file position of a
|
||||
seekable input stream to the byte after the last one actually read:
|
||||
glibc 2.13, FreeBSD.
|
||||
@item
|
||||
On Windows platforms (excluding Cygwin), this function does not set @code{errno}
|
||||
upon failure.
|
||||
@end itemize
|
||||
|
10
modules/fclose-tests
Normal file
10
modules/fclose-tests
Normal file
@@ -0,0 +1,10 @@
|
||||
Files:
|
||||
tests/test-fclose.c
|
||||
|
||||
Depends-on:
|
||||
|
||||
configure.ac:
|
||||
|
||||
Makefile.am:
|
||||
TESTS += test-fclose
|
||||
check_PROGRAMS += test-fclose
|
90
tests/test-fclose.c
Normal file
90
tests/test-fclose.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/* Test of fclose module.
|
||||
Copyright (C) 2011 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
|
||||
|
||||
/* Written by Eric Blake. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "signature.h"
|
||||
SIGNATURE_CHECK (fclose, int, (FILE *));
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "macros.h"
|
||||
|
||||
#define BASE "test-fclose.t"
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
const char buf[] = "hello world";
|
||||
int fd;
|
||||
int fd2;
|
||||
FILE *f;
|
||||
|
||||
/* Prepare a seekable file. */
|
||||
fd = open (BASE, O_RDWR | O_CREAT | O_TRUNC, 0600);
|
||||
ASSERT (0 <= fd);
|
||||
ASSERT (write (fd, buf, sizeof buf) == sizeof buf);
|
||||
ASSERT (lseek (fd, 1, SEEK_SET) == 1);
|
||||
|
||||
/* Create an output stream visiting the file; when it is closed, all
|
||||
other file descriptors visiting the file must see the new file
|
||||
position. */
|
||||
fd2 = dup (fd);
|
||||
ASSERT (0 <= fd2);
|
||||
f = fdopen (fd2, "w");
|
||||
ASSERT (f);
|
||||
ASSERT (fputc (buf[1], f) == buf[1]);
|
||||
ASSERT (fclose (f) == 0);
|
||||
errno = 0;
|
||||
ASSERT (lseek (fd2, 0, SEEK_CUR) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
ASSERT (lseek (fd, 0, SEEK_CUR) == 2);
|
||||
|
||||
/* Likewise for an input stream. */
|
||||
fd2 = dup (fd);
|
||||
ASSERT (0 <= fd2);
|
||||
f = fdopen (fd2, "r");
|
||||
ASSERT (f);
|
||||
ASSERT (fgetc (f) == buf[2]);
|
||||
ASSERT (fclose (f) == 0);
|
||||
errno = 0;
|
||||
ASSERT (lseek (fd2, 0, SEEK_CUR) == -1);
|
||||
ASSERT (errno == EBADF);
|
||||
ASSERT (lseek (fd, 0, SEEK_CUR) == 3);
|
||||
|
||||
/* Test that fclose() sets errno if someone else closes the stream
|
||||
fd behind the back of stdio. */
|
||||
f = fdopen (fd, "w+");
|
||||
ASSERT (f);
|
||||
ASSERT (close (fd) == 0);
|
||||
errno = 0;
|
||||
ASSERT (fclose (f) == EOF);
|
||||
ASSERT (errno == EBADF);
|
||||
|
||||
/* Clean up. */
|
||||
ASSERT (remove (BASE) == 0);
|
||||
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user