-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 According to Bruno Haible on 5/24/2007 6:12 PM:
Hi Bruno, >> * tests/test-lseek.c: New file. > > It would be better if it would also test errno. Done like so (and fixing a bug it uncovered in the meantime): 2007-05-28 Eric Blake <[EMAIL PROTECTED]> * lib/lseek.c (rpl_lseek): Detect EBADF on mingw. * lib/unistd_.h (lseek): Scale back link warning message. * tests/test-lseek.c: Beef up test. * tests/test-lseek.sh: Exercise more facets of lseek. Reported by Bruno Haible. - -- Don't work too hard, make some time for fun as well! Eric Blake [EMAIL PROTECTED] -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.5 (Cygwin) Comment: Public key at home.comcast.net/~ericblake/eblake.gpg Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFGWs4/84KuGfSFAYARAlk6AJ94MJFUZEZjAmKvGoZ2BknUhujCAwCgjlGT SvWD/p3FB8ZrjtcMEVWCNi4= =XOCj -----END PGP SIGNATURE-----
Index: lib/lseek.c =================================================================== RCS file: /sources/gnulib/gnulib/lib/lseek.c,v retrieving revision 1.1 diff -u -p -r1.1 lseek.c --- lib/lseek.c 24 May 2007 16:59:20 -0000 1.1 +++ lib/lseek.c 28 May 2007 12:32:22 -0000 @@ -31,7 +31,13 @@ off_t rpl_lseek (int fd, off_t offset, int whence) { /* mingw lseek mistakenly succeeds on pipes, sockets, and terminals. */ - if (GetFileType ((HANDLE) _get_osfhandle (fd)) != FILE_TYPE_DISK) + HANDLE h = (HANDLE) _get_osfhandle (fd); + if (h == INVALID_HANDLE_VALUE) + { + errno = EBADF; + return -1; + } + if (GetFileType (h) != FILE_TYPE_DISK) { errno = ESPIPE; return -1; Index: lib/unistd_.h =================================================================== RCS file: /sources/gnulib/gnulib/lib/unistd_.h,v retrieving revision 1.9 diff -u -p -r1.9 unistd_.h --- lib/unistd_.h 24 May 2007 16:59:21 -0000 1.9 +++ lib/unistd_.h 28 May 2007 12:32:22 -0000 @@ -188,9 +188,8 @@ extern int getlogin_r (char *name, size_ #elif defined GNULIB_POSIXCHECK # undef lseek # define lseek(f,o,w) \ - (GL_LINK_WARNING ("lseek does not fail with ESPIPE on non-seekable " \ - "files on some systems - " \ - "use gnulib module lseek for portability"), \ + (GL_LINK_WARNING ("lseek does not fail with ESPIPE on pipes on some " \ + "systems - use gnulib module lseek for portability"), \ lseek (f, o, w)) #endif Index: tests/test-lseek.c =================================================================== RCS file: /sources/gnulib/gnulib/tests/test-lseek.c,v retrieving revision 1.1 diff -u -p -r1.1 test-lseek.c --- tests/test-lseek.c 24 May 2007 16:59:22 -0000 1.1 +++ tests/test-lseek.c 28 May 2007 12:32:22 -0000 @@ -19,11 +19,67 @@ #include <config.h> +#include <errno.h> +#include <stdio.h> #include <unistd.h> +#define ASSERT(expr) \ + do \ + { \ + if (!(expr)) \ + { \ + fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \ + abort (); \ + } \ + } \ + while (0) + +/* ARGC must be 1; *ARGV[1] is '0' if stdin and stdout are files, '1' + if they are pipes, and '2' if they are closed. Check for proper + semantics of lseek. */ int -main () +main (int argc, char **argv) { - /* Exit with success only if stdin is seekable. */ - return lseek (0, (off_t)0, SEEK_CUR) < 0; + switch (*argv[1]) + { + case '0': /* regular files */ + ASSERT (lseek (0, (off_t)2, SEEK_SET) == 2); + ASSERT (lseek (0, (off_t)-4, SEEK_CUR) == -1); + ASSERT (errno == EINVAL); + errno = 0; + ASSERT (lseek (0, (off_t)0, SEEK_CUR) == 2); + ASSERT (lseek (0, (off_t)0, (SEEK_SET | SEEK_CUR | SEEK_END) + 1) == -1); + ASSERT (errno == EINVAL); + ASSERT (lseek (1, (off_t)2, SEEK_SET) == 2); + errno = 0; + ASSERT (lseek (1, (off_t)-4, SEEK_CUR) == -1); + ASSERT (errno == EINVAL); + errno = 0; + ASSERT (lseek (1, (off_t)0, SEEK_CUR) == 2); + ASSERT (lseek (1, (off_t)0, (SEEK_SET | SEEK_CUR | SEEK_END) + 1) == -1); + ASSERT (errno == EINVAL); + break; + + case '1': /* pipes */ + errno = 0; + ASSERT (lseek (0, (off_t)0, SEEK_CUR) == -1); + ASSERT (errno == ESPIPE); + errno = 0; + ASSERT (lseek (1, (off_t)0, SEEK_CUR) == -1); + ASSERT (errno == ESPIPE); + break; + + case '2': /* closed */ + errno = 0; + ASSERT (lseek (0, (off_t)0, SEEK_CUR) == -1); + ASSERT (errno == EBADF); + errno = 0; + ASSERT (lseek (1, (off_t)0, SEEK_CUR) == -1); + ASSERT (errno == EBADF); + break; + + default: + return 1; + } + return 0; } Index: tests/test-lseek.sh =================================================================== RCS file: /sources/gnulib/gnulib/tests/test-lseek.sh,v retrieving revision 1.1 diff -u -p -r1.1 test-lseek.sh --- tests/test-lseek.sh 24 May 2007 16:59:22 -0000 1.1 +++ tests/test-lseek.sh 28 May 2007 12:32:22 -0000 @@ -1,7 +1,17 @@ #!/bin/sh -# Succeed on seekable stdin -./test-lseek${EXEEXT} < "$srcdir/test-lseek.sh" || exit 1 -# Fail on pipe stdin -echo hi | ./test-lseek${EXEEXT} && exit 1 +tmpfiles= +trap 'rm -fr $tmpfiles' 1 2 3 15 + +tmpfiles=t-lseek.tmp +# seekable files +./test-lseek${EXEEXT} 0 < "$srcdir/test-lseek.sh" > t-lseek.tmp || exit 1 + +# pipes +echo hi | ./test-lseek${EXEEXT} 1 | cat || exit 1 + +# closed descriptors +./test-lseek${EXEEXT} 2 <&- >&- || exit 1 + +rm -rf $tmpfiles exit 0