Nir said:
In windows platforms how can I make two processes hold two ends of the
same pipe?
os.pipe() returns reader and writer descriptors but how do I export one
of the ends to another process?
Note: popen() is not good for me since the new process is left without
tty input and output.
I have a little namedpipe class that I use. I stole it somewhat from a
perl version a while ago.
"""Named pipe wrapper.
#server
from NamedPipe import NamedPipe
pipe = NamedPipe("mypipe")
pipe.connect()
pipe.write("foo")
#client
from NamedPipe import NamedPipe, CLIENT
import time
pipe = NamedPipe("\\\\.\\pipe\\test1", mode=CLIENT)
while pipe.select() is None:
time.sleep(1)
print pipe.read()
"""
from win32pipe import *
from win32file import *
import pywintypes
import win32security, win32file
import string
SERVER = 0
CLIENT = 1
class NamedPipe:
_header = '\\\\.\\pipe\\'
def __init__(self,
pipeName,
mode=SERVER,
openMode=PIPE_ACCESS_DUPLEX,
pipeMode=0,
maxInstances=1,
outBufferSize=0,
inBufferSize=0,
defaultTimeOut=0,
securityAttributes=None):
# fix the name if appropriate
pipeName = self._fixName(pipeName)
sAttrs = win32security.SECURITY_ATTRIBUTES()
sAttrs.bInheritHandle = 1
self._pipeName = pipeName
# allocate a 100K readbuffer
self._bufsize = 100000
self._buf = win32file.AllocateReadBuffer(self._bufsize)
if mode:
WaitNamedPipe(pipeName, NMPWAIT_WAIT_FOREVER)
self._pipe = CreateFile(pipeName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
None,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH,
None)
else:
self._pipe = CreateNamedPipe(pipeName, openMode, pipeMode,
maxInstances,
outBufferSize, inBufferSize,
defaultTimeOut, securityAttributes)
def __del__(self):
if self._pipe:
try:
self.disconnect()
except pywintypes.error:
# I don't know why this happens...
pass
def _fixName(self, pipeName):
"""(pipeName)->fixed pipeName
Pipe names must start with header '\\.\pipe\',
if the given pipeName
does not, append the header to the pipeName"""
if string.find(pipeName, self._header) != 0:
return "%s%s"%(self._header, pipeName)
else:
return pipeName
def connect(self):
return ConnectNamedPipe(self._pipe, None)
def disconnect(self):
result = DisconnectNamedPipe(self._pipe)
self._pipe = None
return result
def select(self):
"""returns None is the pipe has no data, self otherwise"""
data, size, something = PeekNamedPipe(self._pipe, 1)
if not data:
return None
return data
def write(self, data):
win32file.WriteFile(self._pipe, data, None)
def read(self):
length, s = win32file.ReadFile(self._pipe, self._buf)
return s
if __name__ == "__main__":
import tempfile
import thread, time
done = 0
def runpipe():
pipe = NamedPipe("test1")
pipe.connect()
pipe.write('Sending to pipe')
def readpipe():
global done
pipe2 = NamedPipe("test1", mode=CLIENT)
print pipe2.read()
done = 1
thread.start_new_thread(runpipe, ())
thread.start_new_thread(readpipe, ())
while not done:
time.sleep(1)