peebles@mips.COM (Andrew Peebles) (03/16/90)
Why can't I seem to run perl attached to the slave side of a psuedo tty? I have a program that creates a ptty, and fork/execs a perl script with its stdin, stdout, and stderr duped to the slave half of the ptty. My wish is to make the perl script think its getting input from stdin and producing output on stdout, when its this parent process that is doing the work. Perl seems to be doing something to its stdin and stdout file descriptors that prevents such control. Anyone done this sort of thing before? How? -- Andrew Peebles {ames,prls,pyramid,decwrl}!mips!peebles or peebles@mips.com MIPS Computer Systems, 930 Arques, Sunnyvale, CA 94086, (408) 991-0443 "quote"
hakanson@ogicse.ogi.edu (Marion Hakanson) (03/17/90)
It's not exactly what you described, but should get you started. This must be the third or fourth time I've posted this fragment. PTY's are tricky, even if you aren't using Perl. If you want the middle of the "pipeline" to be a Perl routine, just replace the "exec 'tr'..." with your code. =============ptytst5.pl=========== #!/usr/bin/perl # Pseudo-tty test program -- 89/12/01 # Marion Hakanson (hakanson@cse.ogi.edu) # Oregon Graduate Institute of Science and Technology do 'getpty.pl'; die "$@, aborted" if $@; $MAST = 'MASTER'; $SLAV = 'SLAVE'; ($mast,$slav) = do getpty($MAST,$SLAV); print STDERR "getpty returns '$mast','$slav'\n"; die 'Cannot get pty, aborted' if ($mast eq ''); if ( fork ) { # parent close($SLAV); # not needed if ( fork ) { # still parent open(MASTOUT, "+>&$MAST") || die "Cannot dup $MAST to MASTOUT, aborted"; close($MAST); select(MASTOUT); $| = 1; select(STDOUT); $| = 1; for ($i=0; $i<10; $i++ ) { print MASTOUT "LINE out $i\n" || die "Cannot print to $mast, aborted"; sleep(1); } exit(0); } else { # child 2 open(MASTIN, "+>&$MAST") || die "Cannot dup $MAST to MASTIN, aborted"; close($MAST); while ($mastin = <MASTIN>) { print STDOUT "$$: $mastin"; } exit(0); } } else { # child 1 close($MAST); # not needed open(STDOUT, "+>&$SLAV") || die "Cannot dup $SLAV to STDOUT, aborted"; open(STDIN, "+>&$SLAV") || die "Cannot dup $SLAV to STDIN, aborted"; close($SLAV); select(STDOUT); $| = 1; exec ('tr','A-Z','a-z') || die "Cannot start 'tr', aborted"; } =============end of ptytst5.pl=========== =============getpty.pl========== # # $Id: getpty.pl,v 1.3 90/01/02 17:18:56 hakanson Exp $ # # Perl subroutine to allocate a free pseudo-tty (master/slave pair). # Marion Hakanson (hakanson@cse.ogi.edu) # Oregon Graduate Institute of Science and Technology sub getpty { local ($MASTER,$SLAVE) = @_; local ($master,$slave); $master = ''; $slave = ''; pty: while ( </dev/pty*> ) { # print STDERR "trying '$_'\n"; $master = $_; unless ( open($MASTER,"+>$master") ) { # print STDERR "open failed: $master\n"; $master = ''; next pty; } s/pty/tty/; $slave = $_; last pty if ( open($SLAVE,"+>$slave") ); # print STDERR "open failed: $slave\n"; close($MASTER); $master = ''; $slave = ''; } # print STDERR "getpty returning '$master','$slave'\n"; ($master,$slave); } =============end of getpty.pl========== -- Marion Hakanson Domain: hakanson@cse.ogi.edu UUCP : {hp-pcd,tektronix}!ogicse!hakanson
peebles@ling.Berkeley.EDU (Andrew Peebles) (03/17/90)
> > It's not exactly what you described, but should get you started. This > must be the third or fourth time I've posted this fragment. PTY's are > tricky, even if you aren't using Perl. If you want the middle of the > "pipeline" to be a Perl routine, just replace the "exec 'tr'..." with > your code. > > -- > Marion Hakanson Domain: hakanson@cse.ogi.edu > UUCP : {hp-pcd,tektronix}!ogicse!hakanson Nice code, I'll use it elsewhere, but this does not really address my particular problem. I don't have access to the parent's code (I do but I don't want to have to) to play w/ its ptys. Since emacs uses a pty when you have an emacs shell, you can't (or at least I can't) run a perl script from w/in an emacs shell. This behavior is what I'm asking about, i.e. can YOU run a perl script from w/in an emacs shell? Can you run `perl -d' on this same script from w/in an emacs shell? Andrew Peebles {ames,prls,pyramid,decwrl}!mips!peebles or peebles@mips.com MIPS Computer Systems, 930 Arques, Sunnyvale, CA 94086, (408) 991-0443 "quote"
inc@tc.fluke.COM (Gary Benson) (03/20/90)
The question was raised about using perl-d inside emacs. I thought I had a way, but I don't. I regularly run perl scripts on emacs buffers, and it works really slick. I set a mark, advance to the area in question, and fast-filter-region {the script}. This works for the stuff I normally do, but when I set the -d, whoo-boy! I got knocked into the 0-zone. It also fails if I set up a shell internal to emacs. I was hoping the debug messages would go to the shell window, but alas no. STDOUT it is, and I am not sufficiently emacs conversant to change that. I suppose one ramification is that any perl script that is talking to STDOUT will fail inside emacs. -- Gary Benson -=[ S M I L E R ]=- -_-_-_-inc@fluke.tc.com_-_-_-_-_-_-_-_-_- The most evident characteristic of God is an inordinate fondness for beetles. -J.B.S. Haldane
lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (03/20/90)
In article <1990Mar19.235021.19961@tc.fluke.COM> inc@tc.fluke.COM (Gary Benson) writes:
: The question was raised about using perl-d inside emacs.
:
: I thought I had a way, but I don't. I regularly run perl scripts on emacs
: buffers, and it works really slick. I set a mark, advance to the area in
: question, and fast-filter-region {the script}. This works for the stuff I
: normally do, but when I set the -d, whoo-boy! I got knocked into the 0-zone.
:
: It also fails if I set up a shell internal to emacs. I was hoping the debug
: messages would go to the shell window, but alas no. STDOUT it is, and I am
: not sufficiently emacs conversant to change that. I suppose one ramification
: is that any perl script that is talking to STDOUT will fail inside emacs.
Is the problem simply that perldb.pl can't open /dev/tty? There are two
lines that say
open(IN,"/dev/tty"); # so we don't dingle stdin
open(OUT,">/dev/tty"); # so we don't dongle stdout
Try changing them to
open(IN, "</dev/tty") || open(IN, "<&STDIN"); # so we don't dingle stdin
open(OUT,">/dev/tty") || open(OUT,">&STDOUT"); # so we don't dongle stdout
and see if that makes any difference.
Larry