Module Name:    src
Committed By:   lukem
Date:           Wed Jan  6 04:43:14 UTC 2021

Modified Files:
        src/usr.bin/ftp: ftp.c progressbar.c progressbar.h ssl.c version.h

Log Message:
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


To generate a diff of this commit:
cvs rdiff -u -r1.170 -r1.171 src/usr.bin/ftp/ftp.c
cvs rdiff -u -r1.23 -r1.24 src/usr.bin/ftp/progressbar.c
cvs rdiff -u -r1.8 -r1.9 src/usr.bin/ftp/progressbar.h src/usr.bin/ftp/ssl.c
cvs rdiff -u -r1.91 -r1.92 src/usr.bin/ftp/version.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/ftp/ftp.c
diff -u src/usr.bin/ftp/ftp.c:1.170 src/usr.bin/ftp/ftp.c:1.171
--- src/usr.bin/ftp/ftp.c:1.170	Sat Jul 11 02:19:31 2020
+++ src/usr.bin/ftp/ftp.c	Wed Jan  6 04:43:14 2021
@@ -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 *bu
 		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;
 			}

Index: src/usr.bin/ftp/progressbar.c
diff -u src/usr.bin/ftp/progressbar.c:1.23 src/usr.bin/ftp/progressbar.c:1.24
--- src/usr.bin/ftp/progressbar.c:1.23	Sat Jun 22 23:40:33 2019
+++ src/usr.bin/ftp/progressbar.c	Wed Jan  6 04:43:14 2021
@@ -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));
-}

Index: src/usr.bin/ftp/progressbar.h
diff -u src/usr.bin/ftp/progressbar.h:1.8 src/usr.bin/ftp/progressbar.h:1.9
--- src/usr.bin/ftp/progressbar.h:1.8	Sun Apr 12 10:18:52 2009
+++ src/usr.bin/ftp/progressbar.h	Wed Jan  6 04:43:14 2021
@@ -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);
Index: src/usr.bin/ftp/ssl.c
diff -u src/usr.bin/ftp/ssl.c:1.8 src/usr.bin/ftp/ssl.c:1.9
--- src/usr.bin/ftp/ssl.c:1.8	Sun Apr  7 00:44:54 2019
+++ src/usr.bin/ftp/ssl.c	Wed Jan  6 04:43:14 2021
@@ -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, s
 		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;
 			}

Index: src/usr.bin/ftp/version.h
diff -u src/usr.bin/ftp/version.h:1.91 src/usr.bin/ftp/version.h:1.92
--- src/usr.bin/ftp/version.h:1.91	Sat Jul 18 03:00:37 2020
+++ src/usr.bin/ftp/version.h	Wed Jan  6 04:43:14 2021
@@ -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

Reply via email to