Passing File Descriptors?

Discussion in 'Ruby' started by Worky Workerson, Mar 19, 2007.

  1. Is there a ruby way to pass file descriptors to separate processes?
    I'm thinking of interfacing with a C program, which uses the
    SCM_RIGHTS cmsg over a unix-domain socket ... is this idiom
    implemented in Ruby? How would I marshall an IO object into (and out
    of) the integer file descriptor, or does this "just work"?

    Thanks!
    -Mike
     
    Worky Workerson, Mar 19, 2007
    #1
    1. Advertising

  2. On 19.03.2007 17:43, Worky Workerson wrote:
    > Is there a ruby way to pass file descriptors to separate processes?
    > I'm thinking of interfacing with a C program, which uses the
    > SCM_RIGHTS cmsg over a unix-domain socket ... is this idiom
    > implemented in Ruby? How would I marshall an IO object into (and out
    > of) the integer file descriptor, or does this "just work"?


    Untested: You can determine the descriptor id via io.fileno. The you
    can pass that to the child process via main's args when you exec after
    fork. Then the child should be able to reuse that descriptor.
    Alternatively you can of course transport the descriptor id via an
    environment variable.

    Kind regards

    robert
     
    Robert Klemme, Mar 19, 2007
    #2
    1. Advertising

  3. Worky Workerson

    Gary Wright Guest

    On Mar 19, 2007, at 12:43 PM, Worky Workerson wrote:
    > Is there a ruby way to pass file descriptors to separate processes?
    > I'm thinking of interfacing with a C program, which uses the
    > SCM_RIGHTS cmsg over a unix-domain socket ... is this idiom
    > implemented in Ruby? How would I marshall an IO object into (and out
    > of) the integer file descriptor, or does this "just work"?


    After a little investigation, this turned out to be easier than
    I thought. The following code was tested on Mac OS X with ruby 1.8.5.
    There are three files below, don't cut and paste the whole thing:

    socketpair.rb # example with parent/child

    server.rb # example with unrelated processes
    client.rb

    Socketpair.rb and client.rb both take a single argument, the name
    of the data file to open.

    Start server.rb before running client.rb.

    If you try this on something other than Mac OS X ruby 1.8.5, let us
    know how it works.

    Gary Wright


    $ cat socketpair.rb
    # Scenario 1: parent and child related via fork
    require 'socket'

    read, write = UNIXSocket.pair

    puts "parent end: #{read.inspect}, #{read.fileno}"
    puts "child end: #{write.inspect}, #{write.fileno}"

    pid = fork {
    file = File.open(ARGV[0])
    puts "child is sending: #{file.inspect}/#{file.fileno} connected
    to #{ARGV[0]}"
    write.send_io(file)
    exit
    }

    thefile = read.recv_io
    puts "parent received: #{thefile.inspect}/#{thefile.fileno}, contents:"
    puts thefile.read

    # end of scenario 1

    $ cat server.rb
    require 'socket'

    serv = UNIXServer.new("/tmp/server")
    p "server listening for connections: #{serv.inspect}"

    client = serv.accept
    p "received connection: #{client.inspect}"

    clientfile = client.recv_io
    puts "parent received fd: #{clientfile.fileno}, contents:"

    puts clientfile.read
    # end of server.rb


    $ cat client.rb
    require 'socket'

    server = UNIXSocket.new("/tmp/server")
    puts "connected to : #{server.inspect}"

    fd = File.open(ARGV[0])
    puts "child is sending fd: #{fd.fileno} connected to #{ARGV[0]}"

    server.send_io(fd) # we are *not* sending the data!

    exit
     
    Gary Wright, Mar 19, 2007
    #3
  4. Worky Workerson

    Gary Wright Guest

    On Mar 19, 2007, at 12:43 PM, Worky Workerson wrote:

    > Is there a ruby way to pass file descriptors to separate processes?
    > I'm thinking of interfacing with a C program, which uses the
    > SCM_RIGHTS cmsg over a unix-domain socket ... is this idiom
    > implemented in Ruby? How would I marshall an IO object into (and out
    > of) the integer file descriptor, or does this "just work"?


    In case folks were looking for a use case.

    A client makes a request to a server which opens the file
    and sends the opened file descriptor back to the client.
    Presumably the server process has special permissions to allow it
    access to the files that the client doesn't have. The server
    can also implement any additional security controls.

    The client gets to read and write a file without having had
    permission to open the file directly.

    This only works via Unix Domain sockets and so it only
    works between processes on the same machine. It won't work
    across a network.

    Gary Wright
     
    Gary Wright, Mar 19, 2007
    #4
  5. On 3/19/07, Gary Wright <> wrote:
    >
    > On Mar 19, 2007, at 12:43 PM, Worky Workerson wrote:
    > > Is there a ruby way to pass file descriptors to separate processes?
    > > I'm thinking of interfacing with a C program, which uses the
    > > SCM_RIGHTS cmsg over a unix-domain socket ... is this idiom
    > > implemented in Ruby? How would I marshall an IO object into (and out
    > > of) the integer file descriptor, or does this "just work"?

    >
    > After a little investigation, this turned out to be easier than
    > I thought.

    ...
    > clientfile = client.recv_io
    > puts "parent received fd: #{clientfile.fileno}, contents:"


    Sweet, thanks! I guess I had missed the {send,recv}_io methods.
    They're not in the Ruby book ... guess I should have done to the
    online docs. Ruby does make this trivial ... even works with my
    existing C program.

    -Mike
     
    Worky Workerson, Mar 20, 2007
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Josiah Carlson

    Passing file descriptors

    Josiah Carlson, Jun 10, 2004, in forum: Python
    Replies:
    7
    Views:
    1,675
    Josiah Carlson
    Jun 11, 2004
  2. JG
    Replies:
    5
    Views:
    430
    Lawrence Kirby
    Feb 8, 2005
  3. DJ Dharme
    Replies:
    2
    Views:
    270
    Maxim Yegorushkin
    Oct 20, 2008
  4. Stephan Beal
    Replies:
    11
    Views:
    2,131
    CBFalconer
    Jan 8, 2009
  5. Kevin
    Replies:
    0
    Views:
    167
    Kevin
    Apr 6, 2004
Loading...

Share This Page