On Fri, 19 Aug 2016 19:14:54 -0400, "Ted Unangst" wrote:

> hmm. so I was trying to avoid the need for two different functions. I think
> there's a mental overhead to "do this, then maybe that". this loop reads
> very strangely to me. it's hard to mentally trace the code. it's not really a
> loop, just goto spelled with break and continue.

I suppose it is better to just use connect() and connect_wait() in
a for() loop.  Whichever way you choose we should put as an example
in connect(2).

 - todd

Index: usr.bin/ftp/extern.h
===================================================================
RCS file: /cvs/src/usr.bin/ftp/extern.h,v
retrieving revision 1.43
diff -u -p -u -r1.43 extern.h
--- usr.bin/ftp/extern.h        18 Aug 2016 16:23:06 -0000      1.43
+++ usr.bin/ftp/extern.h        19 Aug 2016 21:54:32 -0000
@@ -62,7 +62,6 @@
  */
 
 #include <sys/types.h>
-#include <sys/socket.h>
 
 void   abort_remote(FILE *);
 void   abortpt(int);
@@ -76,7 +75,7 @@ void  cmdabort(int);
 void   cmdscanner(int);
 int    command(const char *, ...);
 int    confirm(const char *, const char *);
-int    connect_sync(int, const struct sockaddr *, socklen_t);
+int    connect_wait(int);
 FILE   *dataconn(const char *);
 int    foregroundproc(void);
 int    fileindir(const char *, const char *);
Index: usr.bin/ftp/fetch.c
===================================================================
RCS file: /cvs/src/usr.bin/ftp/fetch.c,v
retrieving revision 1.148
diff -u -p -u -r1.148 fetch.c
--- usr.bin/ftp/fetch.c 18 Aug 2016 16:23:06 -0000      1.148
+++ usr.bin/ftp/fetch.c 19 Aug 2016 23:28:11 -0000
@@ -557,8 +557,10 @@ noslash:
                }
 #endif /* !SMALL */
 
-again:
-               if (connect_sync(s, res->ai_addr, res->ai_addrlen) < 0) {
+               for (error = connect(s, res->ai_addr, res->ai_addrlen);
+                   error != 0 && errno == EINTR; error = connect_wait(s))
+                       continue;
+               if (error != 0) {
                        save_errno = errno;
                        close(s);
                        errno = save_errno;
Index: usr.bin/ftp/ftp.c
===================================================================
RCS file: /cvs/src/usr.bin/ftp/ftp.c,v
retrieving revision 1.98
diff -u -p -u -r1.98 ftp.c
--- usr.bin/ftp/ftp.c   18 Aug 2016 16:23:06 -0000      1.98
+++ usr.bin/ftp/ftp.c   19 Aug 2016 23:28:22 -0000
@@ -219,8 +219,10 @@ hookup(char *host, char *port)
                        }
                }
 #endif /* !SMALL */
-               error = connect_sync(s, res->ai_addr, res->ai_addrlen);
-               if (error) {
+               for (error = connect(s, res->ai_addr, res->ai_addrlen);
+                   error != 0 && errno == EINTR; error = connect_wait(s))
+                       continue;
+               if (error != 0) {
                        /* this "if" clause is to prevent print warning twice */
                        if (verbose && res->ai_next) {
                                if (getnameinfo(res->ai_addr, res->ai_addrlen,
@@ -1514,8 +1516,11 @@ reinit:
                } else
                        goto bad;
 
-               if (connect_sync(data, (struct sockaddr *)&data_addr,
-                           data_addr.su_len) < 0) {
+               for (error = connect(data, (struct sockaddr *)&data_addr,
+                   data_addr.su_len); error != 0 && errno == EINTR;
+                   error = connect_wait(data))
+                       continue;
+               if (error != 0) {
                        if (activefallback) {
                                (void)close(data);
                                data = -1;
Index: usr.bin/ftp/util.c
===================================================================
RCS file: /cvs/src/usr.bin/ftp/util.c,v
retrieving revision 1.80
diff -u -p -u -r1.80 util.c
--- usr.bin/ftp/util.c  18 Aug 2016 16:23:06 -0000      1.80
+++ usr.bin/ftp/util.c  19 Aug 2016 22:03:10 -0000
@@ -67,6 +67,7 @@
  * FTP User Program -- Misc support routines
  */
 #include <sys/ioctl.h>
+#include <sys/socket.h>
 #include <sys/time.h>
 #include <arpa/ftp.h>
 
@@ -1070,35 +1071,25 @@ controlediting(void)
 #endif /* !SMALL */
 
 /*
- * Wrapper for connect(2) that restarts the syscall when
- * interrupted and operates synchronously.
+ * Wait for an asynchronous connect(2) attempt to finish.
  */
 int
-connect_sync(int s, const struct sockaddr *name, socklen_t namelen)
+connect_wait(int s)
 {
        struct pollfd pfd[1];
        int error = 0;
        socklen_t len = sizeof(error);
 
-       if (connect(s, name, namelen) < 0) {
-               if (errno != EINTR)
-                       return -1;
-       }
-
-       /* An interrupted connect(2) continues asyncronously. */
        pfd[0].fd = s;
        pfd[0].events = POLLOUT;
-       for (;;) {
-               if (poll(pfd, 1, -1) == -1) {
-                       if (errno != EINTR)
-                               return -1;
-                       continue;
-               }
-               if (getsockopt(s, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
-                       return -1;
-               if (error != 0)
-                       errno = error;
-               break;
+
+       if (poll(pfd, 1, -1) == -1)
+               return -1;
+       if (getsockopt(s, SOL_SOCKET, SO_ERROR, &error, &len) < 0)
+               return -1;
+       if (error != 0) {
+               errno = error;
+               return -1;
        }
-       return (error ? -1 : 0);
+       return 0;
 }

Reply via email to