NetBSD Problem Report #11733
Received: (qmail 19737 invoked from network); 14 Dec 2000 09:38:45 -0000
Message-Id: <200012140941.BAA26899@zen.quick.com.au>
Date: Thu, 14 Dec 2000 01:41:56 -0800 (PST)
From: "Simon J. Gerraty" <sjg@quick.com.au>
Reply-To: sjg@netbsd.org
To: gnats-bugs@gnats.netbsd.org
Subject: rcmd(1) always asks for stderr channel
X-Send-Pr-Version: 3.95
>Number: 11733
>Category: bin
>Synopsis: rcmd(1) always asks for stderr channel
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Dec 14 09:39:00 +0000 2000
>Closed-Date:
>Last-Modified: Sat Jan 05 00:10:42 +0000 2002
>Originator: Simon J. Gerraty
>Release: 20001207
>Organization:
Zen Programming...
>Environment:
System: NetBSD zen.quick.com.au 1.4.2 NetBSD 1.4.2 (ZEN) #2: Wed Mar 22 01:07:26 EST 2000 root@zen.quick.com.au:/u3/NetBSD/1.4.X/src/sys/arch/i386/compile/ZEN i386
>Description:
When rcp calls rcmd(3) is asks for no stderr channel.
This is ignored by rcmd(1) and probably any other rsh thing,
we always ask rshd for a 2nd channel.
This causes interoperability problems.
>How-To-Repeat:
>Fix:
>Release-Note:
>Audit-Trail:
From: "Simon J. Gerraty" <sjg@quick.com.au>
To: gnats-bugs@netbsd.org
Cc:
Subject: Re: bin/11733: rcmd(1) always asks for stderr channel
Date: Tue, 26 Dec 2000 01:12:10 -0800
The essential problem with the way rcmd(1) and rcmd(3) interract is
that there is no way to communicate to rcmd(1) that no stderr channel
should be established - eg for rcp(1).
The following patch provides a fix for PR 11733 but
a/ only solves it for rcmd(1), not replacement commands.
b/ might be better if resrcmd(3) used putenv("RCMD_NO_FD2=1") rather
than pass a new option (-2) to rcmd_cmd. In fact that was my first
inclination.
--sjg
Index: lib/libc/net/rcmd.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libc/net/rcmd.c,v
retrieving revision 1.44
diff -u -p -r1.44 rcmd.c
--- lib/libc/net/rcmd.c 2000/07/07 08:03:39 1.44
+++ lib/libc/net/rcmd.c 2000/12/26 09:00:28
@@ -487,8 +487,9 @@ rshrcmd(ahost, rport, locuser, remuser,
execlp(rshcmd, p ? p + 1 : rshcmd, "-c", cmd, NULL);
} else {
p = strrchr(rshcmd, '/');
- execlp(rshcmd, p ? p + 1 : rshcmd, *ahost, "-l",
- remuser, cmd, NULL);
+ execlp(rshcmd, p ? p + 1 : rshcmd, *ahost,
+ (fd2p) ? "-l" : "-2l",
+ remuser, cmd, NULL);
}
warn("rshrcmd: exec %s", rshcmd);
_exit(1);
Index: usr.bin/rsh/rsh.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/rsh/rsh.c,v
retrieving revision 1.13
diff -u -p -r1.13 rsh.c
--- usr.bin/rsh/rsh.c 2000/01/31 14:19:34 1.13
+++ usr.bin/rsh/rsh.c 2000/12/26 09:00:29
@@ -88,7 +88,7 @@ void warning __P((const char *, ...));
* rsh - remote shell
*/
extern char *__progname; /* XXX */
-int remerr;
+int *remerrp;
static int sigs[] = { SIGINT, SIGTERM, SIGQUIT };
@@ -113,6 +113,7 @@ main(argc, argv)
struct passwd *pw;
struct servent *sp;
sigset_t oset, nset;
+ int fd2;
#ifdef IN_RCMD
char *locuser = 0, *loop;
@@ -125,7 +126,8 @@ main(argc, argv)
argoff = asrsh = dflag = nflag = 0;
one = 1;
host = user = NULL;
-
+ remerrp = &fd2;
+
#ifndef IN_RCMD
/*
* If called as something other than "rsh" use it as the host name,
@@ -145,6 +147,9 @@ main(argc, argv)
}
#ifdef IN_RCMD
+ if (getenv("RCMD_NO_FD2") != NULL)
+ remerrp = NULL;
+
if ((loop = getenv("RCMD_LOOP")) && strcmp(loop, "YES") == 0)
warnx("rcmd appears to be looping!");
@@ -152,24 +157,24 @@ main(argc, argv)
# ifdef KERBEROS
# ifdef CRYPT
-# define OPTIONS "8KLdek:l:nu:wx"
+# define OPTIONS "28KLdek:l:nu:wx"
# else
-# define OPTIONS "8KLdek:l:nu:w"
+# define OPTIONS "28KLdek:l:nu:w"
# endif
# else
-# define OPTIONS "8KLdel:nu:w"
+# define OPTIONS "28KLdel:nu:w"
# endif
#else /* IN_RCMD */
# ifdef KERBEROS
# ifdef CRYPT
-# define OPTIONS "8KLdek:l:nwx"
+# define OPTIONS "28KLdek:l:nwx"
# else
-# define OPTIONS "8KLdek:l:nw"
+# define OPTIONS "28KLdek:l:nw"
# endif
# else
-# define OPTIONS "8KLdel:nw"
+# define OPTIONS "28KLdel:nw"
# endif
#endif /* IN_RCMD */
@@ -181,6 +186,9 @@ main(argc, argv)
err(1, "malloc");
while ((ch = getopt(argc - argoff, argv + argoff, OPTIONS)) != -1)
switch(ch) {
+ case '2':
+ remerrp = NULL;
+ break;
case 'K':
#ifdef KERBEROS
use_kerberos = 0;
@@ -306,10 +314,10 @@ try_connect:
#ifdef CRYPT
if (doencrypt)
rem = krcmd_mutual(&host, sp->s_port, user, args,
- &remerr, dest_realm, &cred, schedule);
+ remerrp, dest_realm, &cred, schedule);
else
#endif
- rem = krcmd(&host, sp->s_port, user, args, &remerr,
+ rem = krcmd(&host, sp->s_port, user, args, remerrp,
dest_realm);
if (rem < 0) {
use_kerberos = 0;
@@ -331,7 +339,7 @@ try_connect:
rem = rcmd_af(&host, sp->s_port,
#endif
name,
- user, args, &remerr, PF_UNSPEC);
+ user, args, remerrp, PF_UNSPEC);
}
#else /* KERBEROS */
@@ -340,20 +348,21 @@ try_connect:
#else
rem = rcmd_af(&host, sp->s_port,
#endif
- name, user, args, &remerr, PF_UNSPEC);
+ name, user, args, remerrp, PF_UNSPEC);
#endif /* KERBEROS */
(void)free(name);
if (rem < 0)
exit(1);
- if (remerr < 0)
+ if (remerrp != NULL && *remerrp < 0)
errx(1, "can't establish stderr");
if (dflag) {
if (setsockopt(rem, SOL_SOCKET, SO_DEBUG, &one,
sizeof(one)) < 0)
warn("setsockopt remote");
- if (setsockopt(remerr, SOL_SOCKET, SO_DEBUG, &one,
+ if (remerrp != NULL &&
+ setsockopt(*remerrp, SOL_SOCKET, SO_DEBUG, &one,
sizeof(one)) < 0)
warn("setsockopt stderr");
}
@@ -387,7 +396,8 @@ try_connect:
if (!doencrypt)
#endif
{
- (void)ioctl(remerr, FIONBIO, &one);
+ if (remerrp)
+ (void)ioctl(*remerrp, FIONBIO, &one);
(void)ioctl(rem, FIONBIO, &one);
}
@@ -451,7 +461,8 @@ talk(nflag, oset, pid, rem)
if (!nflag && pid == 0) {
- (void)close(remerr);
+ if (remerrp)
+ (void)close(*remerrp);
fdp->events = POLLOUT|POLLNVAL|POLLERR|POLLHUP;
fdp->fd = rem;
@@ -507,11 +518,15 @@ done:
}
(void) sigprocmask(SIG_SETMASK, oset, NULL);
+ nfds = 0;
fds[0].events = fds[1].events = POLLIN|POLLNVAL|POLLERR|POLLHUP;
- fds[0].fd = remerr;
- fds[1].fd = rem;
+ if (remerrp)
+ fds[nfds++].fd = *remerrp;
+ else
+ fds[1].events = 0;
+ fds[nfds++].fd = rem;
fdp = &fds[0];
- nfds = 2;
+
do {
if (poll(fdp, nfds, INFTIM) == -1) {
if (errno != EINTR)
@@ -537,15 +552,18 @@ sendsig(sig)
{
char signo;
+ if (!remerrp)
+ return;
+
signo = sig;
#ifdef KERBEROS
#ifdef CRYPT
if (doencrypt)
- (void)des_write(remerr, &signo, 1);
+ (void)des_write(*remerrp, &signo, 1);
else
#endif
#endif
- (void)write(remerr, &signo, 1);
+ (void)write(*remerrp, &signo, 1);
}
#ifdef KERBEROS
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2007
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.