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