php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | |
Patch proc-open-stuff.patch for Program Execution Bug #66437Patch version 2014-01-08 07:15 UTC Return to Bug #66437 | Download this patchThis patch renders other patches obsolete Obsolete patches: Patch Revisions:Developer: krakjoe@php.netdiff --git a/ext/standard/proc_open.c b/ext/standard/proc_open.c index 1e37e64..5c9056d 100644 --- a/ext/standard/proc_open.c +++ b/ext/standard/proc_open.c @@ -199,10 +199,7 @@ static void _php_free_envp(php_process_env_t env, int is_persistent) } /* }}} */ -/* {{{ proc_open_rsrc_dtor */ -static void proc_open_rsrc_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) -{ - struct php_process_handle *proc = (struct php_process_handle*)rsrc->ptr; +static void proc_close_func(struct php_process_handle *proc TSRMLS_DC) { /* {{{ */ int i; #ifdef PHP_WIN32 DWORD wstatus; @@ -219,39 +216,56 @@ static void proc_open_rsrc_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) proc->pipes[i] = 0; } } + + if (proc->closed) { + return; + } #ifdef PHP_WIN32 - if (FG(pclose_wait)) { + if (proc->wait) { WaitForSingleObject(proc->childHandle, INFINITE); } GetExitCodeProcess(proc->childHandle, &wstatus); if (wstatus == STILL_ACTIVE) { - FG(pclose_ret) = -1; + proc->ret = -1; } else { - FG(pclose_ret) = wstatus; + proc->ret = wstatus; } CloseHandle(proc->childHandle); #elif HAVE_SYS_WAIT_H - if (!FG(pclose_wait)) { + if (!proc->wait) { waitpid_options = WNOHANG; } + do { wait_pid = waitpid(proc->child, &wstatus, waitpid_options); } while (wait_pid == -1 && errno == EINTR); if (wait_pid <= 0) { - FG(pclose_ret) = -1; + proc->ret = -1; } else { if (WIFEXITED(wstatus)) - wstatus = WEXITSTATUS(wstatus); - FG(pclose_ret) = wstatus; + proc->ret = WEXITSTATUS(wstatus); } #else - FG(pclose_ret) = -1; + proc->ret = -1 #endif + + proc->closed = 1; +} /* }}} */ + +/* {{{ proc_open_rsrc_dtor */ +static void proc_open_rsrc_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) +{ + struct php_process_handle *proc = (struct php_process_handle*)rsrc->ptr; + + if (!proc->closed) { + proc_close_func(proc TSRMLS_CC); + } + _php_free_envp(proc->env, proc->is_persistent); pefree(proc->command, proc->is_persistent); pefree(proc, proc->is_persistent); @@ -281,6 +295,10 @@ PHP_FUNCTION(proc_terminate) ZEND_FETCH_RESOURCE(proc, struct php_process_handle *, &zproc, -1, "process", le_proc_open); + if (proc->closed) { + RETURN_TRUE; + } + #ifdef PHP_WIN32 if (TerminateProcess(proc->childHandle, 255)) { RETURN_TRUE; @@ -310,10 +328,13 @@ PHP_FUNCTION(proc_close) ZEND_FETCH_RESOURCE(proc, struct php_process_handle *, &zproc, -1, "process", le_proc_open); - FG(pclose_wait) = 1; - zend_list_delete(Z_LVAL_P(zproc)); - FG(pclose_wait) = 0; - RETURN_LONG(FG(pclose_ret)); + if (!proc->closed) { + proc->wait = 1; + proc_close_func(proc TSRMLS_CC); + proc->wait = 0; + } + + RETURN_LONG(proc->ret); } /* }}} */ @@ -347,19 +368,23 @@ PHP_FUNCTION(proc_get_status) GetExitCodeProcess(proc->childHandle, &wstatus); - running = wstatus == STILL_ACTIVE; - exitcode = running ? -1 : wstatus; + if (!(wstatus == STILL_ACTIVE)) { + proc->closed = 1; + } + + proc->ret = !proc->closed ? -1 : wstatus; #elif HAVE_SYS_WAIT_H errno = 0; wait_pid = waitpid(proc->child, &wstatus, WNOHANG|WUNTRACED); - if (wait_pid == proc->child) { + if ((wait_pid == proc->child)) { if (WIFEXITED(wstatus)) { - running = 0; - exitcode = WEXITSTATUS(wstatus); + proc->closed = 1; + proc->ret = WEXITSTATUS(wstatus); } + if (WIFSIGNALED(wstatus)) { running = 0; signaled = 1; @@ -372,16 +397,17 @@ PHP_FUNCTION(proc_get_status) if (WIFSTOPPED(wstatus)) { stopped = 1; stopsig = WSTOPSIG(wstatus); + proc->closed = 1; } } else if (wait_pid == -1) { - running = 0; + proc->closed = 1; } #endif - add_assoc_bool(return_value, "running", running); + add_assoc_bool(return_value, "running", !proc->closed); add_assoc_bool(return_value, "signaled", signaled); add_assoc_bool(return_value, "stopped", stopped); - add_assoc_long(return_value, "exitcode", exitcode); + add_assoc_long(return_value, "exitcode", proc->ret); add_assoc_long(return_value, "termsig", termsig); add_assoc_long(return_value, "stopsig", stopsig); } @@ -886,6 +912,10 @@ PHP_FUNCTION(proc_open) /* we forked/spawned and this is the parent */ proc = (struct php_process_handle*)pemalloc(sizeof(struct php_process_handle), is_persistent); + proc->closed = 0; + proc->ret = -1; + proc->wait = 0; + proc->is_persistent = is_persistent; proc->command = command; proc->npipes = ndesc; @@ -963,7 +993,7 @@ PHP_FUNCTION(proc_open) proc->pipes[i] = 0; } } - + ZEND_REGISTER_RESOURCE(return_value, proc, le_proc_open); return; diff --git a/ext/standard/proc_open.h b/ext/standard/proc_open.h index 6708fde..5e3f621 100644 --- a/ext/standard/proc_open.h +++ b/ext/standard/proc_open.h @@ -46,6 +46,9 @@ struct php_process_handle { int npipes; long pipes[PHP_PROC_OPEN_MAX_DESCRIPTORS]; char *command; + int wait; + int ret; + int closed; int is_persistent; php_process_env_t env; }; |
Copyright © 2001-2025 The PHP Group All rights reserved. |
Last updated: Wed Feb 05 17:01:30 2025 UTC |