[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: Abort a system call

Masschelein Bart

7/5/2005 12:18:00 PM

>
> With parts of other pieces today on the reflector, I assembled this
>
> --------
> pid = Process.fork do
> exec($decoder, $bitstreamPath, $yuvOutputPath)
> end
>
> trap "SIGINT", proc{ Process.kill("SIGINT", pid); print "^C
> was pressed. Process id #{pid}\n" }
>
> Process.waitpid(pid)
> --------
>
> The trap gets executed, meaning that I get the output of the
> print, during the execution of my program, and the pid
> matches the one from the process status list. However the
> first part (Process.kill("SIGINT", pid);) is not executed
> correctly, or at least does not do what I expected, killing
> the process. Is there another way to kill a process from
> Ruby? Or do I need another signal # instead of "SIGINT"
> there? No clue...
>

For those having similar problems, I just solved it by

trap "INT", proc{ Process.kill(9, pid) }

so using a hard kill.

If people have more elegant ways of solving this, let me know!

CU

B


1 Answer

Guillaume Marcais

7/5/2005 2:55:00 PM

0

On Tue, 2005-07-05 at 21:18 +0900, Masschelein Bart wrote:
> >
> > With parts of other pieces today on the reflector, I assembled this
> >
> > --------
> > pid = Process.fork do
> > exec($decoder, $bitstreamPath, $yuvOutputPath)
> > end
> >
> > trap "SIGINT", proc{ Process.kill("SIGINT", pid); print "^C
> > was pressed. Process id #{pid}\n" }
> >
> > Process.waitpid(pid)
> > --------
> >
> > The trap gets executed, meaning that I get the output of the
> > print, during the execution of my program, and the pid
> > matches the one from the process status list. However the
> > first part (Process.kill("SIGINT", pid);) is not executed
> > correctly, or at least does not do what I expected, killing
> > the process. Is there another way to kill a process from
> > Ruby? Or do I need another signal # instead of "SIGINT"
> > there? No clue...
> >
>
> For those having similar problems, I just solved it by
>
> trap "INT", proc{ Process.kill(9, pid) }
>
> so using a hard kill.
>
> If people have more elegant ways of solving this, let me know!

Here is what I think is going on. Ruby sets up the signal handler so
that some system call will resume after the interrupt instead of
returning with EINTR:

from ruby-signal in signal.c:

#if defined(SA_RESTART)
/* All other signals but VTALRM shall restart restartable syscall
VTALRM will cause EINTR to syscall if interrupted.
*/
if (signum != SIGVTALRM) {
sigact.sa_flags |= SA_RESTART; /* SVR4, 4.3+BSD */
}
#endif

And from man sigaction:
SA_RESTART
Provide behaviour compatible with BSD signal
semantics by
making certain system calls restartable across
signals.

That is why Process.waitpid(pid) doesn't return until your decoder
process dies. Maybe Perl doesn't do that and it would explain the
difference of behavior.

Second, it seems that your decoder process doesn't terminate on a
SIGINT. Maybe you should send a SIGTERM, to be a little more graceful
than SIGKILL (9).

Hope it helps,
Guillaume.

PS: people in the know, please correct me if I got it wrong about the
way the signals are handled.