Ameyj Ameyj - 5 months ago 38
Perl Question

How to interpret si_status value

I am working with perl signal handler function for SIGCHLD signal handler on Ubuntu system.
In order to get sa_siginfo I am unpacking binary data I get from sigaction.Now I am getting si_code as "25". Looking at http://man7.org/linux/man-pages/man2/sigaction.2.html how to interpret that? It says it is not bitmask but a value.
Output I am getting is :

in order : signo sicode sigval sigerro sigpid siuid siaddr sistatus siband 17 0 1 0 21225 0 0 25 0


Signo,pid are unpacked correctly, I verified.I do not understand how I get 25 as "si_status"

POSIX::sigaction(
POSIX::SIGCHLD,
POSIX::SigAction->new(
sub{
my $args = \@_;
my $pid = unpack "x16S",$_[2];
my($signo,$sicode,$sigval,$sigerro,$sipid,$siuid,$siaddr,$sistatus,$siband) = unpack "iiiiisssii" ,$_[2];
print "\n in order : signo sicode sigval sigerro sigpid siuid siaddr sistatus siband ";
print (join (" ", $signo, $sicode , $sigval , $sigerro ,$sipid ,$siuid ,$siaddr ,$sistatus ,$siband));
}
0,
POSIX::SA_SIGINFO ),
);

Answer

You are getting si_status 25.

The si_status field contains the exit status of the child (if si_code is CLD_EXITED), or the signal number that caused the process to change state.

If si_code is CLD_EXITED, the child exited normally with exit code si_status.

If si_code isn't CLD_EXITED, the child was killed by signal si_status.

use strict;
use warnings;

use POSIX qw( );

use constant CLD_EXITED => 1;

my $done;
POSIX::sigaction(
    POSIX::SIGCHLD,
    POSIX::SigAction->new(
        sub {
            my ($signo, $errno, $code, $trapno, $pid, $uid, $status) =
                unpack("iiiiiii", $_[2]);

            print("$signo $errno $code $trapno $pid $uid $status\n");

            if ($code == CLD_EXITED) {
                if ($status) {
                    print("Process $pid exited with error $status\n");
                } else {
                    print("Process $pid completed successfully\n");
                }
            } else {
                print("Process $pid was killed by signal $status\n");
            }

            $done = 1;
        },
        0,
        POSIX::SA_SIGINFO,
    ),
);

{
    $done = 0;

    defined( my $pid = fork() )
        or die($!);

    if (!$pid) {
        exec('perl', '-e', 'exit(123)')
            or die($!);
    }
}

sleep(1) while !$done;

{
    $done = 0;

    defined( my $pid = fork() )
        or die($!);

    if (!$pid) {
        exec('perl', '-e', 'kill(TERM => $$)')
            or die($!);
    }
}

sleep(1) while !$done;

Output:

17 0 1 0 24351 2268518 123
Process 24351 exited with error 123
17 0 2 0 24352 2268518 15
Process 24352 was killed by signal 15