bug-gnu-utils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

gawk 3.1 rewinds stdin before reading it as a program


From: Paul Eggert
Subject: gawk 3.1 rewinds stdin before reading it as a program
Date: Mon, 13 Aug 2001 10:19:35 -0700 (PDT)

gawk 3.1 rewinds standard input before reading it as a program.  This
causes it to behave incorrectly in some cases.  Here is an example,
running on Solaris 8.  Solaris 8 'awk' works correctly, but gawk
mishandles this example.

        $ echo foo >foo
        $ echo '({print}' >bar
        $ (dd bs=1 count=1 >/dev/null; awk -f - foo) <bar
        1+0 records in
        1+0 records out
        foo
        $ (dd bs=1 count=1 >/dev/null; gawk -f - foo) <bar
        1+0 records in
        1+0 records out
        gawk: -:1: ({print}
        gawk: -:1:  ^ parse error

Here is a patch.

2001-08-13  Paul Eggert  <address@hidden>

        This patch fixes a bug that causes gawk to rewind standard
        input incorrectly.  It also removes all instances of lseek,
        fseek, and off_t from the gawk source proper, which should
        make gawk a bit more portable.

        * posix/gawkmisc.c (optimal_bufsize):
        Don't use lseek on the input, because that might change
        its state.  Instead, just check whether it is a regular file.
        This obviates the need to invoke isatty.
        (Also, fix a spelling error in the first line of the source.)
        * pc/gawkmisc.pc, unsupported/atari/gawkmisc.atr: Likewise.

        * awk.h (S_ISREG): Move this macro here ...
        * io.c (S_ISREG): from here.

        * protos.h (lseek, fseek): Remove prototypes; no longer used.

===================================================================
RCS file: posix/gawkmisc.c,v
retrieving revision 3.1
retrieving revision 3.1.0.1
diff -pu -r3.1 -r3.1.0.1
--- posix/gawkmisc.c    2001/01/28 13:49:24     3.1
+++ posix/gawkmisc.c    2001/08/13 17:06:44     3.1.0.1
@@ -1,4 +1,4 @@
-/* gawkmisc.c --- miscellanious gawk routines that are OS specific.
+/* gawkmisc.c --- miscellaneous gawk routines that are OS specific.
  
    Copyright (C) 1986, 1988, 1989, 1991 - 98, 2001 the Free Software 
Foundation, Inc.
 
@@ -82,13 +82,10 @@ struct stat *stb;
 #define        DEFBLKSIZE      BUFSIZ
 #endif
 
-       if (isatty(fd))
-               return BUFSIZ;
        if (fstat(fd, stb) == -1)
                fatal("can't stat fd %d (%s)", fd, strerror(errno));
-       if (lseek(fd, (off_t)0, 0) == -1)       /* not a regular file */
-               return DEFBLKSIZE;
-       if (stb->st_size > 0 && stb->st_size < DEFBLKSIZE) /* small file */
+       if (S_ISREG(stb->st_mode)
+           && 0 < stb->st_size && stb->st_size < DEFBLKSIZE) /* small file */
                return stb->st_size;
        return DEFBLKSIZE;
 }
===================================================================
RCS file: pc/gawkmisc.pc,v
retrieving revision 3.1
retrieving revision 3.1.0.1
diff -pu -r3.1 -r3.1.0.1
--- pc/gawkmisc.pc      2001/01/28 13:49:25     3.1
+++ pc/gawkmisc.pc      2001/08/13 17:06:44     3.1.0.1
@@ -1,5 +1,5 @@
 /*
- * gawkmisc.c --- miscellanious gawk routines that are OS specific.
+ * gawkmisc.c --- miscellaneous gawk routines that are OS specific.
  */
 
 /* 
@@ -101,13 +101,10 @@ struct stat *stb;
         */
 #define        DEFBLKSIZE      BUFSIZ
 
-       if (isatty(fd))
-               return BUFSIZ;
        if (fstat(fd, stb) == -1)
                fatal("can't stat fd %d (%s)", fd, strerror(errno));
-       if (lseek(fd, (off_t)0, 0) == -1)       /* not a regular file */
-               return DEFBLKSIZE;
-       if (stb->st_size > 0 && stb->st_size < DEFBLKSIZE) /* small file */
+       if (S_ISREG(stb->st_mode)
+           && 0 < stb->st_size && stb->st_size < DEFBLKSIZE) /* small file */
                return stb->st_size;
        return DEFBLKSIZE;
 }
===================================================================
RCS file: unsupported/atari/gawkmisc.atr,v
retrieving revision 3.1
retrieving revision 3.1.0.1
diff -pu -r3.1 -r3.1.0.1
--- unsupported/atari/gawkmisc.atr      2001/01/28 13:49:25     3.1
+++ unsupported/atari/gawkmisc.atr      2001/08/13 17:06:44     3.1.0.1
@@ -1,5 +1,5 @@
 /*
- * gawkmisc.atr --- miscellanious gawk routines that are OS specific.
+ * gawkmisc.atr --- miscellaneous gawk routines that are OS specific.
  */
 
 /* 
@@ -94,13 +94,12 @@ struct stat *stb;
         * On ST redirected stdin does not have a name attached
         * (this could be hard to do to) and fstat would fail
         */
-       if (fd == 0 || isatty(fd))
+       if (fd == 0)
                return BUFSIZ;
        if (fstat(fd, stb) == -1)
                fatal("can't stat fd %d (%s)", fd, strerror(errno));
-       if (lseek(fd, (off_t)0, 0) == -1)       /* not a regular file */
-               return DEFBLKSIZE;
-       if (stb->st_size > 0 && stb->st_size < DEFBLKSIZE) /* small file */
+       if (S_ISREG(stb->st_mode)
+           && 0 < stb->st_size && stb->st_size < DEFBLKSIZE) /* small file */
                return stb->st_size;
        return DEFBLKSIZE;
 }
===================================================================
RCS file: awk.h,v
retrieving revision 3.1
retrieving revision 3.1.0.1
diff -pu -r3.1 -r3.1.0.1
--- awk.h       2001/04/22 13:44:13     3.1
+++ awk.h       2001/08/13 17:06:44     3.1.0.1
@@ -139,6 +139,10 @@ extern int errno;
 #include <file.h>      /* avoid <fcntl.h> in io.c */
 #endif /* VMS */
 
+#if ! defined(S_ISREG) && defined(S_IFREG)
+#define        S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#endif
+
 #ifdef STDC_HEADERS
 #include <stdlib.h>
 #else  /* not STDC_HEADERS */
===================================================================
RCS file: io.c,v
retrieving revision 3.1
retrieving revision 3.1.0.1
diff -pu -r3.1 -r3.1.0.1
--- io.c        2001/04/24 11:35:35     3.1
+++ io.c        2001/08/13 17:06:44     3.1.0.1
@@ -57,10 +57,6 @@
 #endif /* HAVE_NETDB_H */
 #endif /* HAVE_SOCKETS */
 
-#if ! defined(S_ISREG) && defined(S_IFREG)
-#define        S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
-#endif
-
 #ifndef ENFILE
 #define ENFILE EMFILE
 #endif
===================================================================
RCS file: protos.h,v
retrieving revision 3.1
retrieving revision 3.1.0.1
diff -pu -r3.1 -r3.1.0.1
--- protos.h    2001/01/21 15:47:18     3.1
+++ protos.h    2001/08/13 17:06:44     3.1.0.1
@@ -101,8 +101,6 @@ extern double atof P((const char *));
 extern double strtod P((const char *, char **));
 extern int fstat P((int, struct stat *));
 extern int stat P((const char *, struct stat *));
-extern off_t lseek P((int, off_t, int));
-extern int fseek P((FILE *, long, int));
 extern int close P((int));
 extern int creat P((const char *, mode_t));
 extern int open P((const char *, int, ...));



reply via email to

[Prev in Thread] Current Thread [Next in Thread]