Source-Changes-HG archive

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

[src/trunk]: src/bin/rcp Fix bug revealed by SIGINFO support; Do not treat sh...



details:   https://anonhg.NetBSD.org/src/rev/332bf95b6740
branches:  trunk
changeset: 368552:332bf95b6740
user:      rin <rin%NetBSD.org@localhost>
date:      Mon Jul 18 13:01:59 2022 +0000

description:
Fix bug revealed by SIGINFO support; Do not treat short read(2)/write(2)
as error (*). This occurs typically when signal is received.

(*) For older version, we already deal with short read(2) from remote
host in sink(). But for other cases, i.e., write(2) to local file in
sink(), read(2)/write(2) in source(), error was raised.

This version of rcp(1) can successfully send/receive files with older
version, even if short read(2)/write(2) occurs by SIGINFO.

Also, when real error occurs, give up immediately instead of continue to
send/receive wrong data.

Clean up the mess a little bit as well...

diffstat:

 bin/rcp/rcp.c |  79 +++++++++++++++++++++++++++-------------------------------
 1 files changed, 37 insertions(+), 42 deletions(-)

diffs (146 lines):

diff -r 31532e4fc840 -r 332bf95b6740 bin/rcp/rcp.c
--- a/bin/rcp/rcp.c     Mon Jul 18 11:09:22 2022 +0000
+++ b/bin/rcp/rcp.c     Mon Jul 18 13:01:59 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rcp.c,v 1.51 2022/06/26 09:29:59 rin Exp $     */
+/*     $NetBSD: rcp.c,v 1.52 2022/07/18 13:01:59 rin Exp $     */
 
 /*
  * Copyright (c) 1983, 1990, 1992, 1993
@@ -39,7 +39,7 @@
 #if 0
 static char sccsid[] = "@(#)rcp.c      8.2 (Berkeley) 4/2/94";
 #else
-__RCSID("$NetBSD: rcp.c,v 1.51 2022/06/26 09:29:59 rin Exp $");
+__RCSID("$NetBSD: rcp.c,v 1.52 2022/07/18 13:01:59 rin Exp $");
 #endif
 #endif /* not lint */
 
@@ -335,8 +335,10 @@
        BUF *bp;
        off_t i;
        off_t amt;
-       int fd, haderr, indx, result;
-       char *last, *name, buf[BUFSIZ];
+       size_t resid;
+       ssize_t result;
+       int fd, haderr, indx;
+       char *last, *name, *cp, buf[BUFSIZ];
 
        for (indx = 0; indx < argc; ++indx) {
                name = argv[indx];
@@ -396,19 +398,24 @@
                        amt = bp->cnt;
                        if (i + amt > stb.st_size)
                                amt = stb.st_size - i;
-                       if (!haderr) {
-                               result = read(fd, bp->buf, (size_t)amt);
-                               if (result != amt)
-                                       haderr = result >= 0 ? EIO : errno;
+                       for (resid = (size_t)amt, cp = bp->buf; resid > 0;
+                           resid -= result, cp += result) {
+                               result = read(fd, cp, resid);
+                               if (result == -1) {
+                                       haderr = errno;
+                                       goto error;
+                               }
                        }
-                       if (haderr)
-                               (void)write(rem, bp->buf, (size_t)amt);
-                       else {
-                               result = write(rem, bp->buf, (size_t)amt);
-                               if (result != amt)
-                                       haderr = result >= 0 ? EIO : errno;
+                       for (resid = (size_t)amt, cp = bp->buf; resid > 0;
+                           resid -= result, cp += result) {
+                               result = write(rem, cp, resid);
+                               if (result == -1) {
+                                       haderr = errno;
+                                       goto error;
+                               }
                        }
                }
+ error:
                if (close(fd) && !haderr)
                        haderr = errno;
                if (!haderr)
@@ -479,10 +486,10 @@
        struct stat stb;
        struct timeval tv[2];
        BUF *bp;
-       ssize_t j;
+       size_t resid;
+       ssize_t result;
        off_t i;
        off_t amt;
-       off_t count;
        int exists, first, ofd;
        mode_t mask;
        mode_t mode;
@@ -649,7 +656,6 @@
                        (void)close(ofd);
                        continue;
                }
-               cp = bp->buf;
                wrerr = 0;
 
 /*
@@ -664,44 +670,33 @@
        }                                                               \
 } while(0)
 
-               count = 0;
-               for (i = 0; i < size; i += BUFSIZ) {
+               for (i = 0; i < size; i += bp->cnt) {
                        if (print_info)
                                progress(np, i, size);
-                       amt = BUFSIZ;
+                       amt = bp->cnt;
                        if (i + amt > size)
                                amt = size - i;
-                       count += amt;
-                       do {
-                               j = read(rem, cp, (size_t)amt);
-                               if (j == -1) {
-                                       run_err("%s", j ? strerror(errno) :
-                                           "dropped connection");
+                       for (resid = (size_t)amt, cp = bp->buf; resid > 0;
+                           resid -= result, cp += result) {
+                               result = read(rem, cp, resid);
+                               if (result == -1) {
+                                       run_err("%s", strerror(errno));
                                        exit(1);
                                }
-                               amt -= j;
-                               cp += j;
-                       } while (amt > 0);
-                       if (count == bp->cnt) {
+                       }
+                       for (resid = (size_t)amt, cp = bp->buf; resid > 0;
+                           resid -= result, cp += result) {
                                /* Keep reading so we stay sync'd up. */
                                if (!wrerr) {
-                                       j = write(ofd, bp->buf, (size_t)count);
-                                       if (j != count) {
-                                               if (j >= 0)
-                                                       errno = EIO;
+                                       result = write(ofd, cp, resid);
+                                       if (result == -1) {
                                                RUN_ERR("write");
+                                               goto error;
                                        }
                                }
-                               count = 0;
-                               cp = bp->buf;
                        }
                }
-               if (count != 0 && !wrerr &&
-                   (j = write(ofd, bp->buf, (size_t)count)) != count) {
-                       if (j >= 0)
-                               errno = EIO;
-                       RUN_ERR("write");
-               }
+ error:
                if (ftruncate(ofd, size))
                        RUN_ERR("truncate");
 



Home | Main Index | Thread Index | Old Index