jefftanner Posted January 8, 2008 Share Posted January 8, 2008 QUESTION: If pcntl_exec() fails (returns FALSE), then is there any way to get the reason (exit code) why what executed had failed? To start, if I try to execute an non-existent command "garbage" in the command line, then it fails with an exit code of 127: $ garbage bash: garbage: command not found $ echo $? 127 Next, I have a very simple php script test_exit.php: <?php exit(127); ?> And I try to execute in the command line, then it also fails with an exit code of 127: $ php test_exit.php $ echo $? 127 Now I want to try the previous executions using PHP process controls: pcntl_fork, pcntl_exec, and pcntl_wait, etc... My PHP process controls test script is as follows test_pcntl.php: <?php switch ($cid = pcntl_fork()) { case -1: die('could not fork'); case 0: // Child Fork, set alarm and execute command pcntl_alarm(60); $cid = getmypid(); print "we are in pid child $cid BEFORE\n"; $result = pcntl_exec($pathBinaryExecutable, $args); print "we are in pid child $cid AFTER, indicating that pcntl_exec() failed.\n"; print "pid child $cid pcntl_exec() result: " . var_export( $result, TRUE ) . "\n"; break; default: // Parent Fork, wait for return of child process $cid = pcntl_wait($status); if(pcntl_wifexited($status)) { $exit_code = pcntl_wexitstatus($status); print "pid child $cid returned exit code: $exit_code.\n"; } else if (pcntl_wifstopped($status)) { $stop_signal = pcntl_wstopsig($status); print "pid child $cid is currently stopped: $stop_signal.\n"; } else if (pcntl_wifsignaled($status)) { $terminate_signal = pcntl_wtermsig($status); print "pid child $cid terminated due to a signal $terminate_signal.\n"; } else { print "child $cid was unnaturally terminated.\n"; } } ?> If in the Child fork, pcntl_exec() is passed php script test_exit.php: $pathBinaryExecutable = "/usr/local/bin/php"; $args = array( "/home/jeff/public_html/php/test_exit.php" ); Then execution of this test script will return the expected exit code of 127: $ php test_pcntl.php we are in pid child 23512 BEFORE we are in parent 23511 pre wait child 23512 BEFORE we are in parent 23511 post wait child 23512 AFTER pid child 23512 -- status 32512. pid child 23512 returned exit code: 127. Now if in the Child fork, pcntl_exec() is passed the non-existent command garbage: $pathBinaryExecutable = "garbage"; $args = array(); Then execution of this test script does not return the expected exit code of 127: $ php test_pcntl.php we are in pid child 23609 BEFORE we are in pid child 23609 AFTER, indicating that pcntl_exec() failed. pid child 23609 pcntl_exec() result: false we are in parent 23608 pre wait child 23609 BEFORE we are in parent 23608 post wait child 23609 AFTER pid child 23609 -- status 0. pid child 23609 returned exit code: 0 So, at this point, the parent process thinks that the child process has succeeded because the exit code is zero (0), and not the expected 127. What can I do to my code to determine why pcntl_exec() had failed, AND to determine why pcntl_wait() did not return an exit status of 127? Thanks -- Jeff in Seattle Quote Link to comment https://forums.phpfreaks.com/topic/85097-pcntl_execgarbage-and-pcntl_waitstatus/ Share on other sites More sharing options...
btherl Posted January 9, 2008 Share Posted January 9, 2008 I think that code of 127 is generated by the shell itself. If you try to execute a program that doesn't exist, then of course no program will be executed. If no program is executed, what is the exit status of the program that didn't run? There is none. So the shell creates a "dummy" exit status of 127, to allow scripts to know that the command failed. To replicate this in php, you would have your child return the dummy status of 127 of the exec fails. Quote Link to comment https://forums.phpfreaks.com/topic/85097-pcntl_execgarbage-and-pcntl_waitstatus/#findComment-434115 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.