From c3cbd3311842130ff3f210cdf3288820b7dc9f4f Mon Sep 17 00:00:00 2001 From: lukem Date: Wed, 6 Jan 2021 04:43:14 +0000 Subject: 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 --- include/progressbar.h | 5 ++-- progressbar.c | 70 +++++++-------------------------------------------- 2 files changed, 11 insertions(+), 64 deletions(-) diff --git a/include/progressbar.h b/include/progressbar.h index f627e88..daf382b 100644 --- a/include/progressbar.h +++ b/include/progressbar.h @@ -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); diff --git a/progressbar.c b/progressbar.c index a6218bd..85f1ecb 100644 --- a/progressbar.c +++ b/progressbar.c @@ -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 #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)); -} -- cgit v1.2.3-56-ge451