verve
verve

Reputation: 785

How to pipe to stdin of os.execv'd process in Python

I want to write something to the stdin of a process replacing my current Python process. Is there an easy way to do this? I was thinking along the lines of

import sys, os

r, w = os.pipe()
os.write(w, 'yo')
os.dup2(r, sys.stdin.fileno())
os.execvp('cat', [''])

but when I execute this in OS X, cat hangs, though 'yo' does get displayed. Why?

Upvotes: 3

Views: 1722

Answers (1)

Adam Rosenfield
Adam Rosenfield

Reputation: 400146

You os.fork() the process before execvp()-ing the child process; the parent then writes to the pipe while the child reads from it. The parent must also close() the read end of the pipe after fork(), and the child must dup2() the read end onto stdin and then close both of the original pipe handles before execvp(). It's pretty standard Unix pipe stuff.

For example:

r, w = os.pipe()
if os.fork() == 0:
    # Child process
    os.dup2(r, sys.stdin.fileno())
    os.close(r)
    os.close(w)
    os.execvp(...)
else:
    # Parent process
    os.close(r)
    os.write(w, 'yo')
    ...
    os.close(w)  # When done writing
    os.wait()

Upvotes: 4

Related Questions