Bugzilla – Attachment 1302 Details for
Bug 799
scp incorrectly reports "stalled" on slow copies
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Revised scp diff
scp-smallwrite2.diff (text/plain), 4.93 KB, created by
Damien Miller
on 2007-06-12 16:37:09 AEST
(
hide
)
Description:
Revised scp diff
Filename:
MIME Type:
Creator:
Damien Miller
Created:
2007-06-12 16:37:09 AEST
Size:
4.93 KB
patch
obsolete
>Index: scp.c >=================================================================== >RCS file: /cvs/src/usr.bin/ssh/scp.c,v >retrieving revision 1.156 >diff -u -p -r1.156 scp.c >--- scp.c 22 Jan 2007 13:06:21 -0000 1.156 >+++ scp.c 12 Jun 2007 06:15:05 -0000 >@@ -73,6 +73,7 @@ > > #include <sys/param.h> > #include <sys/types.h> >+#include <sys/poll.h> > #include <sys/wait.h> > #include <sys/stat.h> > #include <sys/time.h> >@@ -98,6 +99,8 @@ > #include "misc.h" > #include "progressmeter.h" > >+#define SCP_BUFLEN 16384 >+ > int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout); > > void bwlimit(int); >@@ -271,6 +274,7 @@ void sink(int, char *[]); > void source(int, char *[]); > void tolocal(int, char *[]); > void toremote(char *, int, char *[]); >+size_t scpio(ssize_t (*)(int, void *, size_t), int, void *, size_t, off_t *); > void usage(void); > > int >@@ -425,6 +429,44 @@ main(int argc, char **argv) > exit(errs != 0); > } > >+/* >+ * atomicio-like wrapper that also applies bandwidth limits and updates >+ * the progressmeter counter. >+ */ >+size_t >+scpio(ssize_t (*f)(int, void *, size_t), int fd, void *_p, size_t l, off_t *c) >+{ >+ u_char *p = (u_char *)_p; >+ size_t o; >+ ssize_t r; >+ struct pollfd pfd; >+ >+ pfd.fd = fd; >+ pfd.events = f == read ? POLLIN : POLLOUT; >+ for (o = 0; o < l;) { >+ if (poll(&pfd, 1, -1) == -1) { >+ if (errno == EINTR) >+ continue; >+ fatal("%s: poll: %s", __func__, strerror(errno)); >+ } >+ r = f(fd, p + o, l - o); >+ if (r == 0) { >+ errno = EPIPE; >+ return o; >+ } >+ if (r < 0) { >+ if (errno == EINTR || errno == EAGAIN) >+ continue; >+ return 0; >+ } >+ o += (size_t)r; >+ *c += (off_t)r; >+ if (limit_rate) >+ bwlimit(r); >+ } >+ return o; >+} >+ > void > toremote(char *targ, int argc, char **argv) > { >@@ -567,7 +609,6 @@ source(int argc, char **argv) > static BUF buffer; > BUF *bp; > off_t i, amt, statbytes; >- size_t result; > int fd = -1, haderr, indx; > char *last, *name, buf[2048]; > int len; >@@ -629,7 +670,7 @@ syserr: run_err("%s: %s", name, strerr > (void) atomicio(vwrite, remout, buf, strlen(buf)); > if (response() < 0) > goto next; >- if ((bp = allocbuf(&buffer, fd, 2048)) == NULL) { >+ if ((bp = allocbuf(&buffer, fd, SCP_BUFLEN)) == NULL) { > next: if (fd != -1) { > (void) close(fd); > fd = -1; >@@ -638,27 +679,25 @@ next: if (fd != -1) { > } > if (showprogress) > start_progress_meter(curfile, stb.st_size, &statbytes); >- /* Keep writing after an error so that we stay sync'd up. */ >+ set_nonblock(remout); > for (haderr = i = 0; i < stb.st_size; i += bp->cnt) { > amt = bp->cnt; > if (i + amt > stb.st_size) > amt = stb.st_size - i; > if (!haderr) { >- result = atomicio(read, fd, bp->buf, amt); >- if (result != amt) >+ if (atomicio(read, fd, bp->buf, amt) != amt) > haderr = errno; > } >- if (haderr) >- (void) atomicio(vwrite, remout, bp->buf, amt); >- else { >- result = atomicio(vwrite, remout, bp->buf, amt); >- if (result != amt) >- haderr = errno; >- statbytes += result; >+ /* Keep writing after error to retain sync */ >+ if (haderr) { >+ (void)atomicio(vwrite, remout, bp->buf, amt); >+ continue; > } >- if (limit_rate) >- bwlimit(amt); >+ if (scpio(vwrite, remout, bp->buf, amt, >+ &statbytes) != amt) >+ haderr = errno; > } >+ unset_nonblock(remout); > if (showprogress) > stop_progress_meter(); > >@@ -764,10 +803,10 @@ bwlimit(int amount) > thresh /= 2; > if (thresh < 2048) > thresh = 2048; >- } else if (bwend.tv_usec < 100) { >+ } else if (bwend.tv_usec < 10000) { > thresh *= 2; >- if (thresh > 32768) >- thresh = 32768; >+ if (thresh > SCP_BUFLEN * 4) >+ thresh = SCP_BUFLEN * 4; > } > > TIMEVAL_TO_TIMESPEC(&bwend, &ts); >@@ -958,7 +997,7 @@ bad: run_err("%s: %s", np, strerror(er > continue; > } > (void) atomicio(vwrite, remout, "", 1); >- if ((bp = allocbuf(&buffer, ofd, 4096)) == NULL) { >+ if ((bp = allocbuf(&buffer, ofd, SCP_BUFLEN)) == NULL) { > (void) close(ofd); > continue; > } >@@ -968,26 +1007,24 @@ bad: run_err("%s: %s", np, strerror(er > statbytes = 0; > if (showprogress) > start_progress_meter(curfile, size, &statbytes); >- for (count = i = 0; i < size; i += 4096) { >- amt = 4096; >+ set_nonblock(remin); >+ for (count = i = 0; i < size; i += bp->cnt) { >+ amt = bp->cnt; > if (i + amt > size) > amt = size - i; > count += amt; > do { >- j = atomicio(read, remin, cp, amt); >+ j = scpio(read, remin, cp, amt, &statbytes); > if (j == 0) { >- run_err("%s", j ? strerror(errno) : >+ run_err("%s", j != EPIPE ? >+ strerror(errno) : > "dropped connection"); > exit(1); > } > amt -= j; > cp += j; >- statbytes += j; > } while (amt > 0); > >- if (limit_rate) >- bwlimit(4096); >- > if (count == bp->cnt) { > /* Keep reading so we stay sync'd up. */ > if (wrerr == NO) { >@@ -1001,6 +1038,7 @@ bad: run_err("%s: %s", np, strerror(er > cp = bp->buf; > } > } >+ unset_nonblock(remin); > if (showprogress) > stop_progress_meter(); > if (count != 0 && wrerr == NO &&
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
dtucker
:
ok+
Actions:
View
|
Diff
Attachments on
bug 799
:
1286
| 1302