Add an ETA timer that kicks in after 30 seconds.
Re-add alarm(2) calls around the calls to fetchStat(3) and fetchXGet(3), since these calls can still time out on DNS lookups or TCP connect(2). Remove the alarm(2) calls in the main loop, since all methods properly handle transfer timeouts (as opposed to connection timeouts). Set the sigalrm flag if a timeout occurs in the main loop. Move the signal: label up a little so we still set the atime and mtime when the transfer times out or is interrupted, so that restarted transfers will work as expected (as long as the file still exists). MFC after: 2 weeks
This commit is contained in:
parent
e24f60e74f
commit
dc161d5582
@ -142,11 +142,27 @@ stat_display(struct xferstat *xs, int force)
|
||||
xs->last = now;
|
||||
|
||||
fprintf(stderr, "\rReceiving %s", xs->name);
|
||||
if (xs->size <= 0)
|
||||
if (xs->size <= 0) {
|
||||
fprintf(stderr, ": %lld bytes", (long long)xs->rcvd);
|
||||
else
|
||||
} else {
|
||||
long elapsed;
|
||||
|
||||
fprintf(stderr, " (%lld bytes): %d%%", (long long)xs->size,
|
||||
(int)((100.0 * xs->rcvd) / xs->size));
|
||||
elapsed = xs->last.tv_sec - xs->start.tv_sec;
|
||||
if (elapsed > 30) {
|
||||
long remaining;
|
||||
|
||||
remaining = ((xs->size * elapsed) / xs->rcvd) - elapsed;
|
||||
fprintf(stderr, " (ETA ");
|
||||
if (remaining > 3600) {
|
||||
fprintf(stderr, "%02ld:", remaining / 3600);
|
||||
remaining %= 3600;
|
||||
}
|
||||
fprintf(stderr, "%02ld:%02ld) ",
|
||||
remaining / 60, remaining % 60);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -328,8 +344,17 @@ fetch(char *URL, const char *path)
|
||||
|
||||
/* just print size */
|
||||
if (s_flag) {
|
||||
if (fetchStat(url, &us, flags) == -1)
|
||||
if (timeout)
|
||||
alarm(timeout);
|
||||
r = fetchStat(url, &us, flags);
|
||||
if (timeout)
|
||||
alarm(0);
|
||||
if (sigalrm || sigint)
|
||||
goto signal;
|
||||
if (r == -1) {
|
||||
warnx("%s", fetchLastErrString);
|
||||
goto failure;
|
||||
}
|
||||
if (us.size == -1)
|
||||
printf("Unknown\n");
|
||||
else
|
||||
@ -359,7 +384,12 @@ fetch(char *URL, const char *path)
|
||||
url->offset = sb.st_size;
|
||||
|
||||
/* start the transfer */
|
||||
if ((f = fetchXGet(url, &us, flags)) == NULL) {
|
||||
if (timeout)
|
||||
alarm(timeout);
|
||||
f = fetchXGet(url, &us, flags);
|
||||
if (sigalrm || sigint)
|
||||
goto signal;
|
||||
if (f == NULL) {
|
||||
warnx("%s: %s", path, fetchLastErrString);
|
||||
goto failure;
|
||||
}
|
||||
@ -501,30 +531,25 @@ fetch(char *URL, const char *path)
|
||||
|
||||
/* suck in the data */
|
||||
signal(SIGINFO, sig_handler);
|
||||
while (!sigint && !sigalrm) {
|
||||
while (!sigint) {
|
||||
if (us.size != -1 && us.size - count < B_size)
|
||||
size = us.size - count;
|
||||
else
|
||||
size = B_size;
|
||||
if (timeout)
|
||||
alarm(timeout);
|
||||
if (siginfo) {
|
||||
stat_end(&xs);
|
||||
siginfo = 0;
|
||||
}
|
||||
if ((size = fread(buf, 1, size, f)) == 0) {
|
||||
if (ferror(f) && errno == EINTR && !sigalrm && !sigint)
|
||||
if (ferror(f) && errno == EINTR && !sigint)
|
||||
clearerr(f);
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (timeout)
|
||||
alarm(0);
|
||||
stat_update(&xs, count += size);
|
||||
for (ptr = buf; size > 0; ptr += wr, size -= wr)
|
||||
if ((wr = fwrite(ptr, 1, size, of)) < size) {
|
||||
if (ferror(of) && errno == EINTR &&
|
||||
!sigalrm && !sigint)
|
||||
if (ferror(of) && errno == EINTR && !sigint)
|
||||
clearerr(of);
|
||||
else
|
||||
break;
|
||||
@ -532,13 +557,18 @@ fetch(char *URL, const char *path)
|
||||
if (size != 0)
|
||||
break;
|
||||
}
|
||||
if (!sigalrm)
|
||||
sigalrm = ferror(f) && errno == ETIMEDOUT;
|
||||
signal(SIGINFO, SIG_DFL);
|
||||
|
||||
if (timeout)
|
||||
alarm(0);
|
||||
|
||||
stat_end(&xs);
|
||||
|
||||
/*
|
||||
* If the transfer timed out or was interrupted, we still want to
|
||||
* set the mtime in case the file is not removed (-r or -R) and
|
||||
* the user later restarts the transfer.
|
||||
*/
|
||||
signal:
|
||||
/* set mtime of local file */
|
||||
if (!n_flag && us.mtime && !o_stdout
|
||||
&& (stat(path, &sb) != -1) && sb.st_mode & S_IFREG) {
|
||||
@ -553,7 +583,6 @@ fetch(char *URL, const char *path)
|
||||
}
|
||||
|
||||
/* timed out or interrupted? */
|
||||
signal:
|
||||
if (sigalrm)
|
||||
warnx("transfer timed out");
|
||||
if (sigint) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user