El SáÃado, 12 de Diciembre de 2009, Robert Klemme escribi
> On 12.12.2009 10:53, Iki Baz Castillo wrote:
> > El SáÃado, 12 de Diciembre de 2009, David Masover escribi
> >> On Friday 11 December 2009 05:33:06 pm Iki Baz Castillo wrote:
> >>> The good point of using:
> >>>
> >>>   start-stop-daemon --stop --pidfile /var/run/rb_program.pid --name
> >>>  rb_program
> >>>
> >>> is that it would stop the process just if it's called "rb_program" and
> >>> its pid matches the value of /var/run/rb_program.pid, so you cannot
> >>> kill any other process using that pid by accident (it could occur if
> >>> your program didn't delete the pidfile and a new process has taken same
> >>> pid value).
> >>
> >> That's a good point -- though I would guess that in theory, it shouldn't
> >> be possible for a program to die in such a way that it wouldn't be able
> >> to delete that file. The only thing that would make sense is a reboot,
> >> and on my system, /var/run is a tmpfs (only exists in RAM/swap), so it's
> >> not stored anywhere that would survive a reboot.
> >
> > Well, usually daemons are coded to deelte the pidfile upon receipt of a
> > SIGINT signal (or some others). But if the daemon is killed with "kill -9
> > PID" then it terminates inmediately without deleting the piddile.
> >
> > In the case of a crash or segmentfault the daemon wouldn't delete the
> > pidfile again.
> >
> > I've coded my Debian init script "start" action so it deletes the
> > existing "pidfile" if it exists (it shouldn't).
> 
> You can make deletion conditionally depending on the presence of the
> process (kill 0).  This is what I would do:
> 
> VAR='/var/run'
> 
> pid_file = File.join(VAR, File.basename($0) + '.pid')
> 
> begin
>    old_pid = File.read(pid_file).to_i
>    Process.kill 0, old_pid
>    $stderr.puts "ERROR: already running with PID #{old_pid}"
>    exit 1
> rescue Errno::ENOENT
>    # no pid file
> rescue Errno::ESRCH
>    # process not running
>    $stderr.puts 'WARNING: stale pid file'
> end
> 
> # open file with EXCL in order to catch race conditions where two
> # processes were started almost at the same time and both thought
> # they would be a new instance.  Uncomment sleep to simulate:
> # sleep 2
> File.open(pid_file, File::EXCL | File::WRONLY | File::CREAT) {|io|
> io.write($$)}
> trap(0) {File.delete pid_file}
> 
> puts "OK, here we go."
> 
> # just for testing purposes:
> File.read(pid_file).to_i == $$ or raise "What went wrong?"
> 
> sleep 10
> 
> puts "Finished"
> 
> > Thanks a lot for all your suggestions, it's a really interesting subject.
> > However I would prefer to keep the code as simple as possible. The onlyanted was the possibility of kill my program using "killall rb_program".
> 
> Why does it have to be "killall"?  What about providing a command line
> option "-k" or "--kill" for killing (e.g. as ssh-agent does)?  You could
> integrate that pretty easily with the PID handling code above.
> 
> > To summarize this is possible in these cases:
> >
> > a) Hardcoding the ruby location (avoiding using "env").
> > Not user-friendly.
> 
> I personally do not find it too unfriendly to place the interpreter name
> with an absolute path in the script.  This has also greater safety and
> robustness: the one installing the program and ruby interpreter (some
> person with administrative permissions) is likely the same and can
> ensure location is set properly.  Relying on users' environments is more
> fragile IMHO.
> 
> > b) Creating a link "rb_program" to ruby interpreter and invoke my program
> > with "rb_program /PATH_TO_rb_program.rb".
> > Not very beauty :)
> >
> > c) Replacing env with your above suggestion.
> > It involves compiling a C program, it could break something in a not pure
> > Linux environment...
> >
> > Well, I've learnt *a lot* in this thread but at this point I think is
> > better just to leave the code as it is.
> > Really thanks a lot.
> 
> Well, it's your choice.


Thanks a lot!


-- 
Iki Baz Castillo <ibc / aliax.net>