プロセスの終了状態を得る
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