summaryrefslogtreecommitdiffstats
path: root/usr.bin/fetch
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/fetch')
-rw-r--r--usr.bin/fetch/fetch.c34
1 files changed, 29 insertions, 5 deletions
diff --git a/usr.bin/fetch/fetch.c b/usr.bin/fetch/fetch.c
index a0796a7..3325346 100644
--- a/usr.bin/fetch/fetch.c
+++ b/usr.bin/fetch/fetch.c
@@ -78,6 +78,7 @@ u_int w_secs; /* -w: retry delay */
int family = PF_UNSPEC; /* -[46]: address family to use */
int sigalrm; /* SIGALRM received */
+int siginfo; /* SIGINFO received */
int sigint; /* SIGINT received */
u_int ftp_timeout; /* default timeout for FTP transfers */
@@ -92,6 +93,9 @@ sig_handler(int sig)
case SIGALRM:
sigalrm = 1;
break;
+ case SIGINFO:
+ siginfo = 1;
+ break;
case SIGINT:
sigint = 1;
break;
@@ -183,11 +187,12 @@ fetch(char *URL, char *path)
struct stat sb;
struct xferstat xs;
FILE *f, *of;
- size_t size;
+ size_t size, wr;
off_t count;
char flags[8];
int n, r;
u_int timeout;
+ u_char *ptr;
f = of = NULL;
@@ -385,9 +390,10 @@ fetch(char *URL, char *path)
/* start the counter */
stat_start(&xs, path, us.size, count);
- sigint = sigalrm = 0;
+ sigalrm = siginfo = sigint = 0;
/* suck in the data */
+ signal(SIGINFO, sig_handler);
for (n = 0; !sigint && !sigalrm; ++n) {
if (us.size != -1 && us.size - count < B_size)
size = us.size - count;
@@ -395,12 +401,30 @@ fetch(char *URL, char *path)
size = B_size;
if (timeout)
alarm(timeout);
- if ((size = fread(buf, 1, size, f)) <= 0)
- break;
+ if ((size = fread(buf, 1, size, f)) == 0) {
+ if (ferror(f) && errno == EINTR && !sigalrm && !sigint)
+ clearerr(f);
+ else
+ break;
+ }
+ if (timeout)
+ alarm(0);
+ if (siginfo) {
+ stat_end(&xs);
+ siginfo = 0;
+ }
stat_update(&xs, count += size, 0);
- if (fwrite(buf, size, 1, of) != 1)
+ for (ptr = buf; size > 0; ptr += wr, size -= wr)
+ if ((wr = fwrite(ptr, 1, size, of)) < size) {
+ if (ferror(of) && errno == EINTR && !sigalrm && !sigint)
+ clearerr(of);
+ else
+ break;
+ }
+ if (size != 0)
break;
}
+ signal(SIGINFO, SIG_DFL);
if (timeout)
alarm(0);
OpenPOWER on IntegriCloud