Re: fseeko use

Eric Blake <[email protected]>
Newsgroups gmane.comp.gnu.m4.patches
Message-ID <[email protected]>
Eric Blake <ebb9 <at> byu.net> writes:

> I'm installing this to both branch and head, now that gnulib guarantees
> fseeko will work (beforehand, it was possible for fseek to fail
> unnecessarily at 2gb on platforms with larger off_t).

And now that gnulib supports fflush on mingw, I'm installing this to branch and 
head.

2007-05-24  Eric Blake  <[email protected]>

	Support POSIX flush semantics on all platforms.
	* m4/gnulib-cache.m4: Remove closout, and augment with
	'gnulib-tool --import closein fflush'.
	* src/m4.h (includes): Use closein, not closeout.
	* src/m4.c (main): Ensure stdin is flushed when not all input is
	consumed.
	(process_file): No return needed.
	* src/debug.c (debug_flush_files): Rely on gnulib module, rather
	than excluding mingw.
	* NEWS: Document this change.

Index: NEWS
===================================================================
RCS file: /sources/m4/m4/NEWS,v
retrieving revision 1.1.1.1.2.99
diff -u -p -r1.1.1.1.2.99 NEWS
--- NEWS	25 Apr 2007 14:04:13 -0000	1.1.1.1.2.99
+++ NEWS	24 May 2007 17:18:56 -0000
@@ -6,6 +6,9 @@ Version 1.4.10 - ?? ??? 2007, by ????  (
 
 * Fix regression introduced in 1.4.9 in the `eval' builtin when performing
   division.
+* Work around a number of corner-case POSIX compliance bugs in various
+  broken stdio libraries.  In particular, the `syscmd' builtin behaves
+  more predictably when stdin is seekable.
 
 Version 1.4.9 - 23 Mar 2007, by Eric Blake  (CVS version 1.4.8c)
 
Index: m4/gnulib-cache.m4
===================================================================
RCS file: /sources/m4/m4/m4/Attic/gnulib-cache.m4,v
retrieving revision 1.1.2.24
diff -u -p -r1.1.2.24 gnulib-cache.m4
--- m4/gnulib-cache.m4	24 May 2007 11:58:20 -0000	1.1.2.24
+++ m4/gnulib-cache.m4	24 May 2007 17:18:56 -0000
@@ -15,11 +15,11 @@
 
 
 # Specification in the form of a command-line invocation:
-#   gnulib-tool --import --dir=. --lib=libm4 --source-base=lib --m4-base=m4 --
doc-base=doc --aux-dir=. --no-libtool --macro-prefix=M4 avltree-oset binary-io 
clean-temp cloexec close-stream closeout config-h error fdl fopen-safer free 
fseeko gendocs getopt gnupload mkstemp obstack regex stdbool stdint stdlib-
safer strtol unlocked-io verror version-etc-fsf xalloc xvasprintf
+#   gnulib-tool --import --dir=. --lib=libm4 --source-base=lib --m4-base=m4 --
doc-base=doc --aux-dir=. --no-libtool --macro-prefix=M4 avltree-oset binary-io 
clean-temp cloexec close-stream closein config-h error fdl fflush fopen-safer 
free fseeko gendocs getopt gnupload mkstemp obstack regex stdbool stdint stdlib-
safer strtol unlocked-io verror version-etc-fsf xalloc xvasprintf
 
 # Specification in the form of a few gnulib-tool.m4 macro invocations:
 gl_LOCAL_DIR([])
-gl_MODULES([avltree-oset binary-io clean-temp cloexec close-stream closeout 
config-h error fdl fopen-safer free fseeko gendocs getopt gnupload mkstemp 
obstack regex stdbool stdint stdlib-safer strtol unlocked-io verror version-etc-
fsf xalloc xvasprintf])
+gl_MODULES([avltree-oset binary-io clean-temp cloexec close-stream closein 
config-h error fdl fflush fopen-safer free fseeko gendocs getopt gnupload 
mkstemp obstack regex stdbool stdint stdlib-safer strtol unlocked-io verror 
version-etc-fsf xalloc xvasprintf])
 gl_AVOID([])
 gl_SOURCE_BASE([lib])
 gl_M4_BASE([m4])
Index: src/debug.c
===================================================================
RCS file: /sources/m4/m4/src/Attic/debug.c,v
retrieving revision 1.1.1.1.2.12
diff -u -p -r1.1.1.1.2.12 debug.c
--- src/debug.c	24 May 2007 11:58:20 -0000	1.1.1.1.2.12
+++ src/debug.c	24 May 2007 17:18:56 -0000
@@ -180,22 +180,19 @@ debug_flush_files (void)
      next character on exit (but places no restrictions on the file
      pointer location on a non-seekable file).  It also requires that
      fflush() followed by fseeko() on an input file set the underlying
-     file pointer.  However, fflush() on a non-seekable file can lose
-     buffered data, which we might otherwise want to process after
-     syscmd.  Hence, we must check whether stdin is seekable.  We must
-     also be tolerant of operating with stdin closed, so we don't
-     report any failures in this attempt.  The stdio-safer module and
-     friends are essential, so that if stdin was closed, this lseek is
-     not on some other file that we have since opened.  Mingw has bugs
-     when using fseek on text files, so we only strive for POSIX
-     behavior when we detect a UNIX environment, until gnulib is improved.  */
-#if UNIX
+     file pointer, and gnulib guarantees these semantics.  However,
+     fflush() on a non-seekable file can lose buffered data, which we
+     might otherwise want to process after syscmd.  Hence, we must
+     check whether stdin is seekable.  We must also be tolerant of
+     operating with stdin closed, so we don't report any failures in
+     this attempt.  The stdio-safer module and friends are essential,
+     so that if stdin was closed, this lseek is not on some other file
+     that we have since opened.  */
   if (lseek (STDIN_FILENO, 0, SEEK_CUR) >= 0
       && fflush (stdin) == 0)
     {
       fseeko (stdin, 0, SEEK_CUR);
     }
-#endif /* UNIX */
 }
 
 /*-------------------------------------------------------------------------.
Index: src/m4.c
===================================================================
RCS file: /sources/m4/m4/src/Attic/m4.c,v
retrieving revision 1.1.1.1.2.46
diff -u -p -r1.1.1.1.2.46 m4.c
--- src/m4.c	28 Feb 2007 13:48:19 -0000	1.1.1.1.2.46
+++ src/m4.c	24 May 2007 17:18:56 -0000
@@ -278,10 +278,9 @@ static const struct option long_options[
 
 /* Process a command line file NAME, and return true only if it was
    stdin.  */
-static bool
+static void
 process_file (const char *name)
 {
-  bool result = false;
   if (strcmp (name, "-") == 0)
     {
       /* If stdin is a terminal, we want to allow 'm4 - file -'
@@ -289,7 +288,6 @@ process_file (const char *name)
 	 there is no point closing stdin before wrapped text, to
 	 minimize bugs in syscmd called from wrapped text.  */
       push_file (stdin, "stdin", false);
-      result = true;
     }
   else
     {
@@ -301,13 +299,12 @@ process_file (const char *name)
 	  /* Set the status to EXIT_FAILURE, even though we
 	     continue to process files after a missing file.  */
 	  retcode = EXIT_FAILURE;
-	  return false;
+	  return;
 	}
       push_file (fp, full_name, true);
       free (full_name);
     }
   expand_input ();
-  return result;
 }
 
 /* POSIX requires only -D, -U, and -s; and says that the first two
@@ -330,7 +327,6 @@ main (int argc, char *const *argv, char 
   int optchar;			/* option character */
 
   macro_definition *defines;
-  bool read_stdin = false;
   bool interactive = false;
   bool seen_file = false;
   const char *debugfile = NULL;
@@ -340,7 +336,7 @@ main (int argc, char *const *argv, char 
 
   program_name = argv[0];
   retcode = EXIT_SUCCESS;
-  atexit (close_stdout);
+  atexit (close_stdin);
 
   include_init ();
   debug_init ();
@@ -554,8 +550,7 @@ main (int argc, char *const *argv, char 
 
 	case '\1':
 	  seen_file = true;
-	  if (process_file (defines->arg))
-	    read_stdin = true;
+          process_file (defines->arg);
 	  break;
 
 	default:
@@ -572,10 +567,10 @@ main (int argc, char *const *argv, char 
      and the input read.  Wrapup text is handled separately later.  */
 
   if (optind == argc && !seen_file)
-    read_stdin = process_file ("-");
+    process_file ("-");
   else
     for (; optind < argc; optind++)
-      read_stdin |= process_file (argv[optind]);
+      process_file (argv[optind]);
 
   /* Now handle wrapup text.  */
 
@@ -583,14 +578,9 @@ main (int argc, char *const *argv, char 
     expand_input ();
 
   /* Change debug stream back to stderr, to force flushing the debug
-     stream and detect any errors it might have encountered.  Close
-     stdin if we read from it, to detect any errors.  */
+     stream and detect any errors it might have encountered.  The
+     three standard streams are closed by close_stdin.  */
   debug_set_output (NULL);
-  if (read_stdin && close_stream (stdin) == EOF)
-    {
-      M4ERROR ((warning_status, errno, "error reading stdin"));
-      retcode = EXIT_FAILURE;
-    }
 
   if (frozen_file_to_write)
     produce_frozen_state (frozen_file_to_write);
Index: src/m4.h
===================================================================
RCS file: /sources/m4/m4/src/m4.h,v
retrieving revision 1.1.1.1.2.41
diff -u -p -r1.1.1.1.2.41 m4.h
--- src/m4.h	28 Feb 2007 13:48:19 -0000	1.1.1.1.2.41
+++ src/m4.h	24 May 2007 17:18:56 -0000
@@ -36,7 +36,7 @@
 #include "clean-temp.h"
 #include "cloexec.h"
 #include "close-stream.h"
-#include "closeout.h"
+#include "closein.h"
 #include "error.h"
 #include "exitfail.h"
 #include "obstack.h"
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.