ftp: don't use restartable signals
Refactor to not rely upon restartable signals (SA_RESTART), possibly fixing intermittent failures with -q QUITTIME. ftp transfers: handle EINTR/EAGAIN in copy_bytes(), instead of relying upon restartable signals. http/https transfers: Explicitly print an error similar to progressmeter() when timing-out for -Q QUITTIME in fetch_wait(), and set errno to ETIMEDOUT so that the warn() in fetch_url() prints a more accurate error message. PR/55857
This commit is contained in:
parent
bd9b719c88
commit
920389c199
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: ftp.c,v 1.170 2020/07/11 02:19:31 lukem Exp $ */
|
||||
/* $NetBSD: ftp.c,v 1.171 2021/01/06 04:43:14 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996-2020 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1996-2021 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
|
@ -92,7 +92,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)ftp.c 8.6 (Berkeley) 10/27/94";
|
||||
#else
|
||||
__RCSID("$NetBSD: ftp.c,v 1.170 2020/07/11 02:19:31 lukem Exp $");
|
||||
__RCSID("$NetBSD: ftp.c,v 1.171 2021/01/06 04:43:14 lukem Exp $");
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
|
@ -593,7 +593,7 @@ abortxfer(int notused)
|
|||
|
||||
/*
|
||||
* Read data from infd & write to outfd, using buf/bufsize as the temporary
|
||||
* buffer, dealing with short writes.
|
||||
* buffer, dealing with short reads or writes.
|
||||
* If rate_limit != 0, rate-limit the transfer.
|
||||
* If hash_interval != 0, fputc('c', ttyout) every hash_interval bytes.
|
||||
* Updates global variables: bytes.
|
||||
|
@ -627,15 +627,25 @@ copy_bytes(int infd, int outfd, char *buf, size_t bufsize,
|
|||
bufrem = bufchunk;
|
||||
while (bufrem > 0) {
|
||||
inc = read(infd, buf, MIN((off_t)bufsize, bufrem));
|
||||
if (inc <= 0)
|
||||
if (inc < 0) {
|
||||
if (errno == EINTR || errno == EAGAIN) {
|
||||
continue;
|
||||
}
|
||||
goto copy_done;
|
||||
} else if (inc == 0) {
|
||||
goto copy_done;
|
||||
}
|
||||
bytes += inc;
|
||||
bufrem -= inc;
|
||||
bufp = buf;
|
||||
while (inc > 0) {
|
||||
outc = write(outfd, bufp, inc);
|
||||
if (outc < 0)
|
||||
if (outc < 0) {
|
||||
if (errno == EINTR || errno == EAGAIN) {
|
||||
continue;
|
||||
}
|
||||
goto copy_done;
|
||||
}
|
||||
inc -= outc;
|
||||
bufp += outc;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: progressbar.c,v 1.23 2019/06/22 23:40:33 christos Exp $ */
|
||||
/* $NetBSD: progressbar.c,v 1.24 2021/01/06 04:43:14 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1997-2009 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1997-2021 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
|
@ -31,7 +31,7 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: progressbar.c,v 1.23 2019/06/22 23:40:33 christos Exp $");
|
||||
__RCSID("$NetBSD: progressbar.c,v 1.24 2021/01/06 04:43:14 lukem Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
|
@ -193,7 +193,7 @@ progressmeter(int flag)
|
|||
if (quit_time > 0 || progress) {
|
||||
#endif /* !STANDALONE_PROGRESS */
|
||||
if (flag == -1) {
|
||||
(void)xsignal_restart(SIGALRM, updateprogressmeter, 1);
|
||||
(void)xsignal(SIGALRM, updateprogressmeter);
|
||||
alarmtimer(1); /* set alarm timer for 1 Hz */
|
||||
} else if (flag == 1) {
|
||||
alarmtimer(0);
|
||||
|
@ -404,73 +404,21 @@ alarmtimer(int wait)
|
|||
setitimer(ITIMER_REAL, &itv, NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Install a POSIX signal handler, allowing the invoker to set whether
|
||||
* the signal should be restartable or not
|
||||
* Install a non-restartable POSIX signal handler.
|
||||
*/
|
||||
sigfunc
|
||||
xsignal_restart(int sig, sigfunc func, int restartable)
|
||||
xsignal(int sig, sigfunc func)
|
||||
{
|
||||
struct sigaction act, oact;
|
||||
act.sa_handler = func;
|
||||
|
||||
sigemptyset(&act.sa_mask);
|
||||
#if defined(SA_RESTART) /* 4.4BSD, Posix(?), SVR4 */
|
||||
act.sa_flags = restartable ? SA_RESTART : 0;
|
||||
#elif defined(SA_INTERRUPT) /* SunOS 4.x */
|
||||
act.sa_flags = restartable ? 0 : SA_INTERRUPT;
|
||||
#else
|
||||
#error "system must have SA_RESTART or SA_INTERRUPT"
|
||||
act.sa_flags = 0;
|
||||
#if defined(SA_INTERRUPT) /* SunOS 4.x */
|
||||
act.sa_flags = SA_INTERRUPT;
|
||||
#endif
|
||||
if (sigaction(sig, &act, &oact) < 0)
|
||||
return (SIG_ERR);
|
||||
return (oact.sa_handler);
|
||||
}
|
||||
|
||||
/*
|
||||
* Install a signal handler with the `restartable' flag set dependent upon
|
||||
* which signal is being set. (This is a wrapper to xsignal_restart())
|
||||
*/
|
||||
sigfunc
|
||||
xsignal(int sig, sigfunc func)
|
||||
{
|
||||
int restartable;
|
||||
|
||||
/*
|
||||
* Some signals print output or change the state of the process.
|
||||
* There should be restartable, so that reads and writes are
|
||||
* not affected. Some signals should cause program flow to change;
|
||||
* these signals should not be restartable, so that the system call
|
||||
* will return with EINTR, and the program will go do something
|
||||
* different. If the signal handler calls longjmp() or siglongjmp(),
|
||||
* it doesn't matter if it's restartable.
|
||||
*/
|
||||
|
||||
switch(sig) {
|
||||
#ifdef SIGINFO
|
||||
case SIGINFO:
|
||||
#endif
|
||||
case SIGQUIT:
|
||||
case SIGUSR1:
|
||||
case SIGUSR2:
|
||||
case SIGWINCH:
|
||||
restartable = 1;
|
||||
break;
|
||||
|
||||
case SIGALRM:
|
||||
case SIGINT:
|
||||
case SIGPIPE:
|
||||
restartable = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
/*
|
||||
* This is unpleasant, but I don't know what would be better.
|
||||
* Right now, this "can't happen"
|
||||
*/
|
||||
errx(1, "xsignal_restart: called with signal %d", sig);
|
||||
}
|
||||
|
||||
return(xsignal_restart(sig, func, restartable));
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: progressbar.h,v 1.8 2009/04/12 10:18:52 lukem Exp $ */
|
||||
/* $NetBSD: progressbar.h,v 1.9 2021/01/06 04:43:14 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996-2009 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1996-2021 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
|
@ -68,7 +68,6 @@ int foregroundproc(void);
|
|||
void alarmtimer(int);
|
||||
void progressmeter(int);
|
||||
sigfunc xsignal(int, sigfunc);
|
||||
sigfunc xsignal_restart(int, sigfunc, int);
|
||||
|
||||
#ifndef STANDALONE_PROGRESS
|
||||
void psummary(int);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ssl.c,v 1.8 2019/04/07 00:44:54 christos Exp $ */
|
||||
/* $NetBSD: ssl.c,v 1.9 2021/01/06 04:43:14 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998-2004 Dag-Erling Coïdan Smørgrav
|
||||
|
@ -34,7 +34,7 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__RCSID("$NetBSD: ssl.c,v 1.8 2019/04/07 00:44:54 christos Exp $");
|
||||
__RCSID("$NetBSD: ssl.c,v 1.9 2021/01/06 04:43:14 lukem Exp $");
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
|
@ -356,6 +356,10 @@ fetch_wait(struct fetch_connect *conn, ssize_t rlen, struct timeval *timeout)
|
|||
if (quit_time > 0) {
|
||||
gettimeofday(&now, NULL);
|
||||
if (!timercmp(timeout, &now, >)) {
|
||||
fprintf(ttyout, "\r\n%s: transfer aborted"
|
||||
" because stalled for %lu sec.\r\n",
|
||||
getprogname(), (unsigned long)quit_time);
|
||||
errno = ETIMEDOUT;
|
||||
conn->iserr = ETIMEDOUT;
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* $NetBSD: version.h,v 1.91 2020/07/18 03:00:37 lukem Exp $ */
|
||||
/* $NetBSD: version.h,v 1.92 2021/01/06 04:43:14 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999-2020 The NetBSD Foundation, Inc.
|
||||
* Copyright (c) 1999-2021 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
|
@ -34,5 +34,5 @@
|
|||
#endif
|
||||
|
||||
#ifndef FTP_VERSION
|
||||
#define FTP_VERSION "20200718"
|
||||
#define FTP_VERSION "20210106"
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue