Ticket #3529: demo.4.py

File demo.4.py, 1.6 KB (added by exarkun, 5 years ago)

switch to stdio calls for talking to stdin in the child process

Line 
1
2import sys, os, select
3
4def main():
5    # Create stdin, stdout, stderr for the child process
6    stdin = os.pipe()
7    stdout = os.pipe()
8    stderr = os.pipe()
9
10    # Create the child
11    pid = os.fork()
12    if pid == 0:
13        child(stdin, stdout, stderr)
14    else:
15        parent(pid, stdin, stdout, stderr)
16
17
18def child(stdin, stdout, stderr):
19    # close the parent sides
20    stdin, close = stdin
21    os.close(close)
22    close, stdout = stdout
23    os.close(close)
24    close, stderr = stderr
25    os.close(close)
26
27    # Make them look like stdio and get rid of the originals
28    os.dup2(stdin, 0)
29    os.close(stdin)
30    os.dup2(stdout, 1)
31    os.close(stdout)
32    os.dup2(stderr, 2)
33    os.close(stderr)
34
35    # Run another Python process
36    fObj = file('tempdemo.py', 'w')
37    fObj.write('''
38import sys, os
39# wait for instructions from the parent
40while True:
41    command = sys.stdin.readline().strip()
42    if not command:
43        break
44    os.close(int(command))
45''')
46    fObj.close()
47
48    os.execvpe(sys.executable, [sys.executable, 'tempdemo.py'], os.environ)
49
50
51def parent(pid, stdin, stdout, stderr):
52    # close the child sides
53    close, stdin = stdin
54    os.close(close)
55    stdout, close = stdout
56    os.close(close)
57    stderr, close = stderr
58    os.close(close)
59
60    # tell the child to close stderr
61    os.write(stdin, '2\n')
62    # wait for it to close
63    select.select([stderr], [], [])
64
65    # now tell it to close the stdout
66    os.write(stdin, '1\n')
67    # wait for it to close
68    select.select([stdout], [], [])
69
70    # now tell it to exit
71    os.write(stdin, '\n')
72    # and wait for it to do so
73    print os.wait()
74
75
76if __name__ == '__main__':
77    main()