php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #46487
Patch proc_close-lingering.patch revision 2012-07-12 15:00 UTC by jille at hexon dot cx

Patch proc_close-lingering.patch for Program Execution Bug #46487

Patch version 2012-07-12 15:00 UTC

Return to Bug #46487 | Download this patch
Patch Revisions:

Developer: jille@hexon.cx

Index: ext/standard/file.c
===================================================================
--- ext/standard/file.c	(revision 125)
+++ ext/standard/file.c	(working copy)
@@ -159,6 +159,7 @@
 static void file_globals_ctor(php_file_globals *file_globals_p TSRMLS_DC)
 {
 	FG(pclose_ret) = 0;
+	FG(pclose_wait) = 0;
 	FG(user_stream_current_filename) = NULL;
 	FG(def_chunk_size) = PHP_SOCK_CHUNK_SIZE;
 }
@@ -959,7 +960,9 @@
 
 	PHP_STREAM_TO_ZVAL(stream, &arg1);
 
+	FG(pclose_wait) = 1;
 	zend_list_delete(stream->rsrc_id);
+	FG(pclose_wait) = 0;
 	RETURN_LONG(FG(pclose_ret));
 }
 /* }}} */
Index: ext/standard/file.h
===================================================================
--- ext/standard/file.h	(revision 125)
+++ ext/standard/file.h	(working copy)
@@ -115,7 +115,8 @@
 php_meta_tags_token php_next_meta_token(php_meta_tags_data * TSRMLS_DC);
 
 typedef struct {
-  	int pclose_ret;
+	int pclose_ret;
+	int pclose_wait;
 	size_t def_chunk_size;
 	long auto_detect_line_endings;
 	long default_socket_timeout;
Index: ext/standard/proc_open.c
===================================================================
--- ext/standard/proc_open.c	(revision 125)
+++ ext/standard/proc_open.c	(working copy)
@@ -208,6 +208,7 @@
 	DWORD wstatus;
 #elif HAVE_SYS_WAIT_H
 	int wstatus;
+	int waitpid_options = 0;
 	pid_t wait_pid;
 #endif
 
@@ -220,18 +221,27 @@
 	}
 
 #ifdef PHP_WIN32
-	WaitForSingleObject(proc->childHandle, INFINITE);
+	if (FG(pclose_wait)) {
+		WaitForSingleObject(proc->childHandle, INFINITE);
+	}
 	GetExitCodeProcess(proc->childHandle, &wstatus);
-	FG(pclose_ret) = wstatus;
+	if (wstatus == STILL_ACTIVE) {
+		FG(pclose_ret) = -1;
+	} else {
+		FG(pclose_ret) = wstatus;
+	}
 	CloseHandle(proc->childHandle);
 
 #elif HAVE_SYS_WAIT_H
 
+	if (!FG(pclose_wait)) {
+		waitpid_options = WNOHANG;
+	}
 	do {
-		wait_pid = waitpid(proc->child, &wstatus, 0);
+		wait_pid = waitpid(proc->child, &wstatus, waitpid_options);
 	} while (wait_pid == -1 && errno == EINTR);
 
-	if (wait_pid == -1) {
+	if (wait_pid <= 0) {
 		FG(pclose_ret) = -1;
 	} else {
 		if (WIFEXITED(wstatus))
@@ -300,7 +310,9 @@
 
 	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));
 }
 /* }}} */
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Apr 25 23:01:29 2024 UTC