svn commit: r208029 - stable/7/contrib/telnet/telnet
Jilles Tjoelker
jilles at FreeBSD.org
Thu May 13 15:28:35 UTC 2010
Author: jilles
Date: Thu May 13 15:28:34 2010
New Revision: 208029
URL: http://svn.freebsd.org/changeset/base/208029
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/7/contrib/telnet/telnet/commands.c
stable/7/contrib/telnet/telnet/externs.h
stable/7/contrib/telnet/telnet/network.c
stable/7/contrib/telnet/telnet/sys_bsd.c
stable/7/contrib/telnet/telnet/telnet.c
stable/7/contrib/telnet/telnet/terminal.c
Directory Properties:
stable/7/contrib/telnet/ (props changed)
Modified: stable/7/contrib/telnet/telnet/commands.c
==============================================================================
--- stable/7/contrib/telnet/telnet/commands.c Thu May 13 12:08:11 2010 (r208028)
+++ stable/7/contrib/telnet/telnet/commands.c Thu May 13 15:28:34 2010 (r208029)
@@ -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/7/contrib/telnet/telnet/externs.h
==============================================================================
--- stable/7/contrib/telnet/telnet/externs.h Thu May 13 12:08:11 2010 (r208028)
+++ stable/7/contrib/telnet/telnet/externs.h Thu May 13 15:28:34 2010 (r208029)
@@ -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/7/contrib/telnet/telnet/network.c
==============================================================================
--- stable/7/contrib/telnet/telnet/network.c Thu May 13 12:08:11 2010 (r208028)
+++ stable/7/contrib/telnet/telnet/network.c Thu May 13 15:28:34 2010 (r208029)
@@ -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/7/contrib/telnet/telnet/sys_bsd.c
==============================================================================
--- stable/7/contrib/telnet/telnet/sys_bsd.c Thu May 13 12:08:11 2010 (r208028)
+++ stable/7/contrib/telnet/telnet/sys_bsd.c Thu May 13 15:28:34 2010 (r208029)
@@ -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/7/contrib/telnet/telnet/telnet.c
==============================================================================
--- stable/7/contrib/telnet/telnet/telnet.c Thu May 13 12:08:11 2010 (r208028)
+++ stable/7/contrib/telnet/telnet/telnet.c Thu May 13 15:28:34 2010 (r208029)
@@ -146,7 +146,6 @@ unsigned char telopt_environ = TELOPT_NE
#endif
jmp_buf toplevel;
-jmp_buf peerdied;
int flushline;
int linemode;
Modified: stable/7/contrib/telnet/telnet/terminal.c
==============================================================================
--- stable/7/contrib/telnet/telnet/terminal.c Thu May 13 12:08:11 2010 (r208028)
+++ stable/7/contrib/telnet/telnet/terminal.c Thu May 13 15:28:34 2010 (r208029)
@@ -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-stable
mailing list