Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 13 Aug 2002 09:00:07 -0700 (PDT)
From:      Keith White <Keith.White@site.uottawa.ca>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: bin/20042: "rsh -t" doesn't timeout if rcmd(3) never returns [patch included]
Message-ID:  <200208131600.g7DG07QC020312@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

The following reply was made to PR bin/20042; it has been noted by GNATS.

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]
Date: Tue, 13 Aug 2002 11:53:53 -0400 (EDT)

 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?200208131600.g7DG07QC020312>