Source-Changes-HG archive

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

[src/trunk]: src/bin/pax Fix SIGINFO botch (PR #8868).



details:   https://anonhg.NetBSD.org/src/rev/41aee9954dcf
branches:  trunk
changeset: 482609:41aee9954dcf
user:      itohy <itohy%NetBSD.org@localhost>
date:      Thu Feb 17 03:06:12 2000 +0000

description:
Fix SIGINFO botch (PR #8868).
Continue partial write(2) on signals (xwrite()).
Partial read(2) at a few places are also continued (xread()).

Add {read,write}_with_restart() hooks for porting on systems
which don't restart interrupted read()/write() calls.

Reviewed and discussed in tech-kern and tech-userlevel lists.

diffstat:

 bin/pax/ar_io.c     |  144 ++++++++++++++++++++++++++++++++++++++++++++++++---
 bin/pax/buf_subs.c  |   10 +-
 bin/pax/extern.h    |   11 +++-
 bin/pax/file_subs.c |    8 +-
 bin/pax/tables.c    |   16 ++--
 5 files changed, 162 insertions(+), 27 deletions(-)

diffs (truncated from 376 to 300 lines):

diff -r 7283bdcf7ecc -r 41aee9954dcf bin/pax/ar_io.c
--- a/bin/pax/ar_io.c   Thu Feb 17 02:07:07 2000 +0000
+++ b/bin/pax/ar_io.c   Thu Feb 17 03:06:12 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ar_io.c,v 1.14 1999/10/22 20:59:08 is Exp $    */
+/*     $NetBSD: ar_io.c,v 1.15 2000/02/17 03:06:12 itohy Exp $ */
 
 /*-
  * Copyright (c) 1992 Keith Muller.
@@ -42,7 +42,7 @@
 #if 0
 static char sccsid[] = "@(#)ar_io.c    8.2 (Berkeley) 4/18/94";
 #else
-__RCSID("$NetBSD: ar_io.c,v 1.14 1999/10/22 20:59:08 is Exp $");
+__RCSID("$NetBSD: ar_io.c,v 1.15 2000/02/17 03:06:12 itohy Exp $");
 #endif
 #endif /* not lint */
 
@@ -438,7 +438,7 @@
        /*
         * keep reading until pipe is drained
         */
-       while ((res = read(arfd, drbuf, sizeof(drbuf))) > 0)
+       while ((res = read_with_restart(arfd, drbuf, sizeof(drbuf))) > 0)
                ;
        lstrval = res;
 }
@@ -518,6 +518,132 @@
        return(-1);
 }
 
+#ifdef SYS_NO_RESTART
+/*
+ * read_with_restart()
+ *     Equivalent to read() but does retry on signals.
+ *     This function is not needed on 4.2BSD and later.
+ * Return:
+ *     Number of bytes written.  -1 indicates an error.
+ */
+
+#if __STDC__
+int
+read_with_restart(int fd, void *buf, int bsz)
+#else
+int
+read_with_restart(fd, buf, bsz)
+       int fd;
+       void *buf;
+       int bsz;
+#endif
+{
+       int r;
+
+       while (((r = read(fd, buf, bsz)) < 0) && errno == EINTR)
+               ;
+
+       return(r);
+}
+#endif
+
+/*
+ * xread()
+ *     Equivalent to read() but does retry on partial read, which may occur
+ *     on signals.
+ * Return:
+ *     Number of bytes read.  0 for end of file, -1 for an error.
+ */
+
+#if __STDC__
+int
+xread(int fd, void *buf, int bsz)
+#else
+int
+xread(fd, buf, bsz)
+       int fd;
+       void *buf;
+       int bsz;
+#endif
+{
+       char *b = buf;
+       int nread = 0;
+       int r;
+
+       do {
+               if ((r = read_with_restart(fd, b, bsz)) <= 0)
+                       break;
+               b += r;
+               bsz -= r;
+               nread += r;
+       } while (bsz > 0);
+
+       return(nread ? nread : r);
+}
+
+#ifdef SYS_NO_RESTART
+/*
+ * write_with_restart()
+ *     Equivalent to write() but does retry on signals.
+ *     This function is not needed on 4.2BSD and later.
+ * Return:
+ *     Number of bytes written.  -1 indicates an error.
+ */
+
+#if __STDC__
+int
+write_with_restart(int fd, void *buf, int bsz)
+#else
+int
+write_with_restart(fd, buf, bsz)
+       int fd;
+       void *buf;
+       int bsz;
+#endif
+{
+       int r;
+
+       while (((r = write(fd, buf, bsz)) < 0) && errno == EINTR)
+               ;
+
+       return(r);
+}
+#endif
+
+/*
+ * xwrite()
+ *     Equivalent to write() but does retry on partial write, which may occur
+ *     on signals.
+ * Return:
+ *     Number of bytes written.  -1 indicates an error.
+ */
+
+#if __STDC__
+int
+xwrite(int fd, void *buf, int bsz)
+#else
+int
+xwrite(fd, buf, bsz)
+       int fd;
+       void *buf;
+       int bsz;
+#endif
+{
+       char *b = buf;
+       int written = 0;
+       int r;
+
+       do {
+               if ((r = write_with_restart(fd, b, bsz)) <= 0)
+                       break;
+               b += r;
+               bsz -= r;
+               written += r;
+       } while (bsz > 0);
+
+       return(written ? written : r);
+}
+
 /*
  * ar_read()
  *     read up to a specified number of bytes from the archive into the
@@ -550,7 +676,7 @@
         */
        switch (artyp) {
        case ISTAPE:
-               if ((res = read(arfd, buf, cnt)) > 0) {
+               if ((res = read_with_restart(arfd, buf, cnt)) > 0) {
                        /*
                         * CAUTION: tape systems may not always return the same
                         * sized records so we leave blksz == MAXBLK. The
@@ -588,7 +714,7 @@
                 * and return. Trying to do anything else with them runs the
                 * risk of failure.
                 */
-               if ((res = read(arfd, buf, cnt)) > 0) {
+               if ((res = read_with_restart(arfd, buf, cnt)) > 0) {
                        io_ok = 1;
                        return(res);
                }
@@ -637,7 +763,7 @@
        if (lstrval <= 0)
                return(lstrval);
 
-       if ((res = write(arfd, buf, bsz)) == bsz) {
+       if ((res = xwrite(arfd, buf, bsz)) == bsz) {
                wr_trail = 1;
                io_ok = 1;
                return(bsz);
@@ -1064,7 +1190,7 @@
                 * we know we are at file mark when we get back a 0 from
                 * read()
                 */
-               while ((res = read(arfd, scbuf, sizeof(scbuf))) > 0)
+               while ((res = read_with_restart(arfd, scbuf, sizeof(scbuf))) > 0)
                        padsz += res;
                if (res < 0) {
                        syswarn(1, errno, "Unable to locate tape filemark.");
@@ -1093,7 +1219,7 @@
                syswarn(1, errno, "Unable to backspace over last tape block.");
                return(-1);
        }
-       if ((phyblk = read(arfd, scbuf, sizeof(scbuf))) <= 0) {
+       if ((phyblk = read_with_restart(arfd, scbuf, sizeof(scbuf))) <= 0) {
                syswarn(1, errno, "Cannot determine archive tape blocksize.");
                return(-1);
        }
@@ -1102,7 +1228,7 @@
         * read foward to the file mark, then back up in front of the filemark
         * (this is a bit paranoid, but should be safe to do).
         */
-       while ((res = read(arfd, scbuf, sizeof(scbuf))) > 0)
+       while ((res = read_with_restart(arfd, scbuf, sizeof(scbuf))) > 0)
                ;
        if (res < 0) {
                syswarn(1, errno, "Unable to locate tape filemark.");
diff -r 7283bdcf7ecc -r 41aee9954dcf bin/pax/buf_subs.c
--- a/bin/pax/buf_subs.c        Thu Feb 17 02:07:07 2000 +0000
+++ b/bin/pax/buf_subs.c        Thu Feb 17 03:06:12 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: buf_subs.c,v 1.11 1999/10/22 10:43:11 mrg Exp $        */
+/*     $NetBSD: buf_subs.c,v 1.12 2000/02/17 03:06:13 itohy Exp $      */
 
 /*-
  * Copyright (c) 1992 Keith Muller.
@@ -42,7 +42,7 @@
 #if 0
 static char sccsid[] = "@(#)buf_subs.c 8.2 (Berkeley) 4/18/94";
 #else
-__RCSID("$NetBSD: buf_subs.c,v 1.11 1999/10/22 10:43:11 mrg Exp $");
+__RCSID("$NetBSD: buf_subs.c,v 1.12 2000/02/17 03:06:13 itohy Exp $");
 #endif
 #endif /* not lint */
 
@@ -699,7 +699,7 @@
                        return(-1);
                }
                cnt = MIN(cnt, size);
-               if ((res = read(ifd, bufpt, cnt)) <= 0)
+               if ((res = read_with_restart(ifd, bufpt, cnt)) <= 0)
                        break;
                size -= res;
                bufpt += res;
@@ -884,10 +884,10 @@
         * read the source file and copy to destination file until EOF
         */
        for(;;) {
-               if ((cnt = read(fd1, buf, blksz)) <= 0)
+               if ((cnt = read_with_restart(fd1, buf, blksz)) <= 0)
                        break;
                if (no_hole)
-                       res = write(fd2, buf, cnt);
+                       res = xwrite(fd2, buf, cnt);
                else
                        res = file_write(fd2, buf, cnt, &rem, &isem, sz, fnm);
                if (res != cnt)
diff -r 7283bdcf7ecc -r 41aee9954dcf bin/pax/extern.h
--- a/bin/pax/extern.h  Thu Feb 17 02:07:07 2000 +0000
+++ b/bin/pax/extern.h  Thu Feb 17 03:06:12 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: extern.h,v 1.20 1999/11/01 01:35:58 mrg Exp $  */
+/*     $NetBSD: extern.h,v 1.21 2000/02/17 03:06:13 itohy Exp $        */
 
 /*-
  * Copyright (c) 1992 Keith Muller.
@@ -57,6 +57,15 @@
 void ar_drain __P((void));
 int ar_set_wr __P((void));
 int ar_app_ok __P((void));
+#ifdef SYS_NO_RESTART
+int read_with_restart __P((int, void *, int));
+int write_with_restart __P((int, void *, int));
+#else
+#define read_with_restart      read
+#define write_with_restart     write
+#endif
+int xread __P((int, void *, int));
+int xwrite __P((int, void *, int));
 int ar_read __P((char *, int));
 int ar_write __P((char *, int));
 int ar_rdsync __P((void));
diff -r 7283bdcf7ecc -r 41aee9954dcf bin/pax/file_subs.c
--- a/bin/pax/file_subs.c       Thu Feb 17 02:07:07 2000 +0000
+++ b/bin/pax/file_subs.c       Thu Feb 17 03:06:12 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: file_subs.c,v 1.15 1999/11/07 15:48:24 mycroft Exp $   */
+/*     $NetBSD: file_subs.c,v 1.16 2000/02/17 03:06:13 itohy Exp $     */
 
 /*-
  * Copyright (c) 1992 Keith Muller.
@@ -42,7 +42,7 @@
 #if 0
 static char sccsid[] = "@(#)file_subs.c        8.1 (Berkeley) 5/31/93";
 #else
-__RCSID("$NetBSD: file_subs.c,v 1.15 1999/11/07 15:48:24 mycroft Exp $");
+__RCSID("$NetBSD: file_subs.c,v 1.16 2000/02/17 03:06:13 itohy Exp $");
 #endif
 #endif /* not lint */
 
@@ -948,7 +948,7 @@
                        }
                        strncpy(gnu_hack_string, st, wcnt);



Home | Main Index | Thread Index | Old Index