Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!uwm.edu!uakari.primate.wisc.edu!caesar.cs.montana.edu!ogicse!hakanson From: hakanson@ogicse.ogc.edu (Marion Hakanson) Newsgroups: comp.lang.perl Subject: Re: Problems using ptys in perl. Message-ID: <7115@ogicse.ogc.edu> Date: 4 Feb 90 20:55:03 GMT References: <2276@uvaarpa.virginia.edu> Reply-To: hakanson@ogicse.UUCP (Marion Hakanson) Organization: Oregon Graduate Institute (formerly OGC), Beaverton, OR Lines: 75 In article <2276@uvaarpa.virginia.edu> kayvan@mrspoc.transact.com writes: >I wrote the following function to snatch pty pairs from the system, >which I put in pty.pl: >. . . >I then used it in a perl test of ptys and got strange results. >. . . > Ready> > abcd > Sent: 'abcd' > Got: 'I got abcd' > Child > Child > foo > Child > Sent: 'foo' > Got: 'I got I got abcd' > Child >. . . >Looking at the code below, can anyone tell me what I'm doing wrong? >(Or is this a bug?) >. . . ># Copyright (C) 1990 Kayvan Sylvan # ># Copying permitted under the terms of the GNU General Public License. # I was hoping someone else would answer this, but I guess everyone thinks I'm the "Perl-pty" expert. Hah! Anyway, I don't think this is a problem with pty's. It somewhat resembles the problem I had when I first tried using pty's, and I tracked it down to not being related to pty's at all. If you rewrote your program to use just plain pipes, you may see the same behavior (I recommend that you try it). The problem I have seen comes from "forked" file-handles, in my opinion. It does not affect all systems -- for example, 4.2bsd and 4.3bsd does not exhibit the behavior, but SunOS-4.0.3 does (in my tests). I recently had an insight into what may be the cause, for SunOS-4, anyway. I suspect that one would see the same problem if the file-handles were forked using "vfork" instead of plain fork. And in fact, Larry has done things so Perl cleverly avoids using vfork if the child is not going to immediately do an exec (or otherwise share some data which shouldn't be shared) -- instead he uses plain fork, which in a "normal" Unix system makes a complete copy of the parent process' address space for the child to run in. But, some modern Unix systems don't have a vfork anymore -- instead these systems with modern memory-management (with hardware support) do a copy-on-write fork. Thus the fork takes place, and no copy is done until the child tries to write to its copy of the data. It's really quite efficient, since you never have to copy anything until you actually need a separate copy, and you only copy those pieces (pages, usually) which are necessary. But I think that Perl operates under the assumption that after a fork (as opposed to a vfork), none of its data structures are shared between the parent and child. I haven't worked out the nitty-gritty details, but the behavior I have seen can be described as the parent writing to a forked filehandle, after which the parent sees both what it wrote to that filehandle as well as what the child wrote to it. In other words, the data gets duplicated, instead of being consumed by (just) the child. I'm not sure that you are seeing the same thing, but it looks similar. My intuition tells me that the implementation of the stdio subsystem is at fault here, but I have not examined any source code to confirm that hypothesis. Larry, I must say that this is one issue that makes me wish Perl used Unix file descriptors instead of C file pointers, but I certainly don't blame you for wanting to avoid implementing your own buffered I/O system. But it certainly would make forking a little less painful. -- Marion Hakanson Domain: hakanson@cse.ogi.edu UUCP : {hp-pcd,tektronix}!ogicse!hakanson