It's just magic, and I hate it ...

Clarence Gardner clarence at silcom.com
Thu Jun 24 10:28:30 EDT 1999


Mitchell Morris (mgm at unpkhswm04.bscc.bls.com) wrote:
: As much as I hate to admit I'm an idiot, I got caught by the simplest of
: things. When the child forks, it inherits all the open file descriptors of
: the parent ... which includes sys.stdin and sys.stdout. Since these two (at
: least) are attached to the socket from the browser, the browser doesn't
: follow the redirect until *ALL* the fds close.
: 
: My new question is how do I close all the connections to the browser after
: the fork? The obvious:
: 	sys.stdin.close()
: 	sys.stdout.close()
: 	sys.stderr.close()
: didn't get them all, since the browser continues to wait. Is there a
: mechanism to determine all opened files?

I had the same problem a while ago, which resulted in FAQ #4.87:

4.87. Why doesn't closing sys.stdout (stdin, stderr)
really close it?

Python file objects are a high-level layer of abstraction on top of C
streams, which in turn are a medium-level layer of abstraction on top
of (among other things) low-level C file descriptors. 

For most file objects f you create in Python via the builtin "open"
function, f.close() marks the Python file object as being closed from
Python's point of view, and also arranges to close the underlying C
stream. This happens automatically too, in f's destructor, when f
becomes garbage. 

But stdin, stdout and stderr are treated specially by Python, because
of the special status also given to them by C: doing 

    sys.stdout.close() # ditto for stdin and stderr

marks the Python-level file object as being closed, but does not close
the associated C stream (provided sys.stdout is still bound to its default
value, which is the stream C also calls "stdout"). 

To close the underlying C stream for one of these three, you should
first be sure that's what you really want to do (e.g., you may confuse
the heck out of extension modules trying to do I/O). If it is, use
os.close: 

    os.close(0)   # close C's stdin stream
    os.close(1)   # close C's stdout stream
    os.close(2)   # close C's stderr stream


-- 
-=-=-=-=-=-=-=-=
Clarence Gardner
AvTel Communications
Software Products and Services Division
clarence at avtel.com




More information about the Python-list mailing list