Article 9920 of comp.lang.perl:
Xref: feenix.metronet.com comp.lang.perl:9920 comp.sys.sun.apps:4147 comp.sys.sun.misc:7363
Path: feenix.metronet.com!news.ecn.bgu.edu!usenet.ins.cwru.edu!howland.reston.ans.net!cs.utexas.edu!swrinde!sgiblab!bridge2!alantec!alantec!paul
From:
[email protected] (G. Paul Ziemba)
Newsgroups: comp.lang.perl,comp.sys.sun.apps,comp.sys.sun.misc
Subject: Re: Problem with passwd
Message-ID: <
[email protected]>
Date: 18 Jan 94 23:31:51 GMT
References: <
[email protected]>
Organization: Alantec, San Jose, CA
Lines: 111
NNTP-Posting-Host: alantec.alantec.com
[email protected] (Dale Worley) writes:
>(All of this is using Perl 4.35 under SunOS 4.1.1.)
>[chat2 doesn't seem to give exec-ed program a tty]
>says "Input not a tty". My guess is that passwd is doing some fairly
>sophisticated checks to see that it is being run in the "ordinary" way.
>However, it's not impossible to fake it out -- I can run passwd in a shell
>window under Gnu Emacs quite easily. So what is going wrong?
>Does anyone know what I'm missing? What changes to chat2 will solve this
>little problem?
Interestingly (to me, anyway), I encountered this very same problem
last week. I am running perl 4.0.36 on SunOS 4.1.2.
At first I thought, surely chat2 is doing the right thing. However,
I open_proc-ed "cat /dev/tty", and cat complained about "no tty".
I looked at the chat2.pl code, and I could not understand why the
slave side of the pty did not become the controlling terminal.
However, I did make a one-line change to chat2'open_proc (below)
that seems to fix it.
I would dearly love for someone more knowledgeable to explain why
chat2 was not doing the right thing, and whether my change is an
appropriate one.
~!paul
## chat.pl: chat with a server
## V2.01.alpha.7 91/06/16
## Randal L. Schwartz
[deleted]
## $handle = &chat'open_proc("command","arg1","arg2",...);
## opens a /bin/sh on a pseudo-tty
sub open_proc { ## public
local(@cmd) = @_;
*S = ++$next;
local(*TTY) = "__TTY" . time;
local($pty,$tty) = &_getpty(S,TTY);
die "Cannot find a new pty" unless defined $pty;
local($pid) = fork;
die "Cannot fork: $!" unless defined $pid;
unless ($pid) {
close STDIN; close STDOUT; close STDERR;
setpgrp(0,$$);
if (open(DEVTTY, "/dev/tty")) {
ioctl(DEVTTY,0x20007471,0); # XXX s/b &TIOCNOTTY
close DEVTTY;
}
open(STDIN,"<&TTY");
open(STDOUT,">&TTY");
open(STDERR,">&STDOUT");
die "Oops" unless fileno(STDERR) == 2; # sanity
close(S);
##################################################
# add this to force controlling terminal
##################################################
close DEVTTY if (open(DEVTTY, "+>$tty")); # force ctl term
##################################################
##################################################
exec @cmd;
die "Cannot exec @cmd: $!";
}
close(TTY);
$next; # return symbol for switcharound
}
# ($pty,$tty) = $chat'_getpty(PTY,TTY):
# internal procedure to get the next available pty.
# opens pty on handle PTY, and matching tty on handle TTY.
# returns undef if can't find a pty.
sub _getpty { ## private
local($_PTY,$_TTY) = @_;
$_PTY =~ s/^([^']+)$/(caller)[$[]."'".$1/e;
$_TTY =~ s/^([^']+)$/(caller)[$[]."'".$1/e;
local($pty,$tty);
for $bank (112..127) {
next unless -e sprintf("/dev/pty%c0", $bank);
for $unit (48..57) {
$pty = sprintf("/dev/pty%c%c", $bank, $unit);
open($_PTY,"+>$pty") || next;
select((select($_PTY), $| = 1)[0]);
($tty = $pty) =~ s/pty/tty/;
open($_TTY,"+>$tty") || next;
select((select($_TTY), $| = 1)[0]);
system "stty nl>$tty";
return ($pty,$tty);
}
}
undef;
}
--
Paul Ziemba, software archaeologist:
[email protected] alantec!paul
"The reasonable man adapts himself to the world; the unreasonable one
persists in trying to adapt the world to himself. Therefore, all progress
depends on the unreasonable man." - George Bernard Shaw