Date: Tue, 13 Aug 2002 11:53:53 -0400 (EDT) From: Keith White <Keith.White@site.uottawa.ca> To: Ian Dowse <iedowse@FreeBSD.org> Cc: kwhite@uottawa.ca, <freebsd-bugs@FreeBSD.org>, <bug-followup@FreeBSD.org> Subject: Re: bin/20042: "rsh -t" doesn't timeout if rcmd(3) never returns [patch included] Message-ID: <Pine.GSO.4.44.0208131142590.29347-100000@siteao.site.uottawa.ca> In-Reply-To: <200208092350.g79No5oZ096260@freefall.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, 9 Aug 2002, Ian Dowse wrote: > Synopsis: "rsh -t" doesn't timeout if rcmd(3) never returns [patch included] > > State-Changed-From-To: open->feedback > State-Changed-By: iedowse > State-Changed-When: Fri Aug 9 16:44:37 PDT 2002 > State-Changed-Why: > > It isn't safe to call errx() from a signal handler - would you > like to suggest a better patch that uses only functions that are > documented in sigaction(2) as being safe to call? You can also > remove the #ifdef's from around the new code. > > http://www.freebsd.org/cgi/query-pr.cgi?pr=20042 My initial bug report didn't include an easy way to demonstrate the problem. This will. server# kill -STOP `cat /var/run/inetd.pid` client$ rsh -t 5 server who ...wait, rsh doesn't return after 5 seconds... after patching rsh client$ rsh -t 5 server who timeout reached before connection completed. server# kill -CONT `cat /var/run/inetd.pid` The following patch should fulfill the criteria: ---cut here--- --- rsh.c.orig Sun Mar 4 04:01:45 2001 +++ rsh.c Tue Aug 13 09:57:06 2002 @@ -89,6 +89,7 @@ char *copyargs __P((char **)); void sendsig __P((int)); +void connect_timeout __P((int)); void talk __P((int, long, pid_t, int, int)); void usage __P((void)); @@ -283,8 +284,22 @@ &rfd2, family); } #else + +/* + * it is possible that the rcmd() will never return -- perhaps because the + * remote machine is hung -- so add an alarm just in case + */ + + if (timeout) { + signal(SIGALRM, connect_timeout); + alarm(timeout); + } rem = rcmd_af(&host, sp->s_port, pw->pw_name, user, args, &rfd2, family); + if (timeout) { + signal(SIGALRM, SIG_DFL); + alarm(0); + } #endif if (rem < 0) @@ -446,6 +461,19 @@ (void)write(1, buf, cc); } } while (FD_ISSET(rfd2, &readfrom) || FD_ISSET(rem, &readfrom)); +} + +void +connect_timeout(sig) + int sig; +{ + char message[] = "timeout reached before connection completed.\n"; +/* + * why not use errx()? -- we're in a signal handler so must restrict ourselves + * to those functions listed in sigaction(2) + */ + write(STDERR_FILENO, message, sizeof(message)-1); + _exit(1); } void ---cut here--- ...keith -- Keith White, EITI/SITE, University of Ottawa kwhite@site.uottawa.ca [+1 613 562 5800 x6681] FAX [+1 613 562 5664] To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.GSO.4.44.0208131142590.29347-100000>