diff --git a/usr.bin/fetch/fetch.1 b/usr.bin/fetch/fetch.1 --- a/usr.bin/fetch/fetch.1 +++ b/usr.bin/fetch/fetch.1 @@ -28,7 +28,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd October 7, 2023 +.Dd June 27, 2026 .Dt FETCH 1 .Os .Sh NAME @@ -283,7 +283,7 @@ .It Fl s , -print-size Print the size in bytes of each requested file, without fetching it. .It Fl T Ar seconds , Fl -timeout= Ns Ar seconds -Set timeout value to +Set the network timeout to .Ar seconds . Overrides the environment variables .Ev FTP_TIMEOUT @@ -322,9 +322,11 @@ .Sh ENVIRONMENT .Bl -tag -width HTTP_TIMEOUT .It Ev FTP_TIMEOUT -Maximum time, in seconds, to wait before aborting an FTP connection. +Maximum time, in seconds, to wait before giving up on a stalled FTP +transfer. .It Ev HTTP_TIMEOUT -Maximum time, in seconds, to wait before aborting an HTTP connection. +Maximum time, in seconds, to wait before giving up on a stalled HTTP +transfer. .El .Pp See diff --git a/usr.bin/fetch/fetch.c b/usr.bin/fetch/fetch.c --- a/usr.bin/fetch/fetch.c +++ b/usr.bin/fetch/fetch.c @@ -87,7 +87,6 @@ static long w_secs; /* -w: retry delay */ static int family = PF_UNSPEC; /* -[46]: address family to use */ -static int sigalrm; /* SIGALRM received */ static int siginfo; /* SIGINFO received */ static int sigint; /* SIGINT received */ @@ -173,9 +172,6 @@ sig_handler(int sig) { switch (sig) { - case SIGALRM: - sigalrm = 1; - break; case SIGINFO: siginfo = 1; break; @@ -436,6 +432,7 @@ char *tmppath; int r, tries; unsigned timeout; + int timedout = 0; char *ptr; f = of = NULL; @@ -519,13 +516,7 @@ /* just print size */ if (s_flag) { - if (timeout) - alarm(timeout); r = fetchStat(url, &us, flags); - if (timeout) - alarm(0); - if (sigalrm || sigint) - goto signal; if (r == -1) { warnx("%s", fetchLastErrString); goto failure; @@ -574,13 +565,7 @@ size_prev = sb.st_size; /* start the transfer */ - if (timeout) - alarm(timeout); f = fetchXGet(url, &us, flags); - if (timeout) - alarm(0); - if (sigalrm || sigint) - goto signal; if (f == NULL) { if (i_flag && *is_http && fetchLastErrCode == FETCH_OK && strcmp(fetchLastErrString, "Not Modified") == 0) { @@ -748,7 +733,7 @@ /* start the counter */ stat_start(&xs, path, us.size, count); - sigalrm = siginfo = sigint = 0; + siginfo = sigint = 0; /* suck in the data */ setvbuf(f, NULL, _IOFBF, B_size); @@ -785,8 +770,7 @@ if (readcnt != 0) break; } - if (!sigalrm) - sigalrm = ferror(f) && errno == ETIMEDOUT; + timedout = ferror(f) && errno == ETIMEDOUT; signal(SIGINFO, SIG_DFL); stat_end(&xs); @@ -811,18 +795,20 @@ } /* timed out or interrupted? */ - if (sigalrm) + if (timedout) { warnx("transfer timed out"); + goto failure; + } if (sigint) { warnx("transfer interrupted"); goto failure; } - /* timeout / interrupt before connection completley established? */ + /* timeout / interrupt before connection completely established? */ if (f == NULL) goto failure; - if (!sigalrm) { + if (!timedout) { /* check the status of our files */ if (ferror(f)) warn("%s", URL); @@ -850,7 +836,7 @@ * If the transfer timed out and we didn't know how much to * expect, assume the worst (i.e. we didn't get all of it) */ - if (sigalrm && us.size == -1) { + if (timedout && us.size == -1) { warnx("%s may be truncated", path); goto failure_keep; } @@ -1126,7 +1112,6 @@ sa.sa_flags = 0; sa.sa_handler = sig_handler; sigemptyset(&sa.sa_mask); - sigaction(SIGALRM, &sa, NULL); sa.sa_flags = SA_RESETHAND; sigaction(SIGINT, &sa, NULL); fetchRestartCalls = 0;