summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS1
-rw-r--r--TSRM/TSRM.dsp8
-rw-r--r--TSRM/tsrm_virtual_cwd.c8
-rw-r--r--TSRM/tsrm_win32.c176
-rw-r--r--TSRM/tsrm_win32.h53
-rw-r--r--main/SAPI.c9
-rw-r--r--main/php.h1
-rw-r--r--main/win95nt.h2
8 files changed, 251 insertions, 7 deletions
diff --git a/NEWS b/NEWS
index 09806a8ed9..878dc7ed04 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,7 @@ PHP 4.0 NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? 200?, Version 4.0.6
+- Fix popen() and the exec family under Win32 (Unable to fork issue) (Daniel)
- Make the printf family of functions binary clean (Rasmus)
- Fixed WDDX serialization to HTML-escape key/variable names so as not to
break the XML packet. (Andrei)
diff --git a/TSRM/TSRM.dsp b/TSRM/TSRM.dsp
index 1a9afc4b61..20483583b7 100644
--- a/TSRM/TSRM.dsp
+++ b/TSRM/TSRM.dsp
@@ -145,6 +145,10 @@ SOURCE=.\tsrm_strtok_r.c
SOURCE=.\tsrm_virtual_cwd.c
# End Source File
+# Begin Source File
+
+SOURCE=.\tsrm_win32.c
+# End Source File
# End Group
# Begin Group "Header Files"
@@ -169,6 +173,10 @@ SOURCE=.\tsrm_strtok_r.h
SOURCE=.\tsrm_virtual_cwd.h
# End Source File
+# Begin Source File
+
+SOURCE=.\tsrm_win32.h
+# End Source File
# End Group
# End Target
# End Project
diff --git a/TSRM/tsrm_virtual_cwd.c b/TSRM/tsrm_virtual_cwd.c
index 0e54b0996f..d7bdafe0f9 100644
--- a/TSRM/tsrm_virtual_cwd.c
+++ b/TSRM/tsrm_virtual_cwd.c
@@ -33,6 +33,7 @@
#ifdef TSRM_WIN32
#include <io.h>
+#include "tsrm_win32.h"
#endif
#define VIRTUAL_CWD_DEBUG 0
@@ -738,11 +739,8 @@ CWD_API FILE *virtual_popen(const char *command, const char *type)
*ptr++ = ' ';
memcpy(ptr, command, command_length+1);
-#ifdef TSRM_WIN32
- retval = _popen(command_line, type);
-#else
retval = popen(command_line, type);
-#endif
+
free(command_line);
return retval;
}
@@ -769,7 +767,7 @@ CWD_API FILE *virtual_popen(const char *command, const char *type)
#endif
chdir(CWDG(cwd).cwd);
- retval = _popen(command, type);
+ retval = popen(command, type);
chdir(prev_cwd);
#ifdef ZTS
diff --git a/TSRM/tsrm_win32.c b/TSRM/tsrm_win32.c
new file mode 100644
index 0000000000..1895507e32
--- /dev/null
+++ b/TSRM/tsrm_win32.c
@@ -0,0 +1,176 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP version 4.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997, 1998, 1999, 2000 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 2.02 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available at through the world-wide-web at |
+ | http://www.php.net/license/2_02.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. |
+ +----------------------------------------------------------------------+
+ | Authors: Daniel Beulshausen <daniel@php4win.de> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <io.h>
+#include <process.h>
+
+#include "TSRM.h"
+
+#ifdef TSRM_WIN32
+#include <windows.h>
+#include "tsrm_win32.h"
+
+#ifdef ZTS
+static ts_rsrc_id win32_globals_id;
+#else
+static tsrm_win32_globals win32_globals;
+#endif
+
+static void tsrm_win32_ctor(tsrm_win32_globals *globals) {
+ globals->process = NULL;
+ globals->process_size = 0;
+}
+
+static void tsrm_win32_dtor(tsrm_win32_globals *globals) {
+ if(globals->process != NULL) {
+ free(globals->process);
+ }
+}
+
+TSRM_API void tsrm_win32_startup(void) {
+#ifdef ZTS
+ win32_globals_id = ts_allocate_id(sizeof(tsrm_win32_globals), (ts_allocate_ctor)tsrm_win32_ctor, (ts_allocate_ctor)tsrm_win32_dtor);
+#else
+ tsrm_win32_ctor(&win32_globals);
+#endif
+}
+
+TSRM_API void tsrm_win32_shutdown(void) {
+#ifndef ZTS
+ tsrm_win32_dtor(&win32_globals);
+#endif
+}
+
+static ProcessPair* process_get(FILE *stream) {
+ ProcessPair* ptr;
+ ProcessPair* newptr;
+ TWLS_FETCH();
+
+ for(ptr = TWG(process); ptr < (TWG(process) + TWG(process_size)); ptr++) {
+ if(stream != NULL && ptr->stream == stream){
+ break;
+ }
+ else if(stream == NULL && !ptr->inuse) {
+ break;
+ }
+ }
+
+ if(ptr < (TWG(process) + TWG(process_size))) {
+ return ptr;
+ }
+
+ newptr = (ProcessPair*)realloc((void*)TWG(process), (TWG(process_size)+1)*sizeof(ProcessPair));
+ if(newptr == NULL) {
+ return NULL;
+ }
+
+ TWG(process) = newptr;
+ ptr = newptr + TWG(process_size);
+ TWG(process_size)++;
+ return ptr;
+}
+
+TSRM_API FILE* popen(const char *command, const char *type) {
+ FILE *stream = NULL;
+ int fno, str_len = strlen(type), read, mode;
+ STARTUPINFO startup;
+ PROCESS_INFORMATION process;
+ SECURITY_ATTRIBUTES security;
+ HANDLE in, out;
+ ProcessPair *proc;
+
+ security.nLength = sizeof(SECURITY_ATTRIBUTES);
+ security.bInheritHandle = TRUE;
+ security.lpSecurityDescriptor = NULL;
+
+ if(!str_len || !CreatePipe(&in, &out, &security, 2048L)) {
+ return NULL;
+ }
+
+ memset(&startup, 0, sizeof(STARTUPINFO));
+ memset(&process, 0, sizeof (PROCESS_INFORMATION));
+
+ startup.cb = sizeof(STARTUPINFO);
+ startup.dwFlags = STARTF_USESTDHANDLES;
+ startup.hStdError = GetStdHandle(STD_ERROR_HANDLE);
+
+ read = (type[0] == 'r') ? TRUE : FALSE;
+ mode = ((str_len == 2) && (type[1] == 'b')) ? O_BINARY : O_TEXT;
+
+
+ if(read) {
+ startup.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
+ startup.hStdOutput = out;
+ }
+ else {
+ startup.hStdInput = in;
+ startup.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+ }
+
+
+ if (!CreateProcess(NULL, (LPTSTR)command, &security, &security, security.bInheritHandle, NORMAL_PRIORITY_CLASS, NULL, NULL, &startup, &process)) {
+ return NULL;
+ }
+
+ CloseHandle(process.hThread);
+ proc = process_get(NULL);
+
+ if(read) {
+ fno = _open_osfhandle((long)in, _O_RDONLY | mode);
+ CloseHandle(out);
+ }
+ else {
+ fno = _open_osfhandle((long)out, _O_WRONLY | mode);
+ CloseHandle(in);
+ }
+
+ stream = _fdopen(fno, type);
+ proc->prochnd = process.hProcess;
+ proc->stream = stream;
+ proc->inuse = 1;
+ return stream;
+}
+
+TSRM_API int pclose(FILE* stream) {
+ DWORD termstat = 0;
+ ProcessPair* process;
+
+ if((process = process_get(stream)) == NULL) {
+ return 0;
+ }
+
+ fflush(process->stream);
+ fclose(process->stream);
+
+ GetExitCodeProcess(process->prochnd, &termstat);
+ if(termstat == STILL_ACTIVE) {
+ TerminateProcess(process->prochnd, termstat);
+ }
+
+ process->stream = NULL;
+ process->inuse = 0;
+ CloseHandle(process->prochnd);
+
+ return termstat;
+}
+#endif \ No newline at end of file
diff --git a/TSRM/tsrm_win32.h b/TSRM/tsrm_win32.h
new file mode 100644
index 0000000000..08eceb644f
--- /dev/null
+++ b/TSRM/tsrm_win32.h
@@ -0,0 +1,53 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP version 4.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997, 1998, 1999, 2000 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 2.02 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available at through the world-wide-web at |
+ | http://www.php.net/license/2_02.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. |
+ +----------------------------------------------------------------------+
+ | Authors: Daniel Beulshausen <daniel@php4win.de> |
+ +----------------------------------------------------------------------+
+*/
+
+/* $Id$ */
+
+#ifndef TSRM_WIN32_H
+#define TSRM_WIN32_H
+
+#include "TSRM.h"
+
+#ifdef TSRM_WIN32
+#include <windows.h>
+typedef struct {
+ FILE *stream;
+ HANDLE prochnd;
+ int inuse;
+} ProcessPair;
+
+typedef struct {
+ ProcessPair *process;
+ int process_size;
+} tsrm_win32_globals;
+
+#ifdef ZTS
+# define TWG(v) (win32_globals->v)
+# define TWLS_FETCH() tsrm_win32_globals *win32_globals = ts_resource(win32_globals_id)
+#else
+# define TWG(v) (win32_globals.v)
+# define TWLS_FETCH()
+#endif
+#endif
+
+TSRM_API void tsrm_win32_startup(void);
+TSRM_API void tsrm_win32_shutdown(void);
+TSRM_API FILE* popen(const char *command, const char *type);
+TSRM_API int pclose(FILE* stream);
+
+#endif \ No newline at end of file
diff --git a/main/SAPI.c b/main/SAPI.c
index e967f6d0ed..b0bb456cae 100644
--- a/main/SAPI.c
+++ b/main/SAPI.c
@@ -73,6 +73,10 @@ SAPI_API void sapi_startup(sapi_module_struct *sf)
virtual_cwd_startup(); /* Could use shutdown to free the main cwd but it would just slow it down for CGI */
#endif
+#ifdef PHP_WIN32
+ tsrm_win32_startup();
+#endif
+
reentrancy_startup();
php_global_startup_internal_extensions();
@@ -84,6 +88,11 @@ SAPI_API void sapi_shutdown(void)
#ifdef VIRTUAL_DIR
virtual_cwd_shutdown();
#endif
+
+#ifdef PHP_WIN32
+ tsrm_win32_shutdown();
+#endif
+
php_global_shutdown_internal_extensions();
zend_hash_destroy(&known_post_content_types);
}
diff --git a/main/php.h b/main/php.h
index fdbb484936..a87e61490c 100644
--- a/main/php.h
+++ b/main/php.h
@@ -42,6 +42,7 @@
#endif
#ifdef PHP_WIN32
+#include "tsrm_win32.h"
#include "win95nt.h"
# ifdef PHP_EXPORTS
# define PHPAPI __declspec(dllexport)
diff --git a/main/win95nt.h b/main/win95nt.h
index 322207fdea..d06e986930 100644
--- a/main/win95nt.h
+++ b/main/win95nt.h
@@ -18,8 +18,6 @@ typedef char * caddr_t;
#define S_IFIFO _IFIFO
#define S_IFBLK _IFBLK
#define S_IFLNK _IFLNK
-#define pclose(a) _pclose(a)
-#define popen(a, b) _popen(a, b)
#define chdir(path) SetCurrentDirectory(path)
#define mkdir(a,b) _mkdir(a)
#define rmdir(a) _rmdir(a)