I needed a little daemon thisafternoon, so I wrote one in ruby using
fork and Process.detach. It’s working ok I suppose, except that when
I logout, it hangs, and I have to kill my session. It’s a little
annoying, to say the least. Anyone know a better way of doing this?
Thanks, code follows
–Kyle
#!/usr/bin/ruby #I’ve chopped out the bulk of the code in the Monitor class, since
it’s not really relevant, and not terribly clean either.
require ‘net/smtp’
class Monitor
def _setup_signals()
death_signals=%w{KILL QUIT STOP TERM EXIT}
Signal.trap(“HUP”) do
_setup_logfile()
_setup_ignores()
end
death_signals.each do
|signal|
Signal.trap(signal) do
log(“Caught #{signal} signal”)
@running=false
end
end
end
def loop
while @running
end
end
end
pid = fork do
m=Monitor.new
m.loop
end
Process.detach(pid)
I needed a little daemon thisafternoon, so I wrote one in ruby using
fork and Process.detach. It’s working ok I suppose, except that when
I logout, it hangs, and I have to kill my session. It’s a little
annoying, to say the least. Anyone know a better way of doing this?
IIUC, Process.detach is not what you need to start a daemon. All it does
is start a ruby thread to reap the pid when the child exits, so you
don’t end up with zombies. If the parent process exits first, this
thread is gone anyway.
Search the list for daemonize… for a classic daemon, you need to
double fork, Process.setsid, chdir, disconnect from stdin/out, and
probably something else I’m forgetting.
On Tue, Feb 17, 2009 at 5:38 PM, Joel VanderWerf [email protected] wrote:
something else I’m forgetting.
–
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
Ahh ok. It’s been so long since I’ve written a classic daemon in C,
that when I saw a post using Process.detach I thought, wow, ruby
really does make everything so easy
I’ll go read, and go the classic route. Daemonize is probably a fine
nice library, but being for work, issues sometimes arise about which
extra packages are put on a server. Gobs of home-grown code are fine,
third party apps and libs are sometimes frowned upon. Just one of
those things.
Ahh ok. It’s been so long since I’ve written a classic daemon in C,
that when I saw a post using Process.detach I thought, wow, ruby
really does make everything so easy
At Thu, 19 Feb 2009 23:25:20 +0900,
Brian C. wrote in [ruby-talk:328745]:
And there is this one from rackup (part of the rack package)
if daemonize
if RUBY_VERSION < “1.9”
Assuming it’s possible to check a feature by version number is
an evil habitat. You can just do it by
unless defined?(Process.daemon)
or, define your own Process.daemon.
module Process
unless defined?(daemon)
def self.daemon(nochdir=nil, noclose=nil)
exit! if fork
Process.setsid
unless nochdir
Dir.chdir “/”
end
unless noclose
STDIN.reopen “/dev/null”
STDOUT.reopen “/dev/null”, “w”
STDERR.reopen STDOUT
end
end
end
end
Apparently it doesn’t need to do many of the things mentioned in
the paper I quoted, like closing all other FDs.
/me sighs and mutters about re-inventing history.
causing dirs to get ceated as
world writable. Why would a daemon want that?
They wouldn’t - but they don’t want their behaviour to depend on
how they were launched either. They should specify a permissions
mask when they create things, or set umask themselves.
an evil habitat. You can just do it by
unless nochdir
Dir.chdir “/”
end
unless noclose
STDIN.reopen “/dev/null”
STDOUT.reopen “/dev/null”, “w”
STDERR.reopen STDOUT
end
end
end
end
It doesn’t need to fork twice?
Also the
File.umask 0000
line differs from Brian’s version (and others I’ve seen).
I’ve never understood why the umask is needed, and in fact recently took
it out of some daemons because it was causing dirs to get ceated as
world writable. Why would a daemon want that?
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.