Trap and multiple occurences

Hi all!

I am kind of new to ruby so forgive if this is really stupid…

I am experimenting with trapping signals on linux.

It seems like a ruby script can only handle one signal at a time.
While in the trap block, all further occurences of that same signal
are lost.
What I want to do is react differently if a, say, SIGUSR1 comes in
while the script is already in that signal’s trap block.
Is that at all possible?

A bit of background:
A have a script that parses some data and displays it on an external
lcd panel. The panel’s only button can bind a command. I have bound
“kill -SIGUSR1 (pidof myscript.rb)” to it.
Now I want to implement some kind of saveguard where the first press
displays a warning (“are you sure…?”) and the second while still
in the trap actually performs the function.

Thanks in advance and best regards,

Phil

Il giorno 05/nov/06, alle ore 02:35, Philipp T. ha scritto:

Hi all!

I am kind of new to ruby so forgive if this is really stupid…

I am experimenting with trapping signals on linux.

It seems like a ruby script can only handle one signal at a time.
While in the trap block, all further occurences of that same signal
are lost.

This is not just a ruby issue, it’s the way signal handlers work.
In C if you assign a function to a specific signal with signal(),
that function gets called when the signal is received and the program
flow continues when the function returns. If the same signal is
received while the function is running, it’s ignored (actually, I
think the function gets called again as soon as it returns).

Try this:

#include <stdio.h>
#include <unistd.h>
#include <signal.h>

void sighup_handler(int sig)
{
printf("Starting to process signal… ");
fflush(stdout);
sleep(5);
printf(“done.\n”);
}

int main(void)
{
signal(SIGINT, sighup_handler);
sleep(60);
return 0;
}

If you type Ctrl-C two times fast enough, you don’t interrupt the
function sighup_handler() itself.

in the trap actually performs the function.
A very good practice is writing signal handlers that just set a
global variable with the signal(s) received, and then check that
variable and actually do something from within the application main
loop.
There are many good reasons, some are here: http://www-128.ibm.com/
developerworks/linux/library/l-reent.html
(In fact I just googled for a link that explains what I’m thinking,
I’m lazy and sleepy so I didn’t read throughly that page and I hope
it really says what I mean :P)

On 05.11.2006 02:59, Gabriele M. wrote:

A very good practice is writing signal handlers that just set a global
variable with the signal(s) received, and then check that variable and
actually do something from within the application main loop.
There are many good reasons, some are here:
http://www-128.ibm.com/developerworks/linux/library/l-reent.html
(In fact I just googled for a link that explains what I’m thinking, I’m
lazy and sleepy so I didn’t read throughly that page and I hope it
really says what I mean :P)

The way I’d probably do it is to set up a Queue and have a reader thread
that will process signals placed into the queue. Something along the
lines like this

require ‘thread’

SIG_HANDLER = Queue.new

Thread.new do
while ( sig = SIG_HANDLER.deq )
print "SIGNAL: ", sig.inspect, “\n”
end
end

Signal.list.each do |name, sig|
Signal.trap sig do |s|
SIG_HANDLER.enq s
end
end

20.times do
puts “.”
sleep 1
end

Kind regards

robert

Hi!

Thus spake Gabriele M. on 11/05/2006 02:59 AM:

This is not just a ruby issue, it’s the way signal handlers work.

Thanks for the explanation and the link.
The days when I learned about unix system programming at the
university are obviously long past… :wink:

Well, I did just what you suggested and now handle signals via
global variables that get set/unset with each signal trappen.
That suits my needs since I do not expect too many signals
(keypresses) at once.

Regards,

Phil

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs