プロセスの終了状態を得る

C と同じだった。

#!/usr/bin/perl
use strict;
use warnings;
use POSIX;

# http://www.linux.or.jp/JM/html/LDP_man-pages/man2/wait.2.html

print '--- exit(5)', $/;
check_exit_macro( sub { exit 5 } );

# 子プロセスが自分自身にシグナル INT
print $/;
print '--- signal INT', $/;
check_exit_macro( sub { kill 'INT', $$ } );

# 子プロセスが自分自身にシグナル STOP
# Windows では動かんかも
print $/;
print '--- signal STOP', $/;
check_exit_macro( sub { kill 'STOP', $$ } );

# system ls
print $/;
print '--- system ls', $/;
print_exit_status(system 'ls > /dev/null');

# system unknown command
print $/;
print '--- system unknown command', $/;
print_exit_status(system 'unknown_command 2> /dev/null');

sub print_exit_status {
    my $status = shift;

    # 子プロセスが正常に終了した場合に真を返す。「正常に」とは、 exit (3)
    # か_exit (2) が呼び出された場合、もしくは main () から復帰した場合であ
    # る。
    print 'WIFEXITED = ', WIFEXITED($status), $/;

    # exit ステータスから exit 値を取得する場合は 256 で割る必要がある。あ
    # るいは、 WEXITSTATUS を使う
    if ( WIFEXITED($status) ) {
        print '  Exit status = ', $status / 256, $/;
        print '  WEXITSTATUS = ', WEXITSTATUS($status), $/;
    }

    # 子プロセスがシグナルにより終了した場合に真を返す
    print 'WIFSIGNALED = ', WIFSIGNALED($status), $/;

    # 子プロセス終了の原因となったシグナルの番号を返す。このマクロを使用す
    # るのは WIFSIGNALED が真を返した場合だけにすべきである
    print '  WTERMSIG = ', WTERMSIG($status), $/ if WIFSIGNALED($status);

    # 子プロセスがシグナルの配送により停止した場合に真を返す
    print 'WIFSTOPPED = ', WIFSTOPPED($status), $/;

    # 子プロセスを停止させたシグナルの番号を返す。このマクロを使用するのは
    # WIFSTOPPED が 0 以外を返した場合だけにすべきである
    print '  WSTOPSIG = ', WSTOPSIG($status), $/ if WIFSTOPPED($status);
}

sub check_exit_macro {
    my $exit_func = shift;

    if ( my $pid = fork ) {    # 親プロセス
         # 子プロセス終了待ち。子プロセスが停止した場合でも復帰する (WUNTRACED)
        waitpid -1, WUNTRACED;
        my $status = $?;

        print_exit_status($status);

    }
    elsif ( defined $pid ) {    # 子プロセス
        $exit_func->();
    }
    else {
        die "Error Fork : $pid";
    }
}
--- exit(5)
WIFEXITED = 1
  Exit status = 5
  WEXITSTATUS = 5
WIFSIGNALED = 0
WIFSTOPPED = 0

--- signal INT
WIFEXITED = 0
WIFSIGNALED = 1
  WTERMSIG = 2
WIFSTOPPED = 0

--- signal STOP
WIFEXITED = 0
WIFSIGNALED = 0
WIFSTOPPED = 1
  WSTOPSIG = 19

--- system ls
WIFEXITED = 1
  Exit status = 0
  WEXITSTATUS = 0
WIFSIGNALED = 0
WIFSTOPPED = 0

--- system unknown command
WIFEXITED = 1
  Exit status = 127
  WEXITSTATUS = 127
WIFSIGNALED = 0
WIFSTOPPED = 0