Portable signals

cfp:~ > cat a.rb

···

#
# on windows signals don't work. least wise you cannot send, for instance,
# SIGABRT to another process. rather, you can only signal yourself! to get
# around this limitation a tiny drb service, fronting the Process object
# itself, can be setup to allow one process to signal another by making a drb
# call that actually causes the other process to signal *itself*. you've
# really got to love ruby at times like these.
#
   require 'drb'

   mode = ARGV.shift || 'servant'
   uri = ARGV.shift
   signal = 'ABRT'

   start_server = lambda do
     trap(signal){ puts "#{ Process.pid } got #{ signal }..." }
     DRb.start_service 'druby://localhost:0', Process
     uri = DRb.uri
   end

   start_client = lambda do
     DRb.start_service 'druby://localhost:0'
     process = DRbObject.new nil, uri
   end

   case mode
     when /server/i
       puts "server.pid => #{ Process.pid }."
       uri = start_server.call
       puts DRb.uri
       loop do
         puts "not blocking..."
         sleep 1
       end

     when /client/i
       puts "client.pid => #{ Process.pid }."
       process = start_client.call
       process.kill signal, process.pid

     when /servant/i
       puts "server.pid => #{ Process.pid }."
       uri = start_server.call
       Thread.new do
         loop do
           puts "not blocking..."
           sleep 1
         end
       end
       program = __FILE__
       client_program = "ruby #{ program } client #{ uri }"
       4.times do
         system client_program
         sleep 1
       end
   end

cfp:~ > ruby a.rb
server.pid => 1593.
not blocking...
client.pid => 1594.
1593 got ABRT...
not blocking...
client.pid => 1595.
1593 got ABRT...
not blocking...
client.pid => 1596.
1593 got ABRT...
not blocking...
client.pid => 1597.
1593 got ABRT...
not blocking...

a @ http://codeforpeople.com/
--
it is not enough to be compassionate. you must act.
h.h. the 14th dalai lama

Ara, did you checked the C code of Ruby? maybe there is some room we
can improve it, according to MSDN docs, the following signals are
being available to be defined:

SIGABRT: Abnormal termination
SIGFPE: Floating-point error
SIGILL: Illegal instruction
SIGINT: CTRL+C signal
SIGSEGV: Illegal storage access
SIGTERM: Termination request

But (there is always a but):

The SIGILL and SIGTERM signals are not generated under Windows NT.
They are included for ANSI compatibility. Thus you can set signal
handlers for these signals with signal, and you can also explicitly
generate these signals by calling raise.

http://msdn2.microsoft.com/en-us/library/xdkz3x12(VS.80).aspx

So, any other signal cannot be generated from other software that is
not ruby. Ruby exposes the list of signals available, but not all are
supported by the platform (so is impossible send a ABRT signal to
other process).

I'm getting it wrong?

Looking forward for your thoughts,

Luis

···

On Dec 28, 11:58 am, "ara.t.howard" <ara.t.how...@gmail.com> wrote:

cfp:~ > cat a.rb
#
# on windows signals don't work. least wise you cannot send, for
instance,
# SIGABRT to another process. rather, you can only signal yourself!
to get
# around this limitation a tiny drb service, fronting the Process object
# itself, can be setup to allow one process to signal another by
making a drb
# call that actually causes the other process to signal *itself*.
you've
# really got to love ruby at times like these.
#

you can generate and trap signals in windows using ruby - but *only for the same process*. in otherwords, currently in ruby, process A cannot send a signal to process B, A may only send signals to itself. at least this is how i'm interpreting this code

http://groups.google.com/group/ruby-talk-google/browse_frm/thread/e8478acbffe804cb

which sets up two processes - one trapping all signals and the other trying to send those same signals. the result of trying to send the signal is always EINVAL.

perhaps i'm missing something - in fact i'd be very happy to be proven wrong here (likely as i know nothing about windows) but my current understanding is that, under windows, signals cannot be sent process to process. my drb hack gets around that by allowing one process to cause another process to signal *itself*.

i've tried using two irb sessions too

irb_0 > puts $$
1234

irb_1 > Process.kill 'TERM', 1234

all signals except 9, which cannot be trapped, cause Errno::EINVAL to be raised in the process attempting to signal.

can you show me an example of one process signaling another in ruby?

cheers.

a @ http://codeforpeople.com/

···

On Dec 28, 2007, at 10:39 AM, Luis Lavena wrote:

Ara, did you checked the C code of Ruby? maybe there is some room we
can improve it, according to MSDN docs, the following signals are
being available to be defined:

SIGABRT: Abnormal termination
SIGFPE: Floating-point error
SIGILL: Illegal instruction
SIGINT: CTRL+C signal
SIGSEGV: Illegal storage access
SIGTERM: Termination request

But (there is always a but):

The SIGILL and SIGTERM signals are not generated under Windows NT.
They are included for ANSI compatibility. Thus you can set signal
handlers for these signals with signal, and you can also explicitly
generate these signals by calling raise.

http://msdn2.microsoft.com/en-us/library/xdkz3x12(VS.80).aspx

So, any other signal cannot be generated from other software that is
not ruby. Ruby exposes the list of signals available, but not all are
supported by the platform (so is impossible send a ABRT signal to
other process).

I'm getting it wrong?

Looking forward for your thoughts,

Luis

--
it is not enough to be compassionate. you must act.
h.h. the 14th dalai lama