Skip to content

Instantly share code, notes, and snippets.

@auroraeosrose
Created September 24, 2014 18:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save auroraeosrose/b17c03728ccda9162d2b to your computer and use it in GitHub Desktop.
Save auroraeosrose/b17c03728ccda9162d2b to your computer and use it in GitHub Desktop.
That pcntl patch I've been sitting on
Index: config.w32
===================================================================
--- config.w32 (revision 0)
+++ config.w32 (revision 0)
@@ -0,0 +1,8 @@
+// $Id: config.w32 264053 2008-08-01 21:20:08Z pajoye $
+// vim:ft=javascript
+
+ARG_ENABLE("pcntl", "process control support", "no");
+
+if (PHP_PCNTL != "no") {
+ EXTENSION("pcntl", "pcntl.c pcntl_win.c php_signal.c");
+}
Index: pcntl.c
===================================================================
--- pcntl.c (revision 290360)
+++ pcntl.c (working copy)
@@ -17,16 +17,6 @@
*/
/* $Id$ */
-
-#define PCNTL_DEBUG 0
-
-#if PCNTL_DEBUG
-#define DEBUG_OUT printf("DEBUG: ");printf
-#define IF_DEBUG(z) z
-#else
-#define IF_DEBUG(z)
-#endif
-
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@@ -34,11 +24,15 @@
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
+
+#ifdef _MSC_VER
+# include "pcntl_win.h"
+#endif
#include "php_pcntl.h"
#include "php_signal.h"
#include "php_ticks.h"
-#if HAVE_GETPRIORITY || HAVE_SETPRIORITY || HAVE_WAIT3
+#if !defined(_MSC_VER) && (HAVE_GETPRIORITY || HAVE_SETPRIORITY || HAVE_WAIT3)
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
@@ -48,9 +42,6 @@
static PHP_GINIT_FUNCTION(pcntl);
/* {{{ arginfo */
-ZEND_BEGIN_ARG_INFO(arginfo_pcntl_void, 0)
-ZEND_END_ARG_INFO()
-
ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_waitpid, 0, 0, 2)
ZEND_ARG_INFO(0, pid)
ZEND_ARG_INFO(1, status)
@@ -120,6 +111,17 @@
ZEND_ARG_INFO(0, seconds)
ZEND_END_ARG_INFO()
+ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_spawn, 0, 0, 1)
+ ZEND_ARG_INFO(0, path)
+ ZEND_ARG_INFO(0, mode)
+ ZEND_ARG_INFO(0, args)
+ ZEND_ARG_INFO(0, envs)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_pcntl_raise, 0)
+ ZEND_ARG_INFO(0, signal)
+ZEND_END_ARG_INFO()
+
#ifdef HAVE_GETPRIORITY
ZEND_BEGIN_ARG_INFO_EX(arginfo_pcntl_getpriority, 0, 0, 0)
ZEND_ARG_INFO(0, pid)
@@ -137,19 +139,24 @@
/* }}} */
const zend_function_entry pcntl_functions[] = {
- PHP_FE(pcntl_fork, arginfo_pcntl_void)
- PHP_FE(pcntl_waitpid, arginfo_pcntl_waitpid)
- PHP_FE(pcntl_wait, arginfo_pcntl_wait)
- PHP_FE(pcntl_signal, arginfo_pcntl_signal)
- PHP_FE(pcntl_signal_dispatch, arginfo_pcntl_void)
- PHP_FE(pcntl_wifexited, arginfo_pcntl_wifexited)
- PHP_FE(pcntl_wifstopped, arginfo_pcntl_wifstopped)
- PHP_FE(pcntl_wifsignaled, arginfo_pcntl_wifsignaled)
- PHP_FE(pcntl_wexitstatus, arginfo_pcntl_wifexitstatus)
- PHP_FE(pcntl_wtermsig, arginfo_pcntl_wtermsig)
- PHP_FE(pcntl_wstopsig, arginfo_pcntl_wstopsig)
- PHP_FE(pcntl_exec, arginfo_pcntl_exec)
- PHP_FE(pcntl_alarm, arginfo_pcntl_alarm)
+#ifdef fork
+ PHP_FE(pcntl_fork, NULL)
+#endif
+ PHP_FE(pcntl_waitpid, arginfo_pcntl_waitpid)
+ PHP_FE(pcntl_wait, arginfo_pcntl_wait)
+ PHP_FE(pcntl_signal, arginfo_pcntl_signal)
+ PHP_FE(pcntl_signal_dispatch, NULL)
+ PHP_FE(pcntl_wifexited, arginfo_pcntl_wifexited)
+ PHP_FE(pcntl_wifstopped, arginfo_pcntl_wifstopped)
+ PHP_FE(pcntl_wifsignaled, arginfo_pcntl_wifsignaled)
+ PHP_FE(pcntl_wexitstatus, arginfo_pcntl_wifexitstatus)
+ PHP_FE(pcntl_wtermsig, arginfo_pcntl_wtermsig)
+ PHP_FE(pcntl_wstopsig, arginfo_pcntl_wstopsig)
+ PHP_FE(pcntl_exec, arginfo_pcntl_exec)
+ //PHP_FE(pcntl_alarm, arginfo_pcntl_alarm)
+ PHP_FE(pcntl_spawn, arginfo_pcntl_spawn)
+ PHP_FE(pcntl_raise, arginfo_pcntl_raise)
+ PHP_FE(pcntl_executable, NULL)
#ifdef HAVE_GETPRIORITY
PHP_FE(pcntl_getpriority, arginfo_pcntl_getpriority)
#endif
@@ -171,15 +178,15 @@
"pcntl",
pcntl_functions,
PHP_MINIT(pcntl),
- PHP_MSHUTDOWN(pcntl),
+ NULL, /* MSHUTDOWN */
PHP_RINIT(pcntl),
PHP_RSHUTDOWN(pcntl),
PHP_MINFO(pcntl),
NO_VERSION_YET,
PHP_MODULE_GLOBALS(pcntl),
PHP_GINIT(pcntl),
+ NULL, /* GSHUTDOWN */
NULL,
- NULL,
STANDARD_MODULE_PROPERTIES_EX
};
@@ -192,7 +199,6 @@
void php_register_signal_constants(INIT_FUNC_ARGS)
{
-
/* Wait Constants */
#ifdef WNOHANG
REGISTER_LONG_CONSTANT("WNOHANG", (long) WNOHANG, CONST_CS | CONST_PERSISTENT);
@@ -200,28 +206,53 @@
#ifdef WUNTRACED
REGISTER_LONG_CONSTANT("WUNTRACED", (long) WUNTRACED, CONST_CS | CONST_PERSISTENT);
#endif
+#ifdef WCONTINUED
+ REGISTER_LONG_CONSTANT("WCONTINUED", (long) WCONTINUED, CONST_CS | CONST_PERSISTENT);
+#endif
+ /* Spawn Constants */
+ REGISTER_LONG_CONSTANT("SPAWN_NOWAIT", 0, CONST_CS | CONST_PERSISTENT);
+ REGISTER_LONG_CONSTANT("SPAWN_WAIT", 1, CONST_CS | CONST_PERSISTENT);
+
/* 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);
+#ifdef SIGHUP
REGISTER_LONG_CONSTANT("SIGHUP", (long) SIGHUP, CONST_CS | CONST_PERSISTENT);
+#endif
REGISTER_LONG_CONSTANT("SIGINT", (long) SIGINT, CONST_CS | CONST_PERSISTENT);
+#ifdef SIGQUIT
REGISTER_LONG_CONSTANT("SIGQUIT", (long) SIGQUIT, CONST_CS | CONST_PERSISTENT);
+#endif
REGISTER_LONG_CONSTANT("SIGILL", (long) SIGILL, CONST_CS | CONST_PERSISTENT);
+#ifdef SIGTRAP
REGISTER_LONG_CONSTANT("SIGTRAP", (long) SIGTRAP, CONST_CS | CONST_PERSISTENT);
+#endif
REGISTER_LONG_CONSTANT("SIGABRT", (long) SIGABRT, CONST_CS | CONST_PERSISTENT);
#ifdef SIGIOT
REGISTER_LONG_CONSTANT("SIGIOT", (long) SIGIOT, CONST_CS | CONST_PERSISTENT);
#endif
+#ifdef SIGBUS
REGISTER_LONG_CONSTANT("SIGBUS", (long) SIGBUS, CONST_CS | CONST_PERSISTENT);
+#endif
REGISTER_LONG_CONSTANT("SIGFPE", (long) SIGFPE, CONST_CS | CONST_PERSISTENT);
+#ifdef SIGKILL
REGISTER_LONG_CONSTANT("SIGKILL", (long) SIGKILL, CONST_CS | CONST_PERSISTENT);
+#endif
+#ifdef SIGUSR1
REGISTER_LONG_CONSTANT("SIGUSR1", (long) SIGUSR1, CONST_CS | CONST_PERSISTENT);
+#endif
REGISTER_LONG_CONSTANT("SIGSEGV", (long) SIGSEGV, CONST_CS | CONST_PERSISTENT);
+#ifdef SIGUSR2
REGISTER_LONG_CONSTANT("SIGUSR2", (long) SIGUSR2, CONST_CS | CONST_PERSISTENT);
+#endif
+#ifdef SIGPIPE
REGISTER_LONG_CONSTANT("SIGPIPE", (long) SIGPIPE, CONST_CS | CONST_PERSISTENT);
+#endif
+#ifdef SIGALRM
REGISTER_LONG_CONSTANT("SIGALRM", (long) SIGALRM, CONST_CS | CONST_PERSISTENT);
+#endif
REGISTER_LONG_CONSTANT("SIGTERM", (long) SIGTERM, CONST_CS | CONST_PERSISTENT);
#ifdef SIGSTKFLT
REGISTER_LONG_CONSTANT("SIGSTKFLT",(long) SIGSTKFLT, CONST_CS | CONST_PERSISTENT);
@@ -232,21 +263,45 @@
#ifdef SIGCHLD
REGISTER_LONG_CONSTANT("SIGCHLD", (long) SIGCHLD, CONST_CS | CONST_PERSISTENT);
#endif
+#ifdef SIGCONT
REGISTER_LONG_CONSTANT("SIGCONT", (long) SIGCONT, CONST_CS | CONST_PERSISTENT);
+#endif
+#ifdef SIGSTOP
REGISTER_LONG_CONSTANT("SIGSTOP", (long) SIGSTOP, CONST_CS | CONST_PERSISTENT);
+#endif
+#ifdef SIGTSTP
REGISTER_LONG_CONSTANT("SIGTSTP", (long) SIGTSTP, CONST_CS | CONST_PERSISTENT);
+#endif
+#ifdef SIGTTIN
REGISTER_LONG_CONSTANT("SIGTTIN", (long) SIGTTIN, CONST_CS | CONST_PERSISTENT);
+#endif
+#ifdef SIGTTOU
REGISTER_LONG_CONSTANT("SIGTTOU", (long) SIGTTOU, CONST_CS | CONST_PERSISTENT);
+#endif
+#ifdef SIGURG
REGISTER_LONG_CONSTANT("SIGURG", (long) SIGURG , CONST_CS | CONST_PERSISTENT);
+#endif
+#ifdef SIGXCPU
REGISTER_LONG_CONSTANT("SIGXCPU", (long) SIGXCPU, CONST_CS | CONST_PERSISTENT);
+#endif
+#ifdef SIGXFSZ
REGISTER_LONG_CONSTANT("SIGXFSZ", (long) SIGXFSZ, CONST_CS | CONST_PERSISTENT);
+#endif
+#ifdef SIGVTALRM
REGISTER_LONG_CONSTANT("SIGVTALRM",(long) SIGVTALRM, CONST_CS | CONST_PERSISTENT);
+#endif
+#ifdef SIGPROF
REGISTER_LONG_CONSTANT("SIGPROF", (long) SIGPROF, CONST_CS | CONST_PERSISTENT);
+#endif
+#ifdef SIGWINCH
REGISTER_LONG_CONSTANT("SIGWINCH", (long) SIGWINCH, CONST_CS | CONST_PERSISTENT);
+#endif
#ifdef SIGPOLL
REGISTER_LONG_CONSTANT("SIGPOLL", (long) SIGPOLL, CONST_CS | CONST_PERSISTENT);
#endif
+#ifdef SIGIO
REGISTER_LONG_CONSTANT("SIGIO", (long) SIGIO, CONST_CS | CONST_PERSISTENT);
+#endif
#ifdef SIGPWR
REGISTER_LONG_CONSTANT("SIGPWR", (long) SIGPWR, CONST_CS | CONST_PERSISTENT);
#endif
@@ -403,9 +458,9 @@
#ifdef BUS_OBJERR
REGISTER_LONG_CONSTANT("BUS_OBJERR", BUS_OBJERR, CONST_CS | CONST_PERSISTENT);
#endif
-#endif /* HAVE_SIGWAITINFO && HAVE_SIGTIMEDWAIT */
- /* }}} */
+#endif /* HAVE_SIGWAITINFO && HAVE_SIGTIMEDWAIT */
}
+/* }}} */
static PHP_GINIT_FUNCTION(pcntl)
{
@@ -427,11 +482,6 @@
return SUCCESS;
}
-PHP_MSHUTDOWN_FUNCTION(pcntl)
-{
- return SUCCESS;
-}
-
PHP_RSHUTDOWN_FUNCTION(pcntl)
{
struct php_pcntl_pending_signal *sig;
@@ -451,7 +501,6 @@
}
return SUCCESS;
}
-
PHP_MINFO_FUNCTION(pcntl)
{
php_info_print_table_start();
@@ -459,8 +508,10 @@
php_info_print_table_end();
}
+#ifdef fork
/* {{{ proto int pcntl_fork(void)
- Forks the currently running process following the same behavior as the UNIX fork() system call*/
+ Forks the currently running process following the same behavior as the UNIX fork() system call
+ not available on windows */
PHP_FUNCTION(pcntl_fork)
{
pid_t id;
@@ -473,6 +524,7 @@
RETURN_LONG((long) id);
}
/* }}} */
+#endif
/* {{{ proto int pcntl_alarm(int seconds)
Set an alarm clock for delivery of a signal*/
@@ -512,7 +564,7 @@
/* }}} */
/* {{{ proto int pcntl_wait(int &status)
- Waits on or returns the status of a forked child as defined by the waitpid() system call */
+ Waits on or returns the status of a forked child as defined by the wait() system call */
PHP_FUNCTION(pcntl_wait)
{
long options = 0;
@@ -778,6 +830,7 @@
if (Z_TYPE_P(handle)==IS_LONG) {
if (Z_LVAL_P(handle)!= (long) SIG_DFL && Z_LVAL_P(handle) != (long) SIG_IGN) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid value for handle argument specified");
+ RETURN_FALSE;
}
if (php_signal(signo, (Sigfunc *) Z_LVAL_P(handle), (int) restart_syscalls) == SIG_ERR) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error assigning signal");
@@ -793,7 +846,7 @@
}
efree(func_name);
- /* Add the function name to our signal table */
+ /* Add the function name to our signal table */
zend_hash_index_update(&PCNTL_G(php_signal_table), signo, (void **) &handle, sizeof(zval *), (void **) &dest_handle);
if (dest_handle) zval_add_ref(dest_handle);
@@ -809,11 +862,29 @@
Dispatch signals to signal handlers */
PHP_FUNCTION(pcntl_signal_dispatch)
{
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) {
+ return;
+ }
+
pcntl_signal_dispatch();
RETURN_TRUE;
}
/* }}} */
+/* {{{ proto bool pcntl_raise()
+ calls raise, allowing signals to be sent without posix extension or kill */
+PHP_FUNCTION(pcntl_raise)
+{
+ long signo;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &signo) == FAILURE) {
+ return;
+ }
+
+ RETURN_LONG(raise(signo));
+}
+/* }}} */
+
#ifdef HAVE_SIGPROCMASK
/* {{{ proto bool pcntl_sigprocmask(int how, array set[, array &oldset])
Examine and change blocked signals */
@@ -1073,6 +1144,227 @@
/* }}} */
#endif
+/* {{{ proto int pcntl_spawn(string path [, int mode, [array args [, array envs]]])
+ implemented as fork + exec for most systems
+ roughly equivalent to fork + exec, this uses win32 api calls on windows */
+PHP_FUNCTION(pcntl_spawn)
+{
+ zval *args = NULL, *envs = NULL;
+ zval **element;
+ HashTable *args_hash, *envs_hash;
+ int argc = 0, argi = 0;
+ int envc = 0, envi = 0;
+ int return_val = 0;
+ char **argv = NULL, **envp = NULL;
+ char **current_arg, **pair;
+ int pair_length;
+ char *key;
+ uint key_length;
+ char *path;
+ int path_len;
+ ulong key_num;
+ long mode = _P_NOWAIT;
+ intptr_t pid;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|laa", &path, &path_len, &mode, &args, &envs) == FAILURE) {
+ return;
+ }
+
+ if (ZEND_NUM_ARGS() > 2) {
+ /* Build argumnent list */
+ args_hash = HASH_OF(args);
+ argc = zend_hash_num_elements(args_hash);
+
+ argv = safe_emalloc((argc + 2), sizeof(char *), 0);
+ *argv = path;
+ for ( zend_hash_internal_pointer_reset(args_hash), current_arg = argv+1;
+ (argi < argc && (zend_hash_get_current_data(args_hash, (void **) &element) == SUCCESS));
+ (argi++, current_arg++, zend_hash_move_forward(args_hash)) ) {
+
+ convert_to_string_ex(element);
+ *current_arg = Z_STRVAL_PP(element);
+ }
+ *(current_arg) = NULL;
+ } else {
+ argv = emalloc(2 * sizeof(char *));
+ *argv = path;
+ *(argv+1) = NULL;
+ }
+
+ if ( ZEND_NUM_ARGS() == 4 ) {
+ /* Build environment pair list */
+ envs_hash = HASH_OF(envs);
+ envc = zend_hash_num_elements(envs_hash);
+
+ envp = safe_emalloc((envc + 1), sizeof(char *), 0);
+ for ( zend_hash_internal_pointer_reset(envs_hash), pair = envp;
+ (envi < envc && (zend_hash_get_current_data(envs_hash, (void **) &element) == SUCCESS));
+ (envi++, pair++, zend_hash_move_forward(envs_hash)) ) {
+ switch (return_val = zend_hash_get_current_key_ex(envs_hash, &key, &key_length, &key_num, 0, NULL)) {
+ case HASH_KEY_IS_LONG:
+ key = emalloc(101);
+ snprintf(key, 100, "%ld", key_num);
+ key_length = strlen(key);
+ break;
+ case HASH_KEY_NON_EXISTANT:
+ pair--;
+ continue;
+ }
+
+ convert_to_string_ex(element);
+
+ /* Length of element + equal sign + length of key + null */
+ pair_length = Z_STRLEN_PP(element) + key_length + 2;
+ *pair = emalloc(pair_length);
+ strlcpy(*pair, key, key_length);
+ strlcat(*pair, "=", pair_length);
+ strlcat(*pair, Z_STRVAL_PP(element), pair_length);
+
+ /* Cleanup */
+ if (return_val == HASH_KEY_IS_LONG) efree(key);
+ }
+ *(pair) = NULL;
+#ifdef _MSC_VER
+ /* Verify our modes, wait and nowait are supported */
+ if (mode) {
+ mode = _P_WAIT;
+ } else {
+ mode = _P_NOWAIT;
+ }
+ /* spawn - NOTICE, with wait mode you will get back EXIT STATUS, with nowait you get PID */
+ pid = spawnve(mode, path, argv, envp);
+
+ if (pid < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error has occured: (errno %d) %s", errno, strerror(errno));
+ }
+#else
+ int status;
+
+ /* Do the fork */
+ switch(pid = fork()){
+ case -1:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error %d", errno);
+ case 0 :
+ /* This is the child, do the exec */
+ if (execve(path, argv, envp) == -1) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error has occured: (errno %d) %s", errno, strerror(errno));
+ }
+ default:
+ /* If wait is on, then wait and assign the return status, otherwise ignore */
+ if (mode) {
+ waitpid((pid_t) pid, &status, NULL);
+ pid = status;
+ }
+ }
+#endif
+ /* Cleanup */
+ for (pair = envp; *pair != NULL; pair++) efree(*pair);
+ efree(envp);
+ } else {
+#ifdef _MSC_VER
+ /* Verify our modes, wait and nowait are supported */
+ if (mode) {
+ mode = _P_WAIT;
+ } else {
+ mode = _P_NOWAIT;
+ }
+ /* spawn - NOTICE, with wait mode you will get back EXIT STATUS, with nowait you get PID */
+ pid = spawnv(mode, path, argv);
+
+ if (pid < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error has occured: (errno %d) %s", errno, strerror(errno));
+ }
+
+ if (!mode) {
+ pid = GetProcessId(pid);
+ }
+#else
+ int status;
+
+ /* Do the fork */
+ switch(pid = fork()){
+ case -1:
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error %d", errno);
+ case 0 :
+ /* This is the child, do the exec */
+ if (execv(path, argv) == -1) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error has occured: (errno %d) %s", errno, strerror(errno));
+ }
+ default:
+ /* If wait is on, then wait and assign the return status, otherwise ignore */
+ if (mode) {
+ waitpid((pid_t) pid, &status, NULL);
+ pid = status;
+ }
+ }
+#endif
+ }
+
+ efree(argv);
+
+ RETURN_LONG(pid);
+}
+/* }}} */
+
+/* {{{ proto string pcntl_executable()
+ returns the current binary executable - may NOT give you what you expect with some SAPIS */
+PHP_FUNCTION(pcntl_executable)
+{
+ char *binary_location;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "") == FAILURE) {
+ return;
+ }
+
+#ifdef PHP_WIN32
+ binary_location = (char *) emalloc(MAXPATHLEN);
+ if (GetModuleFileName(0, binary_location, MAXPATHLEN) == 0) {
+ efree(binary_location);
+ binary_location = NULL;
+ }
+#else
+ if (sapi_module.executable_location) {
+ binary_location = (char *)emalloc(MAXPATHLEN);
+ if (!strchr(sapi_module.executable_location, '/')) {
+ char *envpath, *path;
+ int found = 0;
+
+ if ((envpath = getenv("PATH")) != NULL) {
+ char *search_dir, search_path[MAXPATHLEN];
+ char *last;
+
+ path = estrdup(envpath);
+ search_dir = php_strtok_r(path, ":", &last);
+
+ while (search_dir) {
+ snprintf(search_path, MAXPATHLEN, "%s/%s", search_dir, sapi_module.executable_location);
+ if (VCWD_REALPATH(search_path, binary_location) && !VCWD_ACCESS(binary_location, X_OK)) {
+ found = 1;
+ break;
+ }
+ search_dir = php_strtok_r(NULL, ":", &last);
+ }
+ efree(path);
+ }
+ if (!found) {
+ efree(binary_location);
+ binary_location = NULL;
+ }
+ } else if (!VCWD_REALPATH(sapi_module.executable_location, binary_location) || VCWD_ACCESS(binary_location, X_OK)) {
+ efree(binary_location);
+ binary_location = NULL;
+ }
+ } else {
+ binary_location = NULL;
+ }
+#endif
+ RETVAL_STRING(binary_location, 1);
+ if (binary_location) {
+ efree(binary_location);
+ }
+}
+/* }}} */
+
/* Our custom signal handler that calls the appropriate php_function */
static void pcntl_signal_handler(int signo)
{
@@ -1105,7 +1397,7 @@
struct php_pcntl_pending_signal *queue, *next;
TSRMLS_FETCH();
- /* Bail if the queue is empty or if we are already playing the queue*/
+ /* Bail if the queue is empty or if we are already playing the queue */
if (! PCNTL_G(head) || PCNTL_G(processing_signal_queue))
return;
@@ -1129,6 +1421,11 @@
call_user_function(EG(function_table), NULL, *handle, retval, 1, &param TSRMLS_CC);
zval_ptr_dtor(&param);
zval_ptr_dtor(&retval);
+
+#ifdef _MSC_VER
+ /* Windows is using straight signal calls, reput the item back in */
+ php_signal(queue->signo, (Sigfunc *) Z_LVAL_PP(handle), 0);
+#endif
}
next = queue->next;
@@ -1141,8 +1438,6 @@
PCNTL_G(processing_signal_queue) = 0;
}
-
-
/*
* Local variables:
* tab-width: 4
Index: pcntl_win.c
===================================================================
--- pcntl_win.c (revision 0)
+++ pcntl_win.c (revision 0)
@@ -0,0 +1,181 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2009 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Jason Greene <jason@inetgurus.net> |
+ +----------------------------------------------------------------------+
+ */
+
+/* $Id$ */
+
+#include "php.h"
+#include "pcntl_win.h"
+
+/* Implementation of waitpid - only supports WNOHANG for options */
+pid_t waitpid (pid_t pid, int *stat_loc, int options) {
+ DWORD timeout;
+
+ if (options == WNOHANG) {
+ timeout = 0;
+ } else {
+ timeout = INFINITE;
+ }
+ if (WaitForSingleObject((HANDLE) pid, timeout) == WAIT_OBJECT_0) {
+ pid = _cwait(stat_loc, pid, 0);
+ return pid;
+ }
+ return 0;
+}
+
+/* Implementation of wait - only supports processes created via the pcntl_spawn method */
+pid_t wait (int *stat_loc) {
+ // TODO: make spawn store the process handles on nowait
+ // put process handle hashtable in globals
+ // make waitpid and wait remove process handles
+ // similiar to perl's handling of the matter ;)
+ return 0;
+}
+
+/* Implementation of alarm using timers */
+unsigned int alarm(unsigned int seconds) {
+}
+
+/* Implementation of setpriority using SetPriorityClass */
+int setpriority(int which, int who, int prio) {
+ HANDLE process;
+ zend_bool close_handle = 0;
+ DWORD dwFlag = NORMAL_PRIORITY_CLASS;
+ BOOL success;
+
+ /* On windows, which can only be 0 */
+ if (which != 0) {
+ errno = EINVAL; /* Invalid which value */
+ return -1;
+ }
+
+ /* If who is 0, get the current process handle */
+ if (who == 0) {
+ process = GetCurrentProcess();
+ } else {
+ /* Take the pid provided and open a process handle to use */
+ process = OpenProcess(PROCESS_SET_INFORMATION, FALSE, who);
+ if (!process) {
+ errno = ESRCH; /* Invalid identifier */
+ return -1;
+ } else {
+ close_handle = 1;
+ }
+ }
+
+ /* Translate priorities into windows priority constants
+ range is guessed at -15 to 15 - 0 is included in normal */
+ /* anything less then -10 is idle */
+ if (prio < -10) {
+ dwFlag = IDLE_PRIORITY_CLASS;
+ /* -10 to -5 is below normal */
+ } else if (prio < -5 && prio > -11) {
+ dwFlag = BELOW_NORMAL_PRIORITY_CLASS;
+ /* -5 to 0 is normal */
+ } else if (prio > -6 && prio < 1) {
+ dwFlag = NORMAL_PRIORITY_CLASS;
+ /* 1 to 5 is above normal */
+ } else if (prio > 0 && prio < 6) {
+ dwFlag = ABOVE_NORMAL_PRIORITY_CLASS;
+ /* 5 to 10 is high */
+ } else if (prio > 5 && prio < 11) {
+ dwFlag = HIGH_PRIORITY_CLASS;
+ /* anything above 10 is realtime */
+ } else if (prio > 10) {
+ dwFlag = REALTIME_PRIORITY_CLASS;
+ }
+
+ /* do the setpriority call */
+ success = SetPriorityClass(process, dwFlag);
+
+ /* close any handles */
+ if (close_handle) {
+ CloseHandle(process);
+ }
+
+ /* return values are -1 for an error or zero for worked */
+ if (success == 0) {
+ /* windows uses 0 for fail */
+ errno = GetLastError();
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
+/* Implementation of getpriority using GetPriorityClass */
+int getpriority(int which, int who) {
+ HANDLE process;
+ zend_bool close_handle = 0;
+ DWORD value;
+
+ /* On windows, which can only be 0 */
+ if (which != 0) {
+ errno = EINVAL; /* Invalid which value */
+ return -1;
+ }
+
+ /* If who is 0, get the current process handle */
+ if (who == 0) {
+ process = GetCurrentProcess();
+ } else {
+ /* Take the pid provided and open a process handle to use */
+ process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, who);
+ if (!process) {
+ errno = ESRCH; /* Invalid identifier */
+ return -1;
+ } else {
+ close_handle = 1;
+ }
+ }
+
+ /* do the getpriority call */
+ value = GetPriorityClass(process);
+
+ /* close any handles */
+ if (close_handle) {
+ CloseHandle(process);
+ }
+
+ /* Translate the windows priority constants into simple ints
+ range is guessed at -15 to 15 - 0 is included in normal */
+ /* anything less then -10 is idle */
+ switch(value) {
+ case IDLE_PRIORITY_CLASS:
+ return -11;
+ case BELOW_NORMAL_PRIORITY_CLASS:
+ return -6;
+ case NORMAL_PRIORITY_CLASS:
+ return 0;
+ case ABOVE_NORMAL_PRIORITY_CLASS:
+ return 4;
+ case HIGH_PRIORITY_CLASS:
+ return 9;
+ case REALTIME_PRIORITY_CLASS:
+ return 15;
+ default:
+ return 1;
+ }
+}
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * indent-tabs-mode: t
+ * End:
+ */
Property changes on: pcntl_win.c
___________________________________________________________________
Added: svn:keywords
+ Id
Index: pcntl_win.h
===================================================================
--- pcntl_win.h (revision 0)
+++ pcntl_win.h (revision 0)
@@ -0,0 +1,54 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2009 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 3.01 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available through the world-wide-web at the following url: |
+ | http://www.php.net/license/3_01.txt |
+ | If you did not receive a copy of the PHP license and are unable to |
+ | obtain it through the world-wide-web, please send a note to |
+ | license@php.net so we can mail you a copy immediately. |
+ +----------------------------------------------------------------------+
+ | Author: Jason Greene <jason@inetgurus.net> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef PHP_PCNTL_WIN_H
+#define PHP_PCNTL_WIN_H
+
+#define HAVE_GETPRIORITY 1
+#define HAVE_SETPRIORITY 1
+
+/*
+ * MSVC is missing these macros
+ */
+#define WIFEXITED(stat) (((*((int *) &(stat))) & 0xff) == 0)
+#define WEXITSTATUS(stat) (((*((int *) &(stat))) >> 8) & 0xff)
+#define WIFSIGNALED(stat) (((*((int *) &(stat)))) && ((*((int *) &(stat))) == ((*((int *) &(stat))) & 0x00ff)))
+#define WTERMSIG(stat) ((*((int *) &(stat))) & 0x7f)
+#define WIFSTOPPED(stat) (((*((int *) &(stat))) & 0xff) == 0177)
+#define WSTOPSIG(stat) (((*((int *) &(stat))) >> 8) & 0xff)
+
+#define WNOHANG 1
+#define WUNTRACED 2
+
+#define PRIO_PROCESS 0
+#define PRIO_PGRP 1
+#define PRIO_USER 2
+
+#ifndef intptr_t
+ typedef INT_PTR intptr_t;
+#endif
+
+pid_t waitpid (pid_t pid, int *stat_loc, int options);
+pid_t wait (int *stat_loc);
+unsigned int alarm(unsigned int seconds);
+int setpriority(int which, int who, int prio);
+int getpriority(int which, int who);
+
+#endif
Property changes on: pcntl_win.h
___________________________________________________________________
Added: svn:keywords
+ Id
Index: php_pcntl.h
===================================================================
--- php_pcntl.h (revision 290360)
+++ php_pcntl.h (working copy)
@@ -25,7 +25,6 @@
#define phpext_pcntl_ptr &pcntl_module_entry
PHP_MINIT_FUNCTION(pcntl);
-PHP_MSHUTDOWN_FUNCTION(pcntl);
PHP_RINIT_FUNCTION(pcntl);
PHP_RSHUTDOWN_FUNCTION(pcntl);
PHP_MINFO_FUNCTION(pcntl);
@@ -42,6 +41,7 @@
PHP_FUNCTION(pcntl_wstopsig);
PHP_FUNCTION(pcntl_signal);
PHP_FUNCTION(pcntl_signal_dispatch);
+PHP_FUNCTION(pcntl_raise);
#ifdef HAVE_SIGPROCMASK
PHP_FUNCTION(pcntl_sigprocmask);
#endif
@@ -56,6 +56,8 @@
#ifdef HAVE_SETPRIORITY
PHP_FUNCTION(pcntl_setpriority);
#endif
+PHP_FUNCTION(pcntl_spawn);
+PHP_FUNCTION(pcntl_executable);
struct php_pcntl_pending_signal {
struct php_pcntl_pending_signal *next;
Index: php_signal.c
===================================================================
--- php_signal.c (revision 290360)
+++ php_signal.c (working copy)
@@ -20,6 +20,48 @@
#include "php_signal.h"
+#ifdef _MSC_VER
+
+#if defined(PHP_WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1400)
+static _invalid_parameter_handler old_invalid_parameter_handler;
+void swallow_invalid_parameter_handler(const wchar_t* expression,
+ const wchar_t* function,
+ const wchar_t* file,
+ unsigned int line,
+ uintptr_t pReserved)
+{
+ /* Do nothing */
+}
+#endif
+
+/* windows does not HAVE sigaction available to it, instead signal() must
+ be used */
+Sigfunc *php_signal(int signo, Sigfunc *func, int restart)
+{
+ Sigfunc *value;
+
+#if defined(PHP_WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1400)
+ /* bad voodoo - PHP has a CRT invalid parameter handler
+ that's nice, but we'll be checking for errors in a moment
+ and don't need double warnings! */
+ old_invalid_parameter_handler = _set_invalid_parameter_handler(swallow_invalid_parameter_handler);
+#endif
+
+ /* Do the call */
+ value = signal(signo, func);
+
+#if defined(PHP_WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1400)
+ /* restore the previous handler - my word this is ugly */
+ if (old_invalid_parameter_handler != NULL) {
+ _set_invalid_parameter_handler(old_invalid_parameter_handler);
+ }
+#endif
+
+ return value;
+}
+
+#else
+
/* php_signal using sigaction is derrived from Advanced Programing
* in the Unix Environment by W. Richard Stevens p 298. */
Sigfunc *php_signal(int signo, Sigfunc *func, int restart)
@@ -42,6 +84,7 @@
return oact.sa_handler;
}
+#endif
/*
* Local variables:
Index: php_signal.h
===================================================================
--- php_signal.h (revision 290360)
+++ php_signal.h (working copy)
@@ -18,6 +18,7 @@
/* $Id$ */
+#include <php.h>
#include <signal.h>
#ifndef PHP_SIGNAL_H
#define PHP_SIGNAL_H
Index: tests/pcntl_exec.phpt
===================================================================
--- tests/pcntl_exec.phpt (revision 290360)
+++ tests/pcntl_exec.phpt (working copy)
@@ -1,12 +1,14 @@
--TEST--
pcntl_exec()
--SKIPIF--
-<?php if (!getenv("TEST_PHP_EXECUTABLE") || !is_executable(getenv("TEST_PHP_EXECUTABLE"))) die("skip TEST_PHP_EXECUTABLE not set"); ?>
+<?php
+ if (!extension_loaded('pcntl')) echo 'skip';
+?>
--FILE--
<?php
echo "ok\n";
-pcntl_exec(getenv("TEST_PHP_EXECUTABLE"));
+pcntl_exec(pcntl_executable());
echo "nok\n";
?>
--EXPECT--
-ok
+ok
\ No newline at end of file
Index: tests/pcntl_exec_2.phpt
===================================================================
--- tests/pcntl_exec_2.phpt (revision 290360)
+++ tests/pcntl_exec_2.phpt (working copy)
@@ -1,7 +1,9 @@
--TEST--
-pcntl_exec() 2
+pcntl_exec() with environment variables
--SKIPIF--
-<?php if (!getenv("TEST_PHP_EXECUTABLE") || !is_executable(getenv("TEST_PHP_EXECUTABLE"))) die("skip TEST_PHP_EXECUTABLE not set"); ?>
+<?php
+ if (!extension_loaded('pcntl')) echo 'skip';
+?>
--FILE--
<?php
if (getenv("PCNTL_EXEC_TEST_IS_CHILD")) {
@@ -9,14 +11,13 @@
exit;
}
echo "ok\n";
-pcntl_exec(getenv("TEST_PHP_EXECUTABLE"), array(__FILE__), array(
+pcntl_exec(pcntl_executable(), array(__FILE__), array(
b"PCNTL_EXEC_TEST_IS_CHILD" => b"1",
- b"FOO" => b"BAR",
- 1 => b"long")
+ b"FOO" => b"BAR")
);
echo "nok\n";
?>
--EXPECT--
ok
-string(3) "BAR"
+string(3) "BAR"
\ No newline at end of file
Index: tests/pcntl_exec_3.phpt
===================================================================
--- tests/pcntl_exec_3.phpt (revision 290360)
+++ tests/pcntl_exec_3.phpt (working copy)
@@ -1,5 +1,9 @@
--TEST--
-pcntl_exec() 3
+pcntl_exec() with bad parameters
+--SKIPIF--
+<?php
+ if (!extension_loaded('pcntl')) echo 'skip';
+?>
--FILE--
<?php
var_dump(pcntl_exec());
@@ -12,4 +16,4 @@
NULL
Warning: pcntl_exec(): Error has occured: (errno %d) %s
-bool(false)
+bool(false)
\ No newline at end of file
Index: tests/pcntl_fork_basic.phpt
===================================================================
--- tests/pcntl_fork_basic.phpt (revision 290360)
+++ tests/pcntl_fork_basic.phpt (working copy)
@@ -7,7 +7,7 @@
--SKIPIF--
<?php
if (!extension_loaded('pcntl')) die('skip pcntl extension not available');
- elseif (!extension_loaded('posix')) die('skip posix extension not available');
+ if (!function_exists('pcntl_fork')) die('skip pcntl_fork not available');
?>
--FILE--
<?php
Index: tests/pcntl_fork_variation.phpt
===================================================================
--- tests/pcntl_fork_variation.phpt (revision 290360)
+++ tests/pcntl_fork_variation.phpt (working copy)
@@ -7,7 +7,7 @@
--SKIPIF--
<?php
if (!extension_loaded('pcntl')) die('skip pcntl extension not available');
- elseif (!extension_loaded('posix')) die('skip posix extension not available');
+ if (!function_exists('pcntl_fork')) die('skip pcntl_fork not available');
?>
--FILE--
<?php
@@ -29,7 +29,7 @@
echo "son ($pid)\n";
$pid2 = pcntl_fork();
if ($pid2 > 0)
- {
+ {
pcntl_wait($status2);
echo "son is father of $pid2\n";
}
Index: tests/pcntl_signal.phpt
===================================================================
--- tests/pcntl_signal.phpt (revision 290360)
+++ tests/pcntl_signal.phpt (working copy)
@@ -1,24 +1,22 @@
--TEST--
pcntl_signal()
--SKIPIF--
-<?php if (!extension_loaded("posix")) die("skip posix extension not available"); ?>
+<?php if (!extension_loaded('pcntl')) die('skip pcntl extension not available'); ?>
--FILE--
<?php
pcntl_signal(SIGTERM, function($signo){
echo "signal dispatched\n";
});
-posix_kill(posix_getpid(), SIGTERM);
+pcntl_raise(SIGTERM);
pcntl_signal_dispatch();
-
var_dump(pcntl_signal());
-var_dump(pcntl_signal(SIGALRM, SIG_IGN));
+var_dump(pcntl_signal(SIGILL, SIG_IGN));
var_dump(pcntl_signal(-1, -1));
var_dump(pcntl_signal(-1, function(){}));
-var_dump(pcntl_signal(SIGALRM, "not callable"));
+var_dump(pcntl_signal(SIGILL, 'not callable'));
-
/* test freeing queue in RSHUTDOWN */
-posix_kill(posix_getpid(), SIGTERM);
+pcntl_raise(SIGTERM);
echo "ok\n";
?>
--EXPECTF--
@@ -29,8 +27,6 @@
bool(true)
Warning: pcntl_signal(): Invalid value for handle argument specified in %s
-
-Warning: pcntl_signal(): Error assigning signal %s
bool(false)
Warning: pcntl_signal(): Error assigning signal %s
Index: tests/pcntl_signal_dispatch.phpt
===================================================================
--- tests/pcntl_signal_dispatch.phpt (revision 290360)
+++ tests/pcntl_signal_dispatch.phpt (working copy)
@@ -2,19 +2,16 @@
pcnt_signal_dispatch()
--SKIPIF--
<?php
- if (!extension_loaded("pcntl")) print "skip";
- elseif (!function_exists("pcntl_signal")) print "skip pcntl_signal() not available";
- elseif (!function_exists("pcntl_signal_dispatch")) print "skip pcntl_signal_dispatch() not available";
- elseif (!function_exists("posix_kill")) print "skip posix_kill() not available";
- elseif (!function_exists("posix_getpid")) print "skip posix_getpid() not available";
+ if (!extension_loaded('pcntl')) die('skip pcntl extension not available');
+ if (!function_exists('pcntl_signal')) die('skip pcntl_signal not available');
+ if (!function_exists('pcntl_signal_dispatch')) die('skip pcntl_signal_dispatch not available');
?>
--FILE--
<?php
-
pcntl_signal(SIGTERM, function ($signo) { echo "Signal handler called!\n"; });
echo "Start!\n";
-posix_kill(posix_getpid(), SIGTERM);
+pcntl_raise(SIGTERM);
$i = 0; // dummy
pcntl_signal_dispatch();
echo "Done!\n";
Index: tests/pcntl_spawn_basic.phpt
===================================================================
--- tests/pcntl_spawn_basic.phpt (revision 0)
+++ tests/pcntl_spawn_basic.phpt (revision 0)
@@ -0,0 +1,21 @@
+--TEST--
+Test function pcntl_spawn() by calling it with its expected arguments
+--SKIPIF--
+<?php
+ if (!extension_loaded('pcntl')) die('skip pcntl extension not available');
+?>
+--FILE--
+<?php
+if (getenv("PCNTL_SPAWN_TEST_IS_CHILD")) {
+ var_dump(getmypid());
+ var_dump((binary)getenv("FOO"));
+ exit;
+}
+$pid = pcntl_spawn(pcntl_executable(), NULL, array(__FILE__), array(
+ b"PCNTL_SPAWN_TEST_IS_CHILD" => b"1",
+ b"FOO" => b"BAR"));
+
+pcntl_waitpid($pid, $status, null);
+var_dump($pid);
+?>
+--EXPECTF--
Index: tests/pcntl_waitpid.phpt
===================================================================
--- tests/pcntl_waitpid.phpt (revision 0)
+++ tests/pcntl_waitpid.phpt (revision 0)
@@ -0,0 +1,41 @@
+--TEST--
+pcntl_waitpid functionality
+--SKIPIF--
+<?php
+ if (!extension_loaded('pcntl')) echo 'skip';
+?>
+--FILE--
+<?php
+$pid = pcntl_spawn();
+
+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);
+ }
+}
+
+
+print "Staring wait.h tests....";
+test_exit_waits();
+test_exit_signal();
+test_stop_signal();
+?>
+--EXPECT--
+Staring wait.h tests....
+
+Testing pcntl_wifexited and wexitstatus....
+Exited With: 255
+
+Testing pcntl_wifsignaled....
+Process was terminated by signal : SIGTERM
+
+Testing pcntl_wifstopped and pcntl_wstopsig....
+Process was stoped by signal : SIGSTOP
Index: tests/pcntl_wifexited.phpt
===================================================================
--- tests/pcntl_wifexited.phpt (revision 0)
+++ tests/pcntl_wifexited.phpt (revision 0)
@@ -0,0 +1,34 @@
+--TEST--
+pcntl_wifexited()
+--SKIPIF--
+<?php if (!extension_loaded('pcntl')) die('skip pcntl extension not available'); ?>
+--FILE--
+<?php
+if (getenv('is_child')) {
+ exit;
+}
+if (getenv('is_child_bad')) {
+ exit(42);
+}
+$pid = pcntl_spawn(pcntl_executable(), NULL, array(__FILE__), array(
+ 'is_child' => '1'));
+
+pcntl_waitpid($pid, $status);
+
+var_dump(pcntl_wifexited($status));
+
+$pid = pcntl_spawn(pcntl_executable(), NULL, array(__FILE__), array(
+ 'is_child_bad' => '1'));
+
+pcntl_waitpid($pid, $status);
+
+var_dump(pcntl_wifexited($status));
+
+var_dump(pcntl_wifexited());
+?>
+--EXPECTF--
+bool(true)
+bool(false)
+
+Warning: pcntl_wifexited() expects exactly 1 parameter, 0 given in %s on line %d
+NULL
\ No newline at end of file
Index: tests/signal_closure_handler.phpt
===================================================================
--- tests/signal_closure_handler.phpt (revision 290360)
+++ tests/signal_closure_handler.phpt (working copy)
@@ -1,11 +1,9 @@
--TEST--
-Closures as a signal handler
+Using ticks for signal handling
--SKIPIF--
<?php
- if (!extension_loaded("pcntl")) print "skip";
- elseif (!function_exists("pcntl_signal")) print "skip pcntl_signal() not available";
- elseif (!function_exists("posix_kill")) print "skip posix_kill() not available";
- elseif (!function_exists("posix_getpid")) print "skip posix_getpid() not available";
+ if (!extension_loaded('pcntl')) die('skip pcntl extension not available');
+ if (!function_exists('pcntl_signal')) die('skip pcntl_signal not available');
?>
--FILE--
<?php
@@ -14,7 +12,7 @@
pcntl_signal(SIGTERM, function ($signo) { echo "Signal handler called!\n"; });
echo "Start!\n";
-posix_kill(posix_getpid(), SIGTERM);
+pcntl_raise(SIGTERM);
$i = 0; // dummy
echo "Done!\n";
Index: TODO
===================================================================
--- TODO (revision 0)
+++ TODO (revision 0)
@@ -0,0 +1,7 @@
+1. put hashtable for storing child process PIDs in for win32 into globals
+2. make spawn store the child process PIDs for nowait
+3. make waitpid remove the child process PID if it's closed
+4. make wait "waitformultipleobjects" on the child process hash table and remove them if they're done
+
+5. create win_pcntl.h and win_pcntl.c with windows specific stuff
+6. deal with signals - ick!
\ No newline at end of file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment