Author: jilles
Date: Fri May  3 15:28:31 2013
New Revision: 250214
URL: http://svnweb.freebsd.org/changeset/base/250214

Log:
  sh: Improve error handling in read builtin:
  
  * If read -t times out, return status as if interrupted by SIGALRM
    (formerly 1).
  * If a trapped signal interrupts read, return status 128+sig (formerly 1).
  * If [EINTR] occurs but there is no trap, retry the read (for example
    because of a SIGWINCH in interactive mode).
  * If a read error occurs, write an error message and return status 2.
  
  As before, a variable assignment error returns 2 and discards the remaining
  data read.

Added:
  head/tools/regression/bin/sh/builtins/read7.0   (contents, props changed)
  head/tools/regression/bin/sh/builtins/read8.0   (contents, props changed)
Modified:
  head/bin/sh/miscbltin.c
  head/bin/sh/sh.1

Modified: head/bin/sh/miscbltin.c
==============================================================================
--- head/bin/sh/miscbltin.c     Fri May  3 14:59:32 2013        (r250213)
+++ head/bin/sh/miscbltin.c     Fri May  3 15:28:31 2013        (r250214)
@@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$");
 #include "error.h"
 #include "mystring.h"
 #include "syntax.h"
+#include "trap.h"
 
 #undef eflag
 
@@ -102,6 +103,8 @@ readcmd(int argc __unused, char **argv _
        struct timeval tv;
        char *tvptr;
        fd_set ifds;
+       ssize_t nread;
+       int sig;
 
        rflag = 0;
        prompt = NULL;
@@ -156,8 +159,10 @@ readcmd(int argc __unused, char **argv _
                /*
                 * If there's nothing ready, return an error.
                 */
-               if (status <= 0)
-                       return(1);
+               if (status <= 0) {
+                       sig = pendingsig;
+                       return (128 + (sig != 0 ? sig : SIGALRM));
+               }
        }
 
        status = 0;
@@ -165,7 +170,19 @@ readcmd(int argc __unused, char **argv _
        backslash = 0;
        STARTSTACKSTR(p);
        for (;;) {
-               if (read(STDIN_FILENO, &c, 1) != 1) {
+               nread = read(STDIN_FILENO, &c, 1);
+               if (nread == -1) {
+                       if (errno == EINTR) {
+                               sig = pendingsig;
+                               if (sig == 0)
+                                       continue;
+                               status = 128 + sig;
+                               break;
+                       }
+                       warning("read error: %s", strerror(errno));
+                       status = 2;
+                       break;
+               } else if (nread != 1) {
                        status = 1;
                        break;
                }

Modified: head/bin/sh/sh.1
==============================================================================
--- head/bin/sh/sh.1    Fri May  3 14:59:32 2013        (r250213)
+++ head/bin/sh/sh.1    Fri May  3 15:28:31 2013        (r250214)
@@ -32,7 +32,7 @@
 .\"    from: @(#)sh.1  8.6 (Berkeley) 5/4/95
 .\" $FreeBSD$
 .\"
-.Dd April 21, 2013
+.Dd May 3, 2013
 .Dt SH 1
 .Os
 .Sh NAME
@@ -2372,7 +2372,9 @@ option is specified and the
 elapses before a complete line of input is supplied,
 the
 .Ic read
-command will return an exit status of 1 without assigning any values.
+command will return an exit status as if terminated by
+.Dv SIGALRM
+without assigning any values.
 The
 .Ar timeout
 value may optionally be followed by one of
@@ -2388,6 +2390,11 @@ is assumed.
 The
 .Fl e
 option exists only for backward compatibility with older scripts.
+.Pp
+The exit status is 0 on success, 1 on end of file,
+between 2 and 128 if an error occurs
+and greater than 128 if a trapped signal interrupts
+.Ic read .
 .It Ic readonly Oo Fl p Oc Op Ar name ...
 Each specified
 .Ar name

Added: head/tools/regression/bin/sh/builtins/read7.0
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/tools/regression/bin/sh/builtins/read7.0       Fri May  3 15:28:31 
2013        (r250214)
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+{ errmsg=`read x <&- 2>&1 >&3`; } 3>&1
+r=$?
+[ "$r" -ge 2 ] && [ "$r" -le 128 ] && [ -n "$errmsg" ]

Added: head/tools/regression/bin/sh/builtins/read8.0
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/tools/regression/bin/sh/builtins/read8.0       Fri May  3 15:28:31 
2013        (r250214)
@@ -0,0 +1,13 @@
+# $FreeBSD$
+
+T=`mktemp -d ${TMPDIR:-/tmp}/sh-test.XXXXXX`
+trap 'rm -rf $T' 0
+cd $T || exit 3
+mkfifo fifo1
+trapped=
+trap trapped=1 QUIT
+{ kill -QUIT $$; sleep 1; exit 4; } >fifo1 &
+read dummy <fifo1
+r=$?
+kill $!
+[ "$r" -gt 128 ] && [ -n "$trapped" ]
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to