do anonymous pipes normally work on NT?

Georg Mischler schorsch at schorsch.com
Tue Jun 15 01:40:05 CEST 1999


Ok, here we go again.

I simplified my class to the absolute minimum I could.
It now does nothing but create three pipes, save the
parent ends to self.xxx, and create a process with
the child ends of the pipes. After that it tries to
write to the stdin pipe of the child, which goes
without error, and tries to read from stdout, which
blocks.

To have a look at the other end, I wrote a little
script that mimicks the unix "cat" command (in a
very verbose logging incarnation...). This script
first tries to write something to stdout as well,
which goes without error, and then enters a loop
reading from stdin and writing to stdout.

This script is called from my class as a child
process. The interesting thing is now, that in this
case the child gets a "Bad file descriptor" when
reading from stdin!

There must be something going fundamentally wrong
with the pipes, but without any Windows programming
background, I have no chance left figuring out what.
This happens on NT4sp3 with Python 1.5.2 (the
binary from python.org) and the win32 extensions
build 125, if that makes any difference.

If this should be caused by a mistake I made
(which may be likely), could anyone recommend a
book where I can learn how to do this stuff
right? And in any case, what is going on here?

To try this out, copy both files together into
a directory, change the path of python in the
last code line of numproc.py to something that
exists on your system, and call "python runproc.py".
You'll have to kill the process with the task
manager (at least I have to do this). The new
file "log.txt" will contain the results of the
child process.


Thanks a lot for any help!

-schorsch

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

'''cat.py

a "enhanced" version of the good old cat unix filter.
'''

import sys

try:
    # write status to a file, in order not to lose it.
    f = open('log.txt', 'a')
    f.write('before write\n')
    sys.stdout.write('huh?')
    f.write('after write, before read\n')
    data = sys.stdin.read()
    f.write('after read\n')
    while data:
        f.write('in loop, before write\n')
        sys.stdout.write(data)
        f.write('in loop, after write, before read\n')
        data = sys.stdin.read()
        f.write('in loop, after read\n')
except:
    import traceback, string
    tb_strs = traceback.format_exception(
            sys.exc_type,
            sys.exc_value,
            sys.exc_traceback)
    f.write(string.join(tb_strs))

# end of cat.py

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

'''cat.py

an "enhanced" version of the good old cat unix filter.
'''

import sys

try:
    # write status to a file, in order not to lose it.
    f = open('log.txt', 'a')
    f.write('before write\n')
    sys.stdout.write('huh?')
    f.write('after write, before read\n')
    data = sys.stdin.read()
    f.write('after read\n')
    while data:
        f.write('in loop, before write\n')
        sys.stdout.write(data)
        f.write('in loop, after write, before read\n')
        data = sys.stdin.read()
        f.write('in loop, after read\n')
except:
    import traceback, string
    tb_strs = traceback.format_exception(
            sys.exc_type,
            sys.exc_value,
            sys.exc_traceback)
    f.write(string.join(tb_strs))

# end of cat.py

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

'''runproc.py

start a process with three inherited pipes.
Try to write to and read from those.
'''

import win32pipe
import win32file
import win32process
import win32security

class Process:
    def run(self, cmdline):

        # security attributes for pipes
        sAttrs = win32security.SECURITY_ATTRIBUTES()
        sAttrs.bInheritHandle = 1

        # create pipes
        hStdin_r,  self.hStdin_w  = win32pipe.CreatePipe(sAttrs, 0)
        self.hStdout_r, hStdout_w = win32pipe.CreatePipe(sAttrs, 0)
        self.hStderr_r, hStderr_w = win32pipe.CreatePipe(sAttrs, 0)

        # set the info structure for the new process.
        StartupInfo = win32process.STARTUPINFO()
        StartupInfo.hStdInput  = hStdin_r
        StartupInfo.hStdOutput = hStdout_w
        StartupInfo.hStdError  = hStderr_w
        StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES

        # start the process.
        hProcess, hThread, dwPid, dwTid = win32process.CreateProcess(
                None,   # program
                cmdline,# command line
                None,   # process security attributes
                None,   # thread attributes
                1,      # inherit handles, or USESTDHANDLES won't work.
                        # creation flags. Don't access the console.
                win32process.DETACHED_PROCESS,
                None,   # no new environment
                None,   # current directory (stay where we are)
                StartupInfo)
        # normally, we would save the pid etc. here...

        err, bytes = win32file.WriteFile(self.hStdin_w, 'hmmm')
        print 'wrote:', bytes, 'bytes'

        res, str = win32file.ReadFile(self.hStdout_r, 1)
        if res == 0: print 'read:', str
        else: 'read nothing.'

        res, str = win32file.ReadFile(self.hStderr_r, 1)
        if res == 0: print 'read:', str
        else: 'read nothing.'


if __name__ == '__main__':
    p = Process()
    p.run('c:\programme\python\python.exe cat.py')

# end of runproc.py

--
Georg Mischler  --  simulation developper  --  schorsch at schorsch.com
+schorsch.com+  --  lighting design tools  --  http://www.schorsch.com/


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.




More information about the Python-list mailing list