Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interrupt child called from ruby

Tags:

ruby

Why interrupting ruby process with child created using call to system does not interrupt ruby process itself? They should belong to the same group, so should be both interrupted. Also this is not valid for ruby2.0.

Given ruby 1.8.7 patch 371, ruby 1.9.3 patch 392 and ruby2.0 patch 0:

Running ruby1.8 -e 'system "sleep 100"; p $?; sleep' in bash and pressing ⌃C kills only inner call to sleep 100.

Ruby 1.9 behaves identically.

Though running ruby2.0 -e 'system "sleep 100"; p $?; sleep' interrupts both inner command and ruby process itself.2.0.0-p0

--EDIT--

Reading sources I've found that handling SIGINT, SIGQUIT and SIGHUP is switched to ignored in rb_syswait method which than waits for created sub process to finish and then restores handlers (rb_syswait in ruby v1.8.7-p370, ruby v1.9.3-p362 and without blocking handlers in ruby v2.0.0-p0).

Why is it done and why only for system and IO.popen, not %x{} or fork{}?

like image 736
tig Avatar asked Apr 02 '13 00:04

tig


1 Answers

For a workaround, you can propagate SIGINT yourself. You can examine whether the system command exited due to a signal, and if so raise SIGINT:

ruby1.8 -e 'system "sleep 100"; p $?; Process.kill("INT",0) if $?.signaled?; sleep'
like image 69
Markku K. Avatar answered Nov 10 '22 01:11

Markku K.