how to find and close opened file descriptor

Discussion in 'Ruby' started by Oliver Peng, May 7, 2009.

  1. Oliver Peng

    Oliver Peng Guest

    During my testing, I found that ruby doesn't create IO object for each
    opened file descriptor which are inherited from parent process. So we
    have to close all these opened file descriptor except stdin, stdout and
    stderr by following way:

    3.upto(1023) do |fd|
    begin
    if io = IO::new(fd)
    io.close
    end
    rescue
    end
    end

    But I really don't like this way. Is there better way that I can find
    all opened file descriptors.

    And now I am assuming the maximum file no is 1023. Is there any way that
    I can get the maximum file no?

    Thanks.
    --
    Posted via http://www.ruby-forum.com/.
     
    Oliver Peng, May 7, 2009
    #1
    1. Advertising

  2. Oliver Peng

    Roger Pack Guest

    > And now I am assuming the maximum file no is 1023. Is there any way that
    > I can get the maximum file no?


    You could run a loop at the beginning of your script which detects it :)

    count = 0
    all = []
    begin
    loop { all << File.open('test','w') }
    rescue Exception
    count = all.length
    for file in all do; file.close; end
    end
    count

    But getting back to your original question, another way to close
    descriptors is
    GC.each_object(IO) do |io| io.close; end

    I guess. Not totally sure what you mean by "doesnt create file
    descriptors for each inherited object" ?
    Thanks.
    -=r
    --
    Posted via http://www.ruby-forum.com/.
     
    Roger Pack, May 8, 2009
    #2
    1. Advertising

  3. Oliver Peng

    Oliver Peng Guest

    Roger Pack wrote:
    >> And now I am assuming the maximum file no is 1023. Is there any way that
    >> I can get the maximum file no?

    >
    > You could run a loop at the beginning of your script which detects it :)
    >
    > count = 0
    > all = []
    > begin
    > loop { all << File.open('test','w') }
    > rescue Exception
    > count = all.length
    > for file in all do; file.close; end
    > end
    > count
    >
    > But getting back to your original question, another way to close
    > descriptors is
    > GC.each_object(IO) do |io| io.close; end
    >
    > I guess. Not totally sure what you mean by "doesnt create file
    > descriptors for each inherited object" ?
    > Thanks.
    > -=r


    At first, I also try to find all IO objects and close. Here is the code:

    ObjectSpace.each_object(IO) do |io|
    begin
    unless io.closed?
    io.close
    end
    rescue ::Exception
    end
    end

    But it doesn't work because ruby doesn't create IO object for the open
    file descriptor which are inherited from parent process.
    --
    Posted via http://www.ruby-forum.com/.
     
    Oliver Peng, May 8, 2009
    #3
  4. On 8 May 2009, at 14:55, Oliver Peng wrote:
    > At first, I also try to find all IO objects and close. Here is the
    > code:
    >
    > ObjectSpace.each_object(IO) do |io|
    > begin
    > unless io.closed?
    > io.close
    > end
    > rescue ::Exception
    > end
    > end
    >
    > But it doesn't work because ruby doesn't create IO object for the open
    > file descriptor which are inherited from parent process.


    You should probably describe how your parent process is opening these
    file descriptors as clearly it's not via objects in the IO hierarchy
    or they would be accessible in the child process. As a general rule
    though, if you have control over where and when the file descriptors
    are coming into play you can use the IO.for_fd(file_descriptor) method
    and store them in a *shudder* global variable or constant...

    OPEN_FILES = []
    ...
    ...
    fd = some_method_that_opens_file_and_returns_descriptor
    OPEN_FILES << IO.for_fd(fd)
    ...
    ...

    Then in the spawned child process closing these would be as simple as:

    OPEN_FILES.each { |file| file.close }



    Ellie

    Eleanor McHugh
    Games With Brains
    http://slides.games-with-brains.net
    ----
    raise ArgumentError unless @reality.responds_to? :reason
     
    Eleanor McHugh, May 8, 2009
    #4
  5. Oliver Peng

    Gary Wright Guest

    On May 7, 2009, at 11:54 AM, Oliver Peng wrote:

    > During my testing, I found that ruby doesn't create IO object for each
    > opened file descriptor which are inherited from parent process. So we
    > have to close all these opened file descriptor except stdin, stdout
    > and
    > stderr by following way:
    >
    > 3.upto(1023) do |fd|
    > begin
    > if io = IO::new(fd)
    > io.close
    > end
    > rescue
    > end
    > end
    >
    > But I really don't like this way. Is there better way that I can find
    > all opened file descriptors.


    I believe this is the standard idiom on *nix type systems to close all
    file descriptors when you have no particular knowledge of which ones
    are open.

    In other words there is no standard way to ask the OS for a list of
    open descriptors via a simple system call.

    A possible alternative is to parse the output of utilities like 'lsof'
    to determine what file descriptors are open or to dig into the various
    platform specific ways that those utilities query the kernel for this
    information.

    Gary Wright
     
    Gary Wright, May 8, 2009
    #5
  6. Oliver Peng

    Roger Pack Guest

    > I believe this is the standard idiom on *nix type systems to close all
    > file descriptors when you have no particular knowledge of which ones
    > are open.


    I think that's right except for maybe solaris has a helper or something,
    but there's no standard.
    -=r
    --
    Posted via http://www.ruby-forum.com/.
     
    Roger Pack, May 8, 2009
    #6
  7. On May 7, 9:54=A0am, Oliver Peng <> wrote:
    > During my testing, I found that ruby doesn't create IO object for each
    > opened file descriptor which are inherited from parent process. So we
    > have to close all these opened file descriptor except stdin, stdout and
    > stderr by following way:
    >
    > =A0 =A0 =A03.upto(1023) do |fd|
    > =A0 =A0 =A0 =A0 begin
    > =A0 =A0 =A0 =A0 =A0 if io =3D IO::new(fd)
    > =A0 =A0 =A0 =A0 =A0 =A0 io.close
    > =A0 =A0 =A0 =A0 =A0 end
    > =A0 =A0 =A0 =A0 rescue
    > =A0 =A0 =A0 =A0 end
    > =A0 =A0 =A0 end
    >
    > But I really don't like this way. Is there better way that I can find
    > all opened file descriptors.
    >
    > And now I am assuming the maximum file no is 1023. Is there any way that
    > I can get the maximum file no?


    The io-extra library might be able to help you, depending on your
    platform.

    gem install io-extra.

    Take a look at the IO.closefrom and IO.fdwalk methods.

    Regards,

    Dan
     
    Daniel Berger, May 8, 2009
    #7
    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. Simon Strandgaard
    Replies:
    4
    Views:
    607
    Simon Strandgaard
    Feb 16, 2004
  2. Iñaki Baz Castillo
    Replies:
    7
    Views:
    868
    Iñaki Baz Castillo
    Jan 12, 2010
  3. Glenn
    Replies:
    2
    Views:
    157
    Glenn
    Oct 30, 2007
  4. PerlFAQ Server
    Replies:
    0
    Views:
    105
    PerlFAQ Server
    Feb 7, 2011
  5. PerlFAQ Server
    Replies:
    0
    Views:
    100
    PerlFAQ Server
    Mar 17, 2011
Loading...

Share This Page