|
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-07 20:18 UTC Return to Bug #66437 | Download this patchThis patch is obsolete Obsoleted by patches: Patch Revisions:Developer: krakjoe@php.net
diff --git a/ext/standard/file.h b/ext/standard/file.h
index 9c044af..80efe56 100644
--- a/ext/standard/file.h
+++ b/ext/standard/file.h
@@ -115,7 +115,6 @@ typedef struct _php_meta_tags_data {
php_meta_tags_token php_next_meta_token(php_meta_tags_data * TSRMLS_DC);
typedef struct {
- int pclose_ret;
size_t def_chunk_size;
long auto_detect_line_endings;
long default_socket_timeout;
@@ -126,7 +125,6 @@ typedef struct {
HashTable *stream_wrappers; /* per-request copy of url_stream_wrappers_hash */
HashTable *stream_filters; /* per-request copy of stream_filters_hash */
HashTable *wrapper_errors; /* key: wrapper address; value: linked list of char* */
- int pclose_wait;
} php_file_globals;
#ifdef ZTS
diff --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 GroupAll rights reserved. |
Last updated: Wed Oct 29 08:00:01 2025 UTC |