Dear Reader

I already send email about my issue with pkg_add staying up for a long time.
I cannot change the sysctl because other connections need large inactivity.

I finally got a 'decent' diff working, still not very good imho,
tls_read shall provide something smart as poll reply the data amount ready
to be fetch but because of the crypto layer, it cannot be used.
Also the FD is inside the tls context.
Also kept it out of <SMALL>

I do hope this, or a better this, can somewhat end up in base.
I suspect some kind of relay or transparent proxy to be bugged,
or a routing to get wrong during the transfer. This creating a socket
that does not ever close but does not send data. Or worse.
Anyway I'd like my pkg_add to quit after a while, and -w is only
doing the connection part.
I guess the variable should be rename too in another diff maybe or the same
don't know.

maybe SIGALARM could be used to effectively timeout in the read
payload part.

Index: fetch.c
===================================================================
RCS file: /cvs/src/usr.bin/ftp/fetch.c,v
retrieving revision 1.167
diff -u -p -r1.167 fetch.c
--- fetch.c     10 Feb 2018 06:25:16 -0000      1.167
+++ fetch.c     13 Oct 2018 03:51:53 -0000
@@ -63,6 +63,9 @@
 #else /* !NOSSL */
 struct tls;
 #endif /* !NOSSL */
+#ifndef SMALL
+#include <poll.h>
+#endif /* SMALL */
 #include "ftp_var.h"
 #include "cmds.h"
@@ -173,6 +176,33 @@ tooslow(int signo)
        _exit(2);
 }
+#ifndef SMALL
+int
+ftp_poll(struct pollfd pfd[]) {
+       int nready;
+       struct timespec timeout;
+       sigset_t blocked, omask;
+       sigemptyset(&blocked);
+       sigaddset(&blocked, SIGALRM); //PROGRESS METER -_-
+       sigprocmask(SIG_BLOCK, &blocked, &omask);
+
+       timeout.tv_sec = connect_timeout;
+       timeout.tv_nsec = 0;
+
+       nready = ppoll(pfd, 1, &timeout, &omask);
+       if (nready == -1) {
+               errx(1, "poll");
+       }
+       if (nready == 0) {
+               warn("Timeout\n");
+               return 1;
+       }
+       if ((pfd[0].revents & (POLLERR|POLLNVAL)))
+               errx(1, "bad fd");
+       return 0;
+}
+#endif
+
 /*
  * Retrieve URL, via the proxy in $proxyvar if necessary.
  * Modifies the string argument given.
@@ -210,6 +240,10 @@ url_get(const char *origline, const char
        int status;
        int save_errno;
        const size_t buflen = 128 * 1024;
+#ifndef SMALL
+       struct pollfd pfd[1];
+       pfd[0].fd = -1;
+#endif
        direction = "received";
@@ -609,6 +643,12 @@ noslash:
                goto cleanup_url_get;
        }
+#ifndef SMALL
+       if (connect_timeout) {
+               pfd[0].fd = fd;
+               pfd[0].events = POLLIN;
+       }
+#endif /* !SMALL */
 #ifndef NOSSL
        if (ishttpsurl) {
                if (proxyenv && sslpath) {
@@ -659,6 +699,11 @@ noslash:
                signal(SIGALRM, SIG_DFL);
                alarmtimer(0);
        }
+#ifndef SMALL
+       if (connect_timeout) {
+               fcntl(pfd[0].fd , F_SETFL, O_NONBLOCK);
+       }
+#endif /* !SMALL */
        /*
         * Construct and send the request. Proxy requests don't want
leading /.
@@ -763,6 +808,11 @@ noslash:
                warn("Writing HTTP request");
                goto cleanup_url_get;
        }
+#ifndef SMALL
+       if (pfd[0].fd != -1)
+               if (ftp_poll(pfd))
+                       goto cleanup_url_get;
+#endif
        if ((buf = ftp_readline(fin, tls, &len)) == NULL) {
                warn("Receiving HTTP reply");
                goto cleanup_url_get;
@@ -833,6 +883,11 @@ noslash:
        filesize = -1;
        for (;;) {
+#ifndef SMALL
+               if (pfd[0].fd != -1)
+                       if (ftp_poll(pfd))
+                               goto cleanup_url_get;
+#endif
                if ((buf = ftp_readline(fin, tls, &len)) == NULL) {
                        warn("Receiving HTTP reply");
                        goto cleanup_url_get;
@@ -978,6 +1033,11 @@ noslash:
        len = 1;
        oldinti = signal(SIGINFO, psummary);
        while (len > 0) {
+#ifndef SMALL
+               if (pfd[0].fd != -1)
+                       if (ftp_poll(pfd))
+                               goto cleanup_url_get;
+#endif
                len = ftp_read(fin, tls, buf, buflen);
                bytes += len;
                for (cp = buf, wlen = len; wlen > 0; wlen -= i, cp += i) {

-- 
--
---------------------------------------------------------------------------------------------------------------------
Knowing is not enough; we must apply. Willing is not enough; we must do

Reply via email to