Bash-4.0 patchlevel 38
[platform/upstream/bash.git] / lib / sh / zread.c
index 0d5320a..0fd1199 100644 (file)
@@ -1,20 +1,22 @@
-/* Copyright (C) 1999 Free Software Foundation, Inc.
+/* zread - read data from file descriptor into buffer with retries */
+
+/* Copyright (C) 1999-2002 Free Software Foundation, Inc.
 
    This file is part of GNU Bash, the Bourne Again SHell.
 
-   Bash 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.
+   Bash 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 3 of the License, or
+   (at your option) any later version.
+
+   Bash 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.
 
-   Bash 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 Bash; see the file COPYING.  If not, write to the Free Software
-   Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
+   You should have received a copy of the GNU General Public License
+   along with Bash.  If not, see <http://www.gnu.org/licenses/>.
+*/
 
 #include <config.h>
 
@@ -36,13 +38,13 @@ extern int errno;
 
 /* Read LEN bytes from FD into BUF.  Retry the read on EINTR.  Any other
    error causes the loop to break. */
-int
+ssize_t
 zread (fd, buf, len)
      int fd;
      char *buf;
      size_t len;
 {
-  int r;
+  ssize_t r;
 
   while ((r = read (fd, buf, len)) < 0 && errno == EINTR)
     ;
@@ -57,13 +59,14 @@ zread (fd, buf, len)
 #endif
 #define NUM_INTR 3
 
-int
-zread1 (fd, buf, len)
+ssize_t
+zreadretry (fd, buf, len)
      int fd;
      char *buf;
      size_t len;
 {
-  int r, nintr;
+  ssize_t r;
+  int nintr;
 
   for (nintr = 0; ; )
     {
@@ -72,7 +75,7 @@ zread1 (fd, buf, len)
        return r;
       if (r == -1 && errno == EINTR)
        {
-         if (++nintr > NUM_INTR)
+         if (++nintr >= NUM_INTR)
            return -1;
          continue;
        }
@@ -80,29 +83,68 @@ zread1 (fd, buf, len)
     }
 }
 
+/* Call read(2) and allow it to be interrupted.  Just a stub for now. */
+ssize_t
+zreadintr (fd, buf, len)
+     int fd;
+     char *buf;
+     size_t len;
+{
+  return (read (fd, buf, len));
+}
+
 /* Read one character from FD and return it in CP.  Return values are as
    in read(2).  This does some local buffering to avoid many one-character
    calls to read(2), like those the `read' builtin performs. */
 
-static unsigned char lbuf[128];
-static int lind, lused;
+static char lbuf[128];
+static size_t lind, lused;
 
-int
+ssize_t
 zreadc (fd, cp)
      int fd;
      char *cp;
 {
-  int r;
+  ssize_t nr;
+
+  if (lind == lused || lused == 0)
+    {
+      nr = zread (fd, lbuf, sizeof (lbuf));
+      lind = 0;
+      if (nr <= 0)
+       {
+         lused = 0;
+         return nr;
+       }
+      lused = nr;
+    }
+  if (cp)
+    *cp = lbuf[lind++];
+  return 1;
+}
+
+/* Don't mix calls to zreadc and zreadcintr in the same function, since they
+   use the same local buffer. */
+ssize_t
+zreadcintr (fd, cp)
+     int fd;
+     char *cp;
+{
+  ssize_t nr;
 
   if (lind == lused || lused == 0)
     {
-      lused = zread (fd, lbuf, sizeof (lbuf));
+      nr = zreadintr (fd, lbuf, sizeof (lbuf));
       lind = 0;
-      if (lused <= 0)
-       return (lused);
+      if (nr <= 0)
+       {
+         lused = 0;
+         return nr;
+       }
+      lused = nr;
     }
   if (cp)
-    *cp = (char)lbuf[lind++];
+    *cp = lbuf[lind++];
   return 1;
 }
 
@@ -118,10 +160,14 @@ void
 zsyncfd (fd)
      int fd;
 {
-  int off;
+  off_t off;
+  int r;
 
   off = lused - lind;
+  r = 0;
   if (off > 0)
-    lseek (fd, -off, SEEK_CUR);
-  lused = lind = 0;
+    r = lseek (fd, -off, SEEK_CUR);
+
+  if (r >= 0)
+    lused = lind = 0;
 }