1
0
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:
Eric Blake
2011-05-02 13:38:23 -06:00
parent 001e7d63df
commit 1fc3525d1f
4 changed files with 109 additions and 0 deletions

View File

@@ -1,5 +1,10 @@
2011-05-02 Eric Blake <eblake@redhat.com> 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 fclose: reduced dependencies
* modules/fclose (Depends-on): Switch from fflush/fseeko to * modules/fclose (Depends-on): Switch from fflush/fseeko to
simpler lseek. simpler lseek.

View File

@@ -17,6 +17,10 @@ followed by @code{fdopen} do not return streams that can be closed by
Portability problems not fixed by Gnulib: Portability problems not fixed by Gnulib:
@itemize @itemize
@item @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} On Windows platforms (excluding Cygwin), this function does not set @code{errno}
upon failure. upon failure.
@end itemize @end itemize

10
modules/fclose-tests Normal file
View 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
View 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;
}