diff options
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | TSRM/TSRM.dsp | 8 | ||||
-rw-r--r-- | TSRM/tsrm_virtual_cwd.c | 8 | ||||
-rw-r--r-- | TSRM/tsrm_win32.c | 176 | ||||
-rw-r--r-- | TSRM/tsrm_win32.h | 53 | ||||
-rw-r--r-- | main/SAPI.c | 9 | ||||
-rw-r--r-- | main/php.h | 1 | ||||
-rw-r--r-- | main/win95nt.h | 2 |
8 files changed, 251 insertions, 7 deletions
@@ -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) |