[Python-bugs-list] [ python-Bugs-514345 ] pty.fork problem

SourceForge.net noreply@sourceforge.net
Wed, 12 Feb 2003 21:57:00 -0800


Bugs item #514345, was opened at 2002-02-07 16:21
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=514345&group_id=5470

Category: Python Library
Group: None
Status: Open
Resolution: None
Priority: 5
Submitted By: M.-A. Lemburg (lemburg)
Assigned to: Fred L. Drake, Jr. (fdrake)
Summary: pty.fork problem

Initial Comment:
Subject: 
         Python bugreport, pty.fork problem
    Date: 
         Thu, 07 Feb 2002 07:30:08 -0800
   From: 
         Ronald Oussoren <oussoren@cistron.nl>
      To: 
         mal@lemburg.com


Sorry about the e-mail, but the bugtracker on SF doesn't 
accept my bugreport (I don't have a SF account).

The following script never returns:

----------------- start of script -------------
import pty
import os
import sys

def test():
        pid, fd = pty.fork()

        if pid == 0:
                print "1"
                print "2"
                print "3"
        else:
                fp = os.fdopen(fd, 'r')
                ln = fp.readline()
                while ln:
                        print '-->', ln
                        ln = fp.readline()
                print '-->', ln

test()
------------------ end of script -----------------
It prints '-->1' to '-->3' and then blocks. 

I've tested this with python 2.1 on Solaris 8. On Solaris 
pty.open seems to use 'openpty' instead of 'os.openpty'. A 
2-line change fixed the problem for me, but not for this 
demo-script: Close 'slave_fd' when pid != CHILD.




----------------------------------------------------------------------

Comment By: Michael Stone (mbrierst)
Date: 2003-02-13 05:57

Message:
Logged In: YES 
user_id=670441

I think I understand the problem.  I'm assuming Ronald was running the script from the interpreter.  In that case I also see the program block.  What's going on here is that python is continuing to run an interpreter in the forked process.  It's actually waiting for input from the user!  If you use read on the file descriptor to read in small quantities, you can actually see it print out the >>> prompt.  You can add sys.exit() to the end of the child fork to get guido's behavior.

The behavior Guido sees, I see if I run the script not in the interpreter.  It seems to be a real problem with forkpty/openpty.  When you close the slave fd, the master fd does not see EOF, it sees IOError.  This can be observed in C code as well.  This might be because of strange terminal settings in the new session, but I checked them and they look pretty normal.

This 'bug' in python was introduced by revision 2.117 of fileobject.c, when errors on close of file were raised instead of ignored.  (The checkin notes say there was no way to test it!)  I can't think of a good way to fix this.  Is there a unix guru who at least knows why it happens?  I tried newsgroups with no luck.  Maybe it should just be a documented problem.

----------------------------------------------------------------------

Comment By: Guido van Rossum (gvanrossum)
Date: 2002-02-08 21:58

Message:
Logged In: YES 
user_id=6380

Assigning to Fred, who appears to have hacked this module
before.

I cannot reproduce the problem, but I see a different
problem that may be hinting at the same issue:

Under Python 2.1 or before, on Red Hat Linux 7.2, the test
program for me prints this:

--> 1

--> 2

--> 3

--> 

and exits. But with Python 2.2, it prints:

--> 1

--> 2

--> 3

Traceback (most recent call last):
  File "/tmp/tpty.py", line 20, in ?
    test() 
  File "/tmp/tpty.py", line 17, in test
    ln = fp.readline() 
IOError: [Errno 5] Input/output error

How can the difference be explained? I like the pre-2.2
behavior better!

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=514345&group_id=5470