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: paul@alantec.com (G. Paul Ziemba) Newsgroups: comp.lang.perl,comp.sys.sun.apps,comp.sys.sun.misc Subject: Re: Problem with passwd Message-ID: Date: 18 Jan 94 23:31:51 GMT References: <2hh6n7$8h1@village.com> Organization: Alantec, San Jose, CA Lines: 111 NNTP-Posting-Host: alantec.alantec.com worley@village.com (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: paul@alantec.com 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