【问题标题】:How to interpret si_status value如何解释 si_status 值
【发布时间】:2016-06-20 18:46:45
【问题描述】:

我正在为 Ubuntu 系统上的 SIGCHLD 信号处理程序使用 perl 信号处理程序函数。 为了获得 sa_siginfo,我正在解压缩从 sigaction 获得的二进制数据。现在我将 si_code 设为“25”。看着http://man7.org/linux/man-pages/man2/sigaction.2.html如何解释?它说它不是位掩码,而是一个值。 我得到的输出是:

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

Signo,pid 已正确解包,我已验证。我不明白如何将 25 设为“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 ),
  );

【问题讨论】:

    标签: linux perl signals


    【解决方案1】:

    si_status(不是si_code)是25

    si_status 字段包含子进程的退出状态(如果 si_codeCLD_EXITED),或导致进程更改状态的信号号。

    如果si_codeCLD_EXITED,则子进程正常退出,退出代码为si_status

    如果si_codeCLD_KILLED,则孩子被信号si_status 杀死。


    您的解包过程中存在一些错误。它们固定在下面,它显示了如何解释si_status

    use strict;
    use warnings;
    
    use IPC::Open3 qw( open3 );
    use POSIX qw( CLD_EXITED );
    
    my $done;
    
    sub sig_child {
        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;
    }
    
    POSIX::sigaction(
        POSIX::SIGCHLD,
        POSIX::SigAction->new(\&sig_child, 0, POSIX::SA_SIGINFO),
    );
    
    sub test {
        $done = 0;
        no warnings qw( once );
        open(local *CHILD_STDIN, '<', '/dev/null') or die($!);
        open3('<&CHILD_STDIN', '>&STDOUT', '>&STDERR', @_);
        sleep(1) while !$done;
    }
    
    test('perl', '-e', 'exit(123)');
    test('perl', '-e', 'kill(TERM => $$)');
    

    输出:

    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
    

    【讨论】:

    • 谢谢 :) .. 我想我对 si_code 和 si_status 感到困惑。手册页说这是孩子的退出代码。
    • 不,这根本不是手册页所说的,我已经证明它可以返回退出代码以外的其他内容。手册页实际上说的和我做的一样。请参阅我更新的答案,除了引用手册页并显示如何解释 si_status 之外,它还纠正了您解包中的一些错误。
    猜你喜欢
    • 1970-01-01
    • 2020-07-15
    • 2017-10-26
    • 1970-01-01
    • 2015-03-23
    • 2018-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多