From: Eric Blake Date: Fri, 27 Apr 2007 17:14:39 +0000 (+0000) Subject: Fix closein for mingw. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5c323b505d3a819032d1d2ef825070faefc247e6;p=pspp Fix closein for mingw. * modules/closein-tests: Add tests for closein. * tests/test-closein.c: New file. * tests/test-closein.sh: Likewise. * lib/unistd_.h [!SEEK_CUR]: Mingw also needs stdlib.h for _exit. * lib/closein.c (close_stdin): Don't fflush non-seekable streams. --- diff --git a/ChangeLog b/ChangeLog index 6b3e691102..7d8e5c3f2e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2007-04-27 Eric Blake + + Fix closein for mingw. + * modules/closein-tests: Add tests for closein. + * tests/test-closein.c: New file. + * tests/test-closein.sh: Likewise. + * lib/unistd_.h [!SEEK_CUR]: Mingw also needs stdlib.h for _exit. + * lib/closein.c (close_stdin): Don't fflush non-seekable streams. + 2007-04-27 Bruno Haible * lib/inttypes_.h [_DECC]: Don't use #include_next if the compiler diff --git a/lib/closein.c b/lib/closein.c index 5153484262..4450d5bd8d 100644 --- a/lib/closein.c +++ b/lib/closein.c @@ -19,7 +19,6 @@ #include #include "closein.h" -#include "closeout.h" #include #include @@ -30,6 +29,7 @@ #define _(msgid) gettext (msgid) #include "close-stream.h" +#include "closeout.h" #include "error.h" #include "exitfail.h" #include "quotearg.h" @@ -79,18 +79,23 @@ void close_stdin (void) { bool fail = false; - if (fflush (stdin) != 0 || close_stream (stdin) != 0) + + /* Only attempt flush if stdin is seekable, as fflush is entitled to + fail on non-seekable streams. */ + if (fseeko (stdin, 0, SEEK_CUR) == 0 && fflush (stdin) != 0) + fail = true; + if (close_stream (stdin) != 0) + fail = true; + if (fail) { + /* Report failure, but defer exit until after closing stdout, + since the failure report should still be flushed. */ char const *close_error = _("error closing file"); if (file_name) error (0, errno, "%s: %s", quotearg_colon (file_name), close_error); else error (0, errno, "%s", close_error); - - /* Defer failure until after closing stdout, since the output - can still usefully be flushed. */ - fail = true; } close_stdout (); diff --git a/lib/unistd_.h b/lib/unistd_.h index 344b5a3888..4febc90b46 100644 --- a/lib/unistd_.h +++ b/lib/unistd_.h @@ -27,6 +27,8 @@ # include #endif +/* mingw fails to declare _exit in . */ +#include /* The definition of GL_LINK_WARNING is copied here. */ diff --git a/modules/closein-tests b/modules/closein-tests new file mode 100644 index 0000000000..efadac5f10 --- /dev/null +++ b/modules/closein-tests @@ -0,0 +1,13 @@ +Files: +tests/test-closein.sh +tests/test-closein.c + +Depends-on: +binary-io + +configure.ac: + +Makefile.am: +TESTS += test-closein.sh +TESTS_ENVIRONMENT += EXEEXT='@EXEEXT@' +check_PROGRAMS += test-closein diff --git a/tests/test-closein.c b/tests/test-closein.c new file mode 100644 index 0000000000..90214e8e25 --- /dev/null +++ b/tests/test-closein.c @@ -0,0 +1,49 @@ +/* Test of closein module. + Copyright (C) 2007 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 2, 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 + +#include "closein.h" + +#include +#include + +#include "binary-io.h" + +char *program_name; + +/* With no arguments, do nothing. With arguments, attempt to consume + first 6 bytes of stdin. In either case, let exit() take care of + closing std streams and changing exit status if ferror(stdin). */ +int +main (int argc, char **argv) +{ + char buf[7]; + int i = -1; + atexit(close_stdin); + program_name = argv[0]; + + /* close_stdin currently relies on ftell, but mingw ftell is + unreliable on text mode input. */ + SET_BINARY (0); + + if (argc > 1) + i = fread (buf, 1, 6, stdin); + return 0; +} diff --git a/tests/test-closein.sh b/tests/test-closein.sh new file mode 100755 index 0000000000..8623ead897 --- /dev/null +++ b/tests/test-closein.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +tmpfiles= +trap 'rm -fr $tmpfiles' 1 2 3 15 + +p=t-closein- +tmpfiles="${p}in.tmp ${p}xout.tmp ${p}out1.tmp ${p}out2.tmp" + +echo Hello world > ${p}in.tmp +echo world > ${p}xout.tmp + +# Test with seekable stdin; followon process must see remaining data +(./test-closein${EXEEXT}; cat) < ${p}in.tmp > ${p}out1.tmp || exit 1 +cmp ${p}out1.tmp ${p}in.tmp || exit 1 + +(./test-closein${EXEEXT} consume; cat) < ${p}in.tmp > ${p}out2.tmp || exit 1 +cmp ${p}out2.tmp ${p}xout.tmp || exit 1 + +# Test for lack of error on pipe +cat ${p}in.tmp | ./test-closein${EXEEXT} || exit 1 + +cat ${p}in.tmp | ./test-closein${EXEEXT} consume || exit 1 + +# Test for lack of error when nothing is read +./test-closein${EXEEXT} /dev/null && exit 1 + +# Cleanup +rm -fr $tmpfiles + +exit 0