Subject: [pkg/26351] Re: CVS commit: src/usr.bin/ftp
To: None <lukem@netbsd.org>
From: Ognyan Kulev <ogi@fmi.uni-sofia.bg>
List: source-changes
Date: 07/20/2004 16:28:26
This is a multi-part message in MIME format.
--------------030200030600090404020903
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

Luke Mewburn wrote:
> Module Name:	src
> Committed By:	lukem
> Date:		Tue Jul 20 10:40:24 UTC 2004
> 
> Modified Files:
> 	src/usr.bin/ftp: cmds.c fetch.c ftp.c ftp_var.h main.c util.c version.h
> 
> Log Message:
> If an ftp auto-fetch transfer is interrupted by SIGINT (usually ^C),
> exit with 130 instead of 1 (or rarely, 0).
> This allows an ftp auto-fetch in a shell loop to correctly terminate the loop.
> Should fix PR [pkg/26351], and possibly others.
> 
> 
> To generate a diff of this commit:
> cvs rdiff -r1.105 -r1.106 src/usr.bin/ftp/cmds.c
> cvs rdiff -r1.147 -r1.148 src/usr.bin/ftp/fetch.c
> cvs rdiff -r1.125 -r1.126 src/usr.bin/ftp/ftp.c
> cvs rdiff -r1.66 -r1.67 src/usr.bin/ftp/ftp_var.h
> cvs rdiff -r1.88 -r1.89 src/usr.bin/ftp/main.c
> cvs rdiff -r1.115 -r1.116 src/usr.bin/ftp/util.c
> cvs rdiff -r1.36 -r1.37 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.

(All my tests are on Debian GNU/Linux testing.)

I've applied these diffs to bootstrap, ftp returns exit code 130 when 
it's interrupted, but shell continues to loop.  So exit code greater 
than 128 is not enough alone.

So when SIGINT is received, the only correct way to handle it is to set 
SIGINT to SIG_DFL and raise SIGINT.  Patch is attached that do this and 
that works.  (I'm not sure if sigaction should be used.)

And there is one more question: is SIGINT enough?  Looking at list of 
signals[1], those that terminate process (without core dump) and are 
usually issued by user are SIGHUP, SIGINT and SIGTERM.  I think all 
these should be handled this way.

[1] http://www.opengroup.org/onlinepubs/009695399/basedefs/signal.h.html

Regards,
ogi

--------------030200030600090404020903
Content-Type: text/x-patch;
 name="main-ogi.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="main-ogi.diff"

--- main.c.lukem	2004-07-20 16:20:21.000000000 +0300
+++ main.c	2004-07-20 16:19:24.000000000 +0300
@@ -498,20 +498,32 @@ main(int argc, char *argv[])
 	if (argc > 0) {
 		if (isupload) {
 			rval = auto_put(argc, argv, upload_path);
-			exit(rval);
+			if (rval != EXIT_SIGINT)
+				exit(rval);
+			else {
+				signal(SIGINT, SIG_DFL);
+				raise(SIGINT);
+			}
 		} else if (strchr(argv[0], ':') != NULL
 			    && ! isipv6addr(argv[0])) {
 			rval = auto_fetch(argc, argv);
-			if (rval >= 0)		/* -1 == connected and cd-ed */
-				exit(rval);
+			if (rval >= 0) {	/* -1 == connected and cd-ed */
+				if (rval != EXIT_SIGINT)
+					exit(rval);
+				else {
+					signal(SIGINT, SIG_DFL);
+					raise(SIGINT);
+				}
+			}
 		} else {
 			char *xargv[4], *user, *host;
 
 			sigint_raised = 0;
 			if (sigsetjmp(toplevel, 1)) {
-				if (sigint_raised)
-					exit(EXIT_SIGINT);
-				else
+				if (sigint_raised) {
+					signal(SIGINT, SIG_DFL);
+					raise(SIGINT);
+				} else
 					exit(1);
 			}
 			(void)xsignal(SIGINT, intr);

--------------030200030600090404020903--