Ruby network question

I will obviously mail the ruby list as well, but on the off chance
someone here might be able to help,

(I’m a ruby newbie)

i have a simple ruby mgmt program listening on a network port, which
accepts commands and does appropriate stuff,

however restarted services weirdly seem to hold the port of the process,

One of the things it does is to restart system services

system “/usr/local/etc/rc.d/proftpd start”

sockstat -4 -l then shows that the proftpd process is tied to the
listening port of the ruby program/daemon.
(It does the same when not running daemonised).

nobody proftpd 30996 1 tcp4 *:21 :
nobody proftpd 30885 3 tcp4 [hostIP]:844 :
root ruby 30826 3 tcp4 [hostIP]:844 :

This doesn’t affect the running of the ftp server or the ruby daemon,
but it means that i need to restart the various other daemons to release
the 844 socket.

can anyone help?

Paul M. wrote in post #1025617:

                   system "/usr/local/etc/rc.d/proftpd start"

sockstat -4 -l then shows that the proftpd process is tied to the
listening port of the ruby program/daemon.
(It does the same when not running daemonised).

nobody proftpd 30996 1 tcp4 *:21 :
nobody proftpd 30885 3 tcp4 [hostIP]:844 :
root ruby 30826 3 tcp4 [hostIP]:844 :

This doesn’t affect the running of the ftp server or the ruby daemon,
but it means that i need to restart the various other daemons to release
the 844 socket.

can anyone help?

Looks like ruby not setting close_on_exec flag on your socket when doing
fork/exec in system(), but I’m not sure how to get round this:

But the simple way is to reimplement system() yourself by using fork and
then exec within the child, and wait in the parent (it’s pretty
straightforward). Before you exec, close the listening socket.

On Fri, Oct 7, 2011 at 7:31 PM, Paul M. [email protected] wrote:

One of the things it does is to restart system services
root ruby 30826 3 tcp4 [hostIP]:844 :

This doesn’t affect the running of the ftp server or the ruby daemon,
but it means that i need to restart the various other daemons to release
the 844 socket.

can anyone help?

Basically the solution is to close all file handles that you do not
want the child process to inherit. One way to achieve that is to fork
either for every accepted connection or immediately before invoking
other programs.

Example

server = TcpServer.new 1234

while (child = server.accept)
fork do
# close fds
server.close

# do whatever
child.puts "I do not hold on to the server port any more!"
system "echo", "me neither"

end
end

The daemons gem might also help.
http://daemons.rubyforge.org/

With that you can daemonize the current process:
http://daemons.rubyforge.org/classes/Daemons.html#M000007

Although, when I look at the source code contained in the docs it
seems like it will close your socket connection…

Kind regards

robert