svn commit: r207758 - stable/8/contrib/telnet/telnet

Jilles Tjoelker jilles at FreeBSD.org
Fri May 7 20:58:51 UTC 2010


Author: jilles
Date: Fri May  7 20:58:50 2010
New Revision: 207758
URL: http://svn.freebsd.org/changeset/base/207758

Log:
  MFC r207449: telnet: Fix infinite loop if local output generates SIGPIPE.
  
  Instead of catching SIGPIPE and jumping out of the signal handler with
  longjmp, ignore it and handle write errors to the local output by exiting
  from there. I have changed the error message to mention the local output
  instead of NetBSD's wrong "Connection closed by foreign host". Write errors
  to the network were already handled by exiting immediately and this now
  applies to EPIPE too.
  
  The code assumed that SIGPIPE could only be generated by the network
  connection; if it was generated by the local output, it would longjmp out of
  the signal handler and write an error message which caused another SIGPIPE.
  
  PR:		19773
  Obtained from:	NetBSD

Modified:
  stable/8/contrib/telnet/telnet/commands.c
  stable/8/contrib/telnet/telnet/externs.h
  stable/8/contrib/telnet/telnet/network.c
  stable/8/contrib/telnet/telnet/sys_bsd.c
  stable/8/contrib/telnet/telnet/telnet.c
  stable/8/contrib/telnet/telnet/terminal.c
Directory Properties:
  stable/8/contrib/telnet/   (props changed)

Modified: stable/8/contrib/telnet/telnet/commands.c
==============================================================================
--- stable/8/contrib/telnet/telnet/commands.c	Fri May  7 20:46:22 2010	(r207757)
+++ stable/8/contrib/telnet/telnet/commands.c	Fri May  7 20:58:50 2010	(r207758)
@@ -2491,8 +2491,7 @@ tn(int argc, char *argv[])
 	env_export("USER");
     }
     (void) call(status, "status", "notmuch", 0);
-    if (setjmp(peerdied) == 0)
-	telnet(user);
+    telnet(user); 
     (void) NetClose(net);
     ExitString("Connection closed by foreign host.\n",1);
     /*NOTREACHED*/

Modified: stable/8/contrib/telnet/telnet/externs.h
==============================================================================
--- stable/8/contrib/telnet/telnet/externs.h	Fri May  7 20:46:22 2010	(r207757)
+++ stable/8/contrib/telnet/telnet/externs.h	Fri May  7 20:58:50 2010	(r207758)
@@ -233,7 +233,6 @@ extern void
     SetNetTrace(char *);	/* Function to change where debugging goes */
 
 extern jmp_buf
-    peerdied,
     toplevel;		/* For error conditions. */
 
 extern void

Modified: stable/8/contrib/telnet/telnet/network.c
==============================================================================
--- stable/8/contrib/telnet/telnet/network.c	Fri May  7 20:46:22 2010	(r207757)
+++ stable/8/contrib/telnet/telnet/network.c	Fri May  7 20:58:50 2010	(r207758)
@@ -158,7 +158,7 @@ netflush(void)
 	    perror(hostname);
 	    (void)NetClose(net);
 	    ring_clear_mark(&netoring);
-	    longjmp(peerdied, -1);
+	    ExitString("Connection closed by foreign host.\n", 1);
 	    /*NOTREACHED*/
 	}
 	n = 0;

Modified: stable/8/contrib/telnet/telnet/sys_bsd.c
==============================================================================
--- stable/8/contrib/telnet/telnet/sys_bsd.c	Fri May  7 20:46:22 2010	(r207757)
+++ stable/8/contrib/telnet/telnet/sys_bsd.c	Fri May  7 20:58:50 2010	(r207758)
@@ -809,14 +809,6 @@ NetNonblockingIO(int fd, int onoff)
  */
 
 /* ARGSUSED */
-static SIG_FUNC_RET
-deadpeer(int sig __unused)
-{
-	setcommandmode();
-	longjmp(peerdied, -1);
-}
-
-/* ARGSUSED */
 SIG_FUNC_RET
 intr(int sig __unused)
 {
@@ -884,7 +876,7 @@ sys_telnet_init(void)
 {
     (void) signal(SIGINT, intr);
     (void) signal(SIGQUIT, intr2);
-    (void) signal(SIGPIPE, deadpeer);
+    (void) signal(SIGPIPE, SIG_IGN);
 #ifdef	SIGWINCH
     (void) signal(SIGWINCH, sendwin);
 #endif

Modified: stable/8/contrib/telnet/telnet/telnet.c
==============================================================================
--- stable/8/contrib/telnet/telnet/telnet.c	Fri May  7 20:46:22 2010	(r207757)
+++ stable/8/contrib/telnet/telnet/telnet.c	Fri May  7 20:58:50 2010	(r207758)
@@ -146,7 +146,6 @@ unsigned char telopt_environ = TELOPT_NE
 #endif
 
 jmp_buf	toplevel;
-jmp_buf	peerdied;
 
 int	flushline;
 int	linemode;

Modified: stable/8/contrib/telnet/telnet/terminal.c
==============================================================================
--- stable/8/contrib/telnet/telnet/terminal.c	Fri May  7 20:46:22 2010	(r207757)
+++ stable/8/contrib/telnet/telnet/terminal.c	Fri May  7 20:58:50 2010	(r207758)
@@ -111,7 +111,8 @@ init_terminal(void)
 }
 
 /*
- *		Send as much data as possible to the terminal.
+ *		Send as much data as possible to the terminal, else exits if
+ *		it encounters a permanent failure when writing to the tty.
  *
  *		Return value:
  *			-1: No useful work done, data waiting to go out.
@@ -152,8 +153,19 @@ ttyflush(int drop)
 	}
 	ring_consumed(&ttyoring, n);
     }
-    if (n < 0)
+    if (n < 0) {
+	if (errno == EAGAIN || errno == EINTR) {
+	    return -1;
+	} else {
+	    ring_consumed(&ttyoring, ring_full_count(&ttyoring));
+	    setconnmode(0);
+	    setcommandmode();
+	    NetClose(net);
+	    fprintf(stderr, "Write error on local output.\n");
+	    exit(1);
+	}
 	return -1;
+    }
     if (n == n0) {
 	if (n0)
 	    return -1;


More information about the svn-src-all mailing list