From: cgf AT bbc DOT com (Christopher Faylor) Subject: Re: rxvt and latest Ian's changes. 2 Feb 1998 10:38:11 -0800 Message-ID: References: <01BD2FFE DOT 50C15C90 AT gater DOT krystalbank DOT msk DOT ru> Reply-To: gnu-win32-developers AT cygnus DOT com To: cygwin32-developers AT cygnus DOT com In article <199802021727 DOT MAA11798 AT subrogation DOT cygnus DOT com>, Ian Lance Taylor wrote: > From: Sergey Okhapkin > Date: Mon, 2 Feb 1998 17:16:34 +0300 > > Thu Jan 22 18:46:40 1998 Ian Lance Taylor > > * tty.h (class tty): Change slave_handles to int. > * tty.cc (fhandler_tty_slave::open): Check for invalid tty > handles. If this is the first slave, set slave_handles to 2; > otherwise, increment slave_handles. > (fhandler_tty_slave::close): Only close the tty handles if the > slave_handles field drops to 1. > > This changes fools rxvt. Rxvt does the following: > > pty = open("/dev/ptmx"); > slave = ptsname(pty); > lstat(slave); > tty = open(slave); > > Lstat call implemented in cygwin as fd=open(name); fstat(fd); close(fd). > This close call closes input_handle and output_handle in tty structure > (because number of slaves drops to 1) and tty=open(slave) call fails. Ian, > any ideas to fix it? > >The basic problem with implementing ptys on top of pipes is getting >the handles closed appropriately. To make expect work, I needed the >master pty to correctly detect EOF when the slave pty was closed. The >slave was open in a child process, and the master was sleeping in the >read system call. To make this work, I made opening a slave copy the >handles into the process opening the slave. This is done in >fhandler_tty_slave::open. > >Of course, it follows that closing the slave must close the handles, >which happens in fhandler_tty_slave::close when all the slaves are >closed. > >Unfortunately, this does not handle the case of the master opening the >pty, then a child opening the pty, and then closing the pty, and then >another child opening the pty. This works on Unix, but I do not know >how to make it work on Windows. I don't happen to know of any >programs that rely on this behaviour, but there may be some. > >You are running into this problem, because lstat does an open behind >the scenes. I can think of a couple of ways to fix this particular >instance of the problem. > >1) Change stat and lstat to not actually call open on the file. Doing >that seems moderately bogus anyhow. You should be able to call stat >without running out of file descriptors. It does seem that for some >reason Windows before NT 4.0 forces you to call OpenFile, but that >does not need to imply open. This seems like a good idea regardless of whether it actually fixes anything. I think the {f,l,}stat code could stand some minor redesign. >2) Have the fhandler_tty_save::open check whether the master and the >slave are the same process. In this case, there is no need to >duplicate the tty handles at all. We would have to record this in >some other way in the tty structure, perhaps by adding a flag field of >some sort. This needs to be handled correctly when doing a fork >tricky. If the slave is closed in the parent, we will need to hand >off the descriptors to the child in order to make read detect EOF >correctly. However, if the slave is not closed, we do not want to >hand off the descriptors. So the handoff would need to happen when >the slave is closed. This is basically a matter of updating the tty >structure information when the slave is closed in the parent. The pty >code is full of race conditions at present, and this would >unfortunately be another one. This would not solve the general >problem of reopening a slave pty, but it would solve the particular >case you are running into. > >Does anybody have any other thoughts? Could the process which has the slave open signal EOF in some other way, perhaps, like by releasing a mutex? -- http://www.bbc.com/ cgf AT bbc DOT com "Strange how unreal VMS=>UNIX Solutions Boston Business Computing the real can be."