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

Reply via email to