Passing file descriptors in Python?

Viktor Fougstedt viktor at dtek.chalmers.se
Sat Oct 2 14:15:28 EDT 1999


viktor at dtek.chalmers.se (Viktor Fougstedt) writes:

>I do not know if you can use the fcntl.ioctl() call in Python to do
>the same thing, but my guess is it should work (if you are on a
>machine whose UNIX dialect supports the I_SENDFD/I_RECVFD ioctls, that
>is. Check your local ioctl() manpage). A quick glance at the Python
>interpreter's source-code seems to indicate that this _should_ work,
>but I'm not certain.

>If I get the time tonight, I'll give it a shot and see if I can make
>it work.


Following up on my own post, of course I couldn't stop myself from
trying at once. It seems to work, which impresses me of Pythons
transparency towards the underlying OS.

Example code below, seems to work fine on Solaris. Not sure which
other UNIX dialects support I_SENDFD/I_RECVFD ioctl()s, but it should
work on them as well. 


/Viktor...

======================================================================
#!/usr/pd/bin/python
#

#
# Example of passing an open filedescriptor with Python. Will only work
# on UNIX dialects that support the I_SENDFD and I_RECVFD ioctl() calls.
#

# STROPTS was created using Tools/scripts/h2py from Python's sourcecode
# distribution.

import STROPTS, fcntl, os, sys, struct

#
# Create a pipe for sending the fd.
#

(pRead, pWrite) = os.pipe()


#
# fork() off!
#

pid = os.fork()

if pid != 0:
    # We're in the parent.

    # 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().
    retval = fcntl.ioctl(pWrite, STROPTS.I_SENDFD, fd)

    # Should probably check retval rather than just printing it. :)
    print "Parent ioctl() returned %d" % retval

    # Wait for child to terminate, then exit.
    os.waitpid(pid, 0)
    sys.exit(0)

else:
    # We're in the child.
    
    # Create a string representing the strrecvfd structure that ioctl()
    # will return.
    str = struct.pack('iii', 0, 0, 0)

    # Receive filedescriptor. Will block until descriptor is sent.
    ret = fcntl.ioctl(pRead, STROPTS.I_RECVFD, str)
    
    # 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)


======================================================================


    
-- 
--|     Viktor Fougstedt, system administrator at dtek.chalmers.se     |--
--|                http://www.dtek.chalmers.se/~viktor/                |--
--| ...soon we'll be sliding down the razor blade of life. /Tom Lehrer |--




More information about the Python-list mailing list