]> granicus.if.org Git - php/commitdiff
get rid of MS's _popen/_pclose
authorDaniel Beulshausen <dbeu@php.net>
Fri, 27 Apr 2001 16:41:53 +0000 (16:41 +0000)
committerDaniel Beulshausen <dbeu@php.net>
Fri, 27 Apr 2001 16:41:53 +0000 (16:41 +0000)
NEWS
TSRM/TSRM.dsp
TSRM/tsrm_virtual_cwd.c
TSRM/tsrm_win32.c [new file with mode: 0644]
TSRM/tsrm_win32.h [new file with mode: 0644]
main/SAPI.c
main/php.h
main/win95nt.h

diff --git a/NEWS b/NEWS
index 09806a8ed9d50d0845d9a2ba0f520e5f98688584..878dc7ed04db993dfd47d393065a18e34ede8ae8 100644 (file)
--- 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)
index 1a9afc4b61f86329989a124b315600d9475952c7..20483583b76f77901c90565d80ee1c6560de3a8a 100644 (file)
@@ -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
index 0e54b0996fee974998ecb0c39237aa768cb2d227..d7bdafe0f93283411fa0623bee1d39e9321e3e46 100644 (file)
@@ -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 (file)
index 0000000..1895507
--- /dev/null
@@ -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 (file)
index 0000000..08eceb6
--- /dev/null
@@ -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
index e967f6d0ed7567b446ce3037b0807956b13cff04..b0bb456cae263dae88d0d691a76ef2b5d9285808 100644 (file)
@@ -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);
 }
index fdbb4849363de5c30aa777a4d710b9a7bd6abbf9..a87e61490c2436ad9dd83957d4004aa613f88aa4 100644 (file)
@@ -42,6 +42,7 @@
 #endif
 
 #ifdef PHP_WIN32
+#include "tsrm_win32.h"
 #include "win95nt.h"
 #      ifdef PHP_EXPORTS
 #      define PHPAPI __declspec(dllexport)
index 322207fdea07fb30722a14654f80f3e42b56b0bb..d06e986930fb6689bb46c16248273d3e2b34343d 100644 (file)
@@ -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)