Passing file descriptors

Josiah Carlson jcarlson at uci.edu
Thu Jun 10 07:29:48 CEST 2004


I've been working on this for more hours than I'm willing to admit, 
perhaps someone here can help me make it happen.


This us using Python 2.3.3
  - I do have access to a SunOS 5.8 machine, and the script at the end 
of this email works.
  - I need it to work on linux kernel 2.4.x.


I'm trying to write the equivalent of what the author calls "ringd" 
described in the below article, and use it with python 2.3.x on linux 2.4:
http://www.remote.org/jochen/work/pub/zero-downtime.pdf


The script that I provide at the end of this post is a variation of one 
posted in this thread:
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&selm=7t5i40%241pn%241%40nyheter.chalmers.se&rnum=8

There is a C version listed later in that article, but I've not yet 
tried it out.

Certainly I need a two things:
1. Unix domain socket, local socket (standard socket connected locally), 
or pipe
2. sendmsg/recvmsg, fcntl.ioctl, or equivalent file descriptor manipulation

In the script listed at the end of this post, I use a file descriptor 
pair returned by os.pipe(), which should be sufficient.  I also use 
fcntl.ioctl().


As stated previously, this works properly on SunOS 5.8:
     jcarlson at synergistic-envision% python2.3 fdpass.py
     Parent ioctl() returned 0
     #!/usr/pd/bin/python
     jcarlson at synergistic-envision%

It does not work on the linux machine I'm testing it on:
     [jcarlson at dev jcarlson]$ python fdpass.py
     [Errno 22] Invalid argument
     Traceback (most recent call last):
       File "fdpass.py", line 58, in ?
         ret = fcntl.ioctl(pRead, fcntl.I_RECVFD, s)
     IOError: [Errno 22] Invalid argument
     [jcarlson at dev jcarlson]$

Seemingly this is because I_SENDFD/I_RECVFD is not properly implemented 
on linux 2.4, but maybe I'm doing something wrong.


I've also tried using SCM_RIGHTS as per this thread:
http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&selm=78c7ca81.0402110402.11eb957d%40posting.google.com

It is not defined in python's fcntl module, but I did find the C 
definition in the linux /usr/include/bits/socket.h...
     SCM_RIGHTS = 0x01,          /* Transfer file descriptors.  */

So I passed the integer 1 manually, on both linux and SunOS 5.8 and got 
exceptions like I normally do on linux.

There is another C-based option that wraps sendmsg and recvmsg in the 
twistedmatrix sandbox:
http://cvs.twistedmatrix.com/cvs/trunk/sandbox/pahan/sendmsg/sendmsg.c?view=markup&rev=9300&root=Twisted

Does anyone have an idea of how to get it working on linux?  I would 
prefer to not have to break into C, if only because I don't want to 
accidentally leak memory (once bitten, twice shy they say).  Certainly 
Pyrex and SWIG are options, but first I'd like to try a pure Python version.


Thanks
  - Josiah



More information about the Python-list mailing list