Passing file descriptors
Josiah Carlson
jcarlson at uci.edu
Thu Jun 10 03:25:07 EDT 2004
> When I first saw the subject, I was about to point out that you had
> the wrong newsgroup: you want comp.lang.perl.misc
>
> I see you were talking about something else though.
No perl here.
> Last I checked, you have to use a Unix-domain socket to do this in
> Linux.
No dice...
[jcarlson at dev jcarlson]$ python fdpass.py
Traceback (most recent call last):
File "fdpass.py", line 63, in ?
ret = fcntl.ioctl(pRead, 1, s)
IOError: [Errno 22] Invalid argument
[Errno 14] Bad address
[jcarlson at dev jcarlson]$
I've tested the data transfer and it works fine.
Using the below modified code, unix domain sockets do not work. Any
other ideas?
- Josiah
-----cut here-----
#!/usr/pd/bin/python
#
# fdpass.py
#
# Example of passing an open filedescriptor with Python. Will only work
# on UNIX dialects that support the I_SENDFD and I_RECVFD ioctl() calls.
#
import fcntl, os, sys, struct, socket
#
# fork() off!
#
pid = os.fork()
port = '10001'
if pid != 0:
# We're in the parent.
s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.bind(port)
s.listen(1)
pWrite, addr = s.accept()
# Open a file for passing along to child. Use own source code,
# which is guaranteed to exist. :)
fileObj = open('./fdpass.py', 'r')
# ioctl() will only pass raw filedescriptors. Find fd of fileObj.
fd = fileObj.fileno()
# Send to the child using ioctl().
try:
retval = fcntl.ioctl(pWrite, fcntl.I_SENDFD, fd)
# Should probably check retval rather than just printing it. :)
print "Parent ioctl() returned %d" % retval
except Exception, e:
print e
# Wait for child to terminate, then exit.
os.waitpid(pid, 0)
sys.exit(0)
else:
import time
time.sleep(1)
# We're in the child.
pRead = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
pRead.connect(port)
# Create a string representing the strrecvfd structure that ioctl()
# will return.
s = struct.pack('iii', 0, 0, 0)
# Receive filedescriptor. Will block until descriptor is sent.
ret = fcntl.ioctl(pRead, fcntl.I_RECVFD, s)
# Unpack the strrecvfd-structure that ioctl() should return.
# fd is the filedescriptor, uid/gid the user/group id of the
# sending stream.
(fd, uid, gid) = struct.unpack('iii', ret)
# Reopen the filedescriptor as a Python File-object.
fileObj = os.fdopen(fd, 'r')
# Example usage: Read file, print the first line.
lines = fileObj.readlines()
print lines[0],
sys.exit(0)
More information about the Python-list
mailing list