Some of those tweaks were mentioned first in
https://marc.info/?l=openbsd-tech&m=157672366409171&w=2 * Fix setjmp vs volatile usage: - "buf" shouldn't be modified after setjmp, else we break the setjmp contract: --8<-- All accessible objects have values as of the time the longjmp() routine was called, except that the values of objects of automatic storage invocation duration that do not have the volatile type and have been changed between the setjmp() invocation and longjmp() call are indeterminate. -->8-- Looks like we're being lucky here. - a bunch of local variables are marked as volatile even though they're not touched between setjmp and longjmp. This leads to inefficient compiled code. * Sync read/write loop with file_get(): - no need for temp variable "i", "wlen" is enough and appropriately typed - make the loop condition/exit more similar (simpler) - there's no point in checking for write(2) returning 0 - properly save and restore errno in case of fread(3) failure size(1) says the resulting executables shrink on amd64. Reviews and oks welcome. Index: fetch.c =================================================================== --- fetch.c.orig +++ fetch.c @@ -77,7 +77,7 @@ static char hextochar(const char *); static char *urldecode(const char *); static char *recode_credentials(const char *_userinfo); static char *ftp_readline(FILE *, size_t *); -static void ftp_close(FILE **, struct tls **, volatile int *); +static void ftp_close(FILE **, struct tls **, int *); static const char *sockerror(struct tls *); #ifdef SMALL #define ftp_printf(fp, ...) fprintf(fp, __VA_ARGS__) @@ -311,13 +311,13 @@ url_get(const char *origline, const char char pbuf[NI_MAXSERV], hbuf[NI_MAXHOST], *cp, *portnum, *path, ststr[4]; char *hosttail, *cause = "unknown", *newline, *host, *port, *buf = NULL; char *epath, *redirurl, *loctail, *h, *p, gerror[200]; - int error, i, isftpurl = 0, isredirect = 0, rval = -1; + int error, isftpurl = 0, isredirect = 0, rval = -1; int isunavail = 0, retryafter = -1; struct addrinfo hints, *res0, *res; - const char * volatile savefile; - char * volatile proxyurl = NULL; + const char *savefile; + char *proxyurl = NULL; char *credentials = NULL; - volatile int fd = -1, out = -1; + int fd = -1, out = -1; volatile sig_t oldintr, oldinti; FILE *fin = NULL; off_t hashbytes; @@ -1013,6 +1013,10 @@ noslash: #endif } + free(buf); + if ((buf = malloc(buflen)) == NULL) + errx(1, "Can't allocate memory for transfer buffer"); + /* Trap signals */ oldintr = NULL; oldinti = NULL; @@ -1029,11 +1033,7 @@ noslash: hashbytes = mark; progressmeter(-1, path); - free(buf); - /* Finally, suck down the file. */ - if ((buf = malloc(buflen)) == NULL) - errx(1, "Can't allocate memory for transfer buffer"); oldinti = signal(SIGINFO, psummary); if (chunked) { error = save_chunked(fin, tls, out, buf, buflen); @@ -1041,18 +1041,14 @@ noslash: if (error == -1) goto cleanup_url_get; } else { - i = 0; - len = 1; - while (len > 0) { - len = fread(buf, 1, buflen, fin); + while ((len = fread(buf, 1, buflen, fin)) > 0) { bytes += len; - for (cp = buf, wlen = len; wlen > 0; wlen -= i, cp += i) { - if ((i = write(out, cp, wlen)) == -1) { + for (cp = buf; len > 0; len -= wlen, cp += wlen) { + if ((wlen = write(out, cp, len)) == -1) { warn("Writing %s", savefile); signal(SIGINFO, oldinti); goto cleanup_url_get; - } else if (i == 0) - break; + } } if (hash && !progress) { while (bytes >= hashbytes) { @@ -1062,6 +1058,7 @@ noslash: (void)fflush(ttyout); } } + save_errno = errno; signal(SIGINFO, oldinti); if (hash && !progress && bytes > 0) { if (bytes < mark) @@ -1069,7 +1066,8 @@ noslash: (void)putc('\n', ttyout); (void)fflush(ttyout); } - if (len != 0) { + if (len == 0 && ferror(fin)) { + errno = save_errno; warnx("Reading from socket: %s", sockerror(tls)); goto cleanup_url_get; } @@ -1650,7 +1648,7 @@ ftp_printf(FILE *fp, const char *fmt, .. #endif /* !SMALL */ static void -ftp_close(FILE **fin, struct tls **tls, volatile int *fd) +ftp_close(FILE **fin, struct tls **tls, int *fd) { #ifndef NOSSL int ret; -- jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF DDCC 0DFA 74AE 1524 E7EE