Signal handling in Perl

Guys,

I'm doing signal handling in Perl. I'm trying to catch ^C signal inside the script.

There two scripts : one shell script and one perl script.

The shell script calls the perl script.

For e.g. shell script a.sh and perl scipt sig.pl.

Shell script a.sh looks something like this :

#!/usr/bin/sh

# some code

sig.pl # Call perl script.

# some more code.

Perl script sig.pl looks something like this :

#!/usr/bin/perl

#some code

#signal handling

$SIG{'INT'} = 'Handler';

sub Handler {
print "Caught ^C \n";
exit (0);
}

# Some more code.

The point is : The signal gets caught in sig.pl, but it doesn't return to
a.sh, but instead returns to the command prompt.

I need to do more processing in shell script a.sh.

I've used die() as well but the result is the same.

Does anyone have any idea how to make the perl script return back to the parent shell script after catching the signal.

Thanks.

It's nothing to do with Perl, remember the shell script will get the ^C as well.

Add a trap handler to the shell script.

Hi.

This worked for me. Here's the simple driver script:

#!/bin/sh -

# @(#) s1       Demonstrate catching signal in perl, return to shell.

echo
echo " Calling perl script."

./user1

echo
echo " Returned from perl script."

exit 0

and the perl script it calls is:

#!/usr/bin/perl

$SIG{'INT'} = 'Handler';

#some code
print "\n Will wait for you to enter ^C ";
my ($junk) + <>;

#signal handling

sub Handler {
  print "\n Caught ^C \n";
  exit(0);
}

I moved the hash setting above the print and read. Executed twice, once with a simple RETURN and once with ^C yields:

user-problem/228 % ./s1

 Calling perl script.

 Will wait for you to enter ^C

 Returned from perl script.
user-problem/228 % ./s1

 Calling perl script.

 Will wait for you to enter ^C
 Caught ^C

 Returned from perl script.

So in both cases, control returns to the shell. My understanding is that signals are caught by the perl process, but not seen by the shell process, like most things for parent-child processes.

If you replaced the shell process with the perl script, say with exec, then the behavior described by the OP would be seen. I verified that with a separate script.

The Programming Perl 3rd, p 413, advises not doing much in the handler beyond setting a global variable, q.v. So I suppose it's possible that if you had a lot of code in the handler, you might run into trouble; PP suggests that a memory fault could occur, even for print statements.

Do this help or confuse the issue? ... cheers, drl

On Solaris all processes got the control C.

$ cat a.sh
#!/bin/sh

SCRIPT=$0

echo $0 started

mysig()
{
   echo $SCRIPT SIGINT
}

trap mysig 2

./b.sh

echo $0 exited
$ cat b.sh
#!/bin/sh

SCRIPT=$0

echo $0 started

mysig()
{
   echo $SCRIPT SIGINT
}

trap mysig 2

sleep 1000

echo $0 exited

results...

$ ./a.sh
./a.sh started
./b.sh started
^C./b.sh SIGINT
./b.sh exited
./a.sh SIGINT
./a.sh exited

Hi, porter.

Interesting. Thanks for the example.

So in this Solais situation the OP needs to add a trap to his shell script to ignore INT (SIGINT) signals.

I don't immediately see the advantage to this way of doing things, but the elegance of design often escapes me ... cheers, drl

The SIGINT goes to all processes associated with the same controlling terminal (ie the one you type control-C on).

Hi.

The results in post # 3 are from GNU/Linux Debian, kernel 2.6.11.

Another data point is for FreeBSD 4.11. It works the same way as it did on GNU/Linux ... cheers, drl