Module Name: src Committed By: martin Date: Sun Oct 24 10:13:40 UTC 2021
Modified Files: src/usr.bin/ftp [netbsd-9]: fetch.c Log Message: Pull up following revision(s) (requested by lukem in ticket #1365): usr.bin/ftp/fetch.c: revision 1.233 Use raw write(2) instead of fwrite(3) to avoid stream corruption because of the progress bar interrupts. From RVP. To generate a diff of this commit: cvs rdiff -u -r1.231.2.1 -r1.231.2.2 src/usr.bin/ftp/fetch.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/ftp/fetch.c diff -u src/usr.bin/ftp/fetch.c:1.231.2.1 src/usr.bin/ftp/fetch.c:1.231.2.2 --- src/usr.bin/ftp/fetch.c:1.231.2.1 Mon Jun 14 11:34:20 2021 +++ src/usr.bin/ftp/fetch.c Sun Oct 24 10:13:40 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: fetch.c,v 1.231.2.1 2021/06/14 11:34:20 martin Exp $ */ +/* $NetBSD: fetch.c,v 1.231.2.2 2021/10/24 10:13:40 martin Exp $ */ /*- * Copyright (c) 1997-2015 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: fetch.c,v 1.231.2.1 2021/06/14 11:34:20 martin Exp $"); +__RCSID("$NetBSD: fetch.c,v 1.231.2.2 2021/10/24 10:13:40 martin Exp $"); #endif /* not lint */ /* @@ -138,6 +138,43 @@ static int redirect_loop; ((urltype) == HTTP_URL_T) #endif +/** + * fwrite(3) replacement that just uses write(2). Many stdio implementations + * don't handle interrupts properly and corrupt the output. We are taking + * alarm interrupts because of the progress bar. + * + * Assumes `fp' is pristine with no prior I/O calls on it. + */ +static size_t +maxwrite(const void *buf, size_t size, size_t nmemb, FILE *fp) +{ + const char *p = buf; + ssize_t nwr = 0; + ssize_t n; + int fd = fileno(fp); + + size *= nmemb; /* assume no overflow */ + + while (size > 0) { + if ((n = write(fd, p, size)) == -1) { + switch (errno) { + case EINTR: + case EAGAIN: +#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: +#endif + continue; + default: + return nwr; + } + } + p += n; + nwr += n; + size -= n; + } + return nwr; +} + /* * Determine if token is the next word in buf (case insensitive). * If so, advance buf past the token and any trailing LWS, and @@ -1650,7 +1687,7 @@ fetch_url(const char *url, const char *p } bytes += flen; bufrem -= flen; - if (fwrite(xferbuf, sizeof(char), flen, fout) + if (maxwrite(xferbuf, sizeof(char), flen, fout) != flen) { warn("Writing `%s'", savefile); goto cleanup_fetch_url;