summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Greene <jason@php.net>2001-07-06 05:48:52 +0000
committerJason Greene <jason@php.net>2001-07-06 05:48:52 +0000
commit0bfa63490d89b53fa00c08dccbcb173043d5659f (patch)
treec270e476c19f1a7c9fb5bf2236726124a75a186d
parent08d1178d6eb5fe49f540bd4e2703dacd4735cc5a (diff)
downloadphp-git-0bfa63490d89b53fa00c08dccbcb173043d5659f.tar.gz
Added wait.h functionality to pcntl
Added tests for such functionality Removed bogus files
-rwxr-xr-xext/pcntl/pcntl.c150
-rw-r--r--ext/pcntl/php_pcntl.h7
-rwxr-xr-xext/pcntl/test-pcntl.php2
-rwxr-xr-xext/pcntl/tests/001.exp0
-rwxr-xr-xext/pcntl/tests/001.out1
-rwxr-xr-xext/pcntl/tests/001.php14
-rw-r--r--ext/pcntl/tests/001.phpt76
7 files changed, 219 insertions, 31 deletions
diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c
index 81d074c3c5..fc015de34d 100755
--- a/ext/pcntl/pcntl.c
+++ b/ext/pcntl/pcntl.c
@@ -41,7 +41,13 @@ static int pcntl_zend_extension_active;
function_entry pcntl_functions[] = {
PHP_FE(pcntl_fork, NULL)
PHP_FE(pcntl_waitpid, NULL)
- PHP_FE(pcntl_signal, NULL)
+ PHP_FE(pcntl_signal, NULL)
+ PHP_FE(pcntl_wifexited, NULL)
+ PHP_FE(pcntl_wifstopped, NULL)
+ PHP_FE(pcntl_wifsignaled, NULL)
+ PHP_FE(pcntl_wexitstatus, NULL)
+ PHP_FE(pcntl_wtermsig, NULL)
+ PHP_FE(pcntl_wstopsig, NULL)
{NULL, NULL, NULL}
};
@@ -86,6 +92,16 @@ PCNTL_ZEND_EXT zend_extension pcntl_extension_entry = {
void php_register_signal_constants(INIT_FUNC_ARGS)
{
+
+ /* Wait Constants */
+#ifdef WNOHANG
+ REGISTER_LONG_CONSTANT("WNOHANG", (long) WNOHANG, CONST_CS | CONST_PERSISTENT);
+#endif
+#ifdef WUNTRACED
+ REGISTER_LONG_CONSTANT("WUNTRACED", (long) WUNTRACED, CONST_CS | CONST_PERSISTENT);
+#endif
+
+ /* Signal Constants */
REGISTER_LONG_CONSTANT("SIG_IGN", (long) SIG_IGN, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SIG_DFL", (long) SIG_DFL, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("SIG_ERR", (long) SIG_ERR, CONST_CS | CONST_PERSISTENT);
@@ -167,6 +183,7 @@ PHP_MINFO_FUNCTION(pcntl)
php_info_print_table_header(2, "pcntl support", "enabled");
php_info_print_table_end();
}
+
/* {{{ proto long pcntl_fork()
Forks the currently running process following the same behavior as the UNIX fork() system call*/
PHP_FUNCTION(pcntl_fork)
@@ -197,7 +214,11 @@ PHP_FUNCTION(pcntl_waitpid)
convert_to_long_ex(pid);
convert_to_long_ex(options);
- SEPARATE_ZVAL(status);
+ if (!ParameterPassedByReference(ht, 2)) {
+ php_error(E_WARNING, "Status not passed by reference in %s", get_active_function_name());
+ RETURN_FALSE;
+ }
+
convert_to_long_ex(status);
if (ZEND_NUM_ARGS()==2) temp_options=0;
@@ -209,6 +230,131 @@ PHP_FUNCTION(pcntl_waitpid)
}
/* }}} */
+/* {{{ proto bool pcntl_wifexited()
+ Returns true if the child status code represents a successful exit */
+PHP_FUNCTION(pcntl_wifexited)
+{
+#ifdef WIFEXITED
+ zval **status;
+ int status_word;
+
+ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(ZEND_NUM_ARGS(), &status) == FAILURE){
+ WRONG_PARAM_COUNT;
+ }
+
+ status_word = (int) Z_LVAL_PP(status);
+
+ if (WIFEXITED(status_word)) RETURN_TRUE;
+#endif
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto bool pcntl_wifstopped()
+ Returns true if the child status code represents a stopped process (WUNTRACED must have been used with waitpid) */
+PHP_FUNCTION(pcntl_wifstopped)
+{
+#ifdef WIFSTOPPED
+ zval **status;
+ int status_word;
+
+ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(ZEND_NUM_ARGS(), &status) == FAILURE){
+ WRONG_PARAM_COUNT;
+ }
+
+ status_word = (int) Z_LVAL_PP(status);
+
+ if (WIFSTOPPED(status_word)) RETURN_TRUE;
+#endif
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto bool pcntl_wifsignaled()
+ Returns true if the child status code represents a process that was terminated due to a signal */
+PHP_FUNCTION(pcntl_wifsignaled)
+{
+#ifdef WIFSIGNALED
+ zval **status;
+ int status_word;
+
+ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(ZEND_NUM_ARGS(), &status) == FAILURE){
+ WRONG_PARAM_COUNT;
+ }
+
+ status_word = (int) Z_LVAL_PP(status);
+
+ if (WIFSIGNALED(status_word)) RETURN_TRUE;
+#endif
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ proto long pcntl_wexitstatus()
+ Returns the status code of a child's exit */
+PHP_FUNCTION(pcntl_wexitstatus)
+{
+#ifdef WEXITSTATUS
+ zval **status;
+ int status_word;
+
+ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(ZEND_NUM_ARGS(), &status) == FAILURE){
+ WRONG_PARAM_COUNT;
+ }
+
+ status_word = (int) Z_LVAL_PP(status);
+
+ /* WEXITSTATUS only returns 8 bits so we *MUST* cast this to signed char
+ if you want to have valid negative exit codes */
+ RETURN_LONG((signed char) WEXITSTATUS(status_word));
+#else
+ RETURN_FALSE;
+#endif
+}
+/* }}} */
+
+/* {{{ proto long pcntl_wtermsig()
+ Returns the number of the signal that terminated the process who's status code is passed */
+PHP_FUNCTION(pcntl_wtermsig)
+{
+#ifdef WTERMSIG
+ zval **status;
+ int status_word;
+
+ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(ZEND_NUM_ARGS(), &status) == FAILURE){
+ WRONG_PARAM_COUNT;
+ }
+
+ status_word = (int) Z_LVAL_PP(status);
+
+ RETURN_LONG(WTERMSIG(status_word));
+#else
+ RETURN_FALSE;
+#endif
+}
+/* }}} */
+
+/* {{{ proto long pcntl_wstopsig()
+ Returns the number of the signal that caused the process to stop who's status code is passed */
+PHP_FUNCTION(pcntl_wstopsig)
+{
+#ifdef WSTOPSIG
+ zval **status;
+ int status_word;
+
+ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(ZEND_NUM_ARGS(), &status) == FAILURE){
+ WRONG_PARAM_COUNT;
+ }
+
+ status_word = (int) Z_LVAL_PP(status);
+
+ RETURN_LONG(WSTOPSIG(status_word));
+#else
+ RETURN_FALSE;
+#endif
+}
+/* }}} */
+
/* {{{ proto bool pcntl_signal(long signo, mixed handle)
Assigns a system signal handler to a php function */
PHP_FUNCTION(pcntl_signal)
diff --git a/ext/pcntl/php_pcntl.h b/ext/pcntl/php_pcntl.h
index be570ea110..347c77f275 100644
--- a/ext/pcntl/php_pcntl.h
+++ b/ext/pcntl/php_pcntl.h
@@ -19,6 +19,7 @@
#ifndef PHP_PCNTL_H
#define PHP_PCNTL_H
+#include <sys/wait.h>
#include "php_signal.h"
#include "zend_extensions.h"
extern zend_module_entry pcntl_module_entry;
@@ -38,6 +39,12 @@ PHP_MINFO_FUNCTION(pcntl);
PHP_FUNCTION(pcntl_fork);
PHP_FUNCTION(pcntl_waitpid);
+PHP_FUNCTION(pcntl_wifexited);
+PHP_FUNCTION(pcntl_wifstopped);
+PHP_FUNCTION(pcntl_wifsignaled);
+PHP_FUNCTION(pcntl_wexitstatus);
+PHP_FUNCTION(pcntl_wtermsig);
+PHP_FUNCTION(pcntl_wstopsig);
PHP_FUNCTION(pcntl_signal);
static void pcntl_signal_handler(int);
diff --git a/ext/pcntl/test-pcntl.php b/ext/pcntl/test-pcntl.php
index c611bfe504..41334ba814 100755
--- a/ext/pcntl/test-pcntl.php
+++ b/ext/pcntl/test-pcntl.php
@@ -31,5 +31,5 @@ if ($pid==0) {
posix_kill($pid,SIGUSR1);
sleep(1);
print "Parent: Sending SIGALRM to Child\n";
- pcntl_waitpid($pid, $status, $options);
+ pcntl_waitpid($pid, &$status, $options);
}
diff --git a/ext/pcntl/tests/001.exp b/ext/pcntl/tests/001.exp
deleted file mode 100755
index e69de29bb2..0000000000
--- a/ext/pcntl/tests/001.exp
+++ /dev/null
diff --git a/ext/pcntl/tests/001.out b/ext/pcntl/tests/001.out
deleted file mode 100755
index efbc584688..0000000000
--- a/ext/pcntl/tests/001.out
+++ /dev/null
@@ -1 +0,0 @@
-pcntl extension is available \ No newline at end of file
diff --git a/ext/pcntl/tests/001.php b/ext/pcntl/tests/001.php
deleted file mode 100755
index d3be528a2a..0000000000
--- a/ext/pcntl/tests/001.php
+++ /dev/null
@@ -1,14 +0,0 @@
-<?php
-echo "pcntl extension is available";
-/*
- you can add regression tests for your extension here
-
- the output of your test code has to be equal to the
- text in the --EXPECT-- section below for the tests
- to pass, differences between the output and the
- expected text are interpreted as failure
-
- see php4/tests/README for further information on
- writing regression tests
-*/
-?>
diff --git a/ext/pcntl/tests/001.phpt b/ext/pcntl/tests/001.phpt
index af214d0f62..d2f9923b95 100644
--- a/ext/pcntl/tests/001.phpt
+++ b/ext/pcntl/tests/001.phpt
@@ -1,22 +1,72 @@
--TEST--
-Check for pcntl presence
+Test pcntl wait functionality
--SKIPIF--
<?php if (!extension_loaded("pcntl")) print "skip"; ?>
--POST--
--GET--
--FILE--
<?php
-echo "pcntl extension is available";
-/*
- you can add regression tests for your extension here
-
- the output of your test code has to be equal to the
- text in the --EXPECT-- section below for the tests
- to pass, differences between the output and the
- expected text are interpreted as failure
-
- see php4/tests/README for further information on
- writing regression tests
-*/
+function test_exit_waits(){
+ print "\n\nTesting pcntl_wifexited and wexitstatus....";
+
+ $pid=pcntl_fork();
+ if ($pid==0) {
+ sleep(1);
+ exit(-1);
+ } else {
+ $options=0;
+ pcntl_waitpid($pid, &$status, $options);
+ if ( pcntl_wifexited($status) ) print "\nExited With: ". pcntl_wexitstatus($status);
+ }
+}
+
+function test_exit_signal(){
+ print "\n\nTesting pcntl_wifsignaled....";
+
+ $pid=pcntl_fork();
+
+ if ($pid==0) {
+ sleep(10);
+ exit;
+ } else {
+ $options=0;
+ posix_kill($pid, SIGTERM);
+ pcntl_waitpid($pid, &$status, $options);
+ if ( pcntl_wifsignaled($status) ) print "\nProcess was terminated by signal : ". pcntl_wtermsig($status);
+ }
+}
+
+
+function test_stop_signal(){
+ print "\n\nTesting pcntl_wifstopped and pcntl_wstopsig....";
+
+ $pid=pcntl_fork();
+
+ if ($pid==0) {
+ sleep(1);
+ exit;
+ } else {
+ $options=WUNTRACED;
+ posix_kill($pid, SIGSTOP);
+ pcntl_waitpid($pid, &$status, $options);
+ if ( pcntl_wifstopped($status) ) print "\nProcess was stoped by signal : ". pcntl_wstopsig($status);
+ posix_kill($pid, SIGCONT);
+ }
+}
+
+print "Staring wait.h tests....";
+test_exit_waits();
+test_exit_signal();
+test_stop_signal();
?>
--EXPECT--
+Staring wait.h tests....
+
+Testing pcntl_wifexited and wexitstatus....-1
+Exited With: -1
+
+Testing pcntl_wifsignaled....
+Process was terminated by signal : 15
+
+Testing pcntl_wifstopped and pcntl_wstopsig....
+Process was stoped by signal : 19