php-src/TSRM/tsrm_win32.c

190 lines
4.9 KiB
C
Raw Normal View History

2001-04-27 16:41:53 +00:00
/*
+----------------------------------------------------------------------+
| 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)
{
2001-04-27 16:41:53 +00:00
globals->process = NULL;
globals->process_size = 0;
2001-07-01 20:08:21 +00:00
globals->comspec = _strdup((GetVersion()<0x80000000)?"cmd.exe":"command.com");
2001-04-27 16:41:53 +00:00
}
static void tsrm_win32_dtor(tsrm_win32_globals *globals)
{
if (globals->process != NULL) {
2001-04-27 16:41:53 +00:00
free(globals->process);
}
2001-07-01 20:08:21 +00:00
free(globals->comspec);
2001-04-27 16:41:53 +00:00
}
TSRM_API void tsrm_win32_startup(void)
{
2001-04-27 16:41:53 +00:00
#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)
{
2001-04-27 16:41:53 +00:00
#ifndef ZTS
tsrm_win32_dtor(&win32_globals);
#endif
}
static ProcessPair* process_get(FILE *stream)
{
2001-04-27 16:41:53 +00:00
ProcessPair* ptr;
ProcessPair* newptr;
TWLS_FETCH();
for (ptr = TWG(process); ptr < (TWG(process) + TWG(process_size)); ptr++) {
2001-07-09 16:44:40 +00:00
if (ptr->stream == stream) {
2001-04-27 16:41:53 +00:00
break;
}
}
if (ptr < (TWG(process) + TWG(process_size))) {
2001-04-27 16:41:53 +00:00
return ptr;
}
newptr = (ProcessPair*)realloc((void*)TWG(process), (TWG(process_size)+1)*sizeof(ProcessPair));
if (newptr == NULL) {
2001-04-27 16:41:53 +00:00
return NULL;
}
TWG(process) = newptr;
ptr = newptr + TWG(process_size);
TWG(process_size)++;
return ptr;
}
2001-07-09 16:44:40 +00:00
static HANDLE dupHandle(HANDLE fh, BOOL inherit) {
HANDLE copy, self = GetCurrentProcess();
if (!DuplicateHandle(self, fh, self, &copy, 0, inherit, DUPLICATE_SAME_ACCESS|DUPLICATE_CLOSE_SOURCE)) {
return NULL;
}
return copy;
}
TSRM_API FILE* popen(const char *command, const char *type)
{
2001-04-27 16:41:53 +00:00
FILE *stream = NULL;
int fno, str_len = strlen(type), read, mode;
STARTUPINFO startup;
PROCESS_INFORMATION process;
SECURITY_ATTRIBUTES security;
HANDLE in, out;
2001-07-01 20:08:21 +00:00
char *cmd;
2001-04-27 16:41:53 +00:00
ProcessPair *proc;
2001-07-01 20:08:21 +00:00
TWLS_FETCH();
2001-04-27 16:41:53 +00:00
security.nLength = sizeof(SECURITY_ATTRIBUTES);
security.bInheritHandle = TRUE;
security.lpSecurityDescriptor = NULL;
if (!str_len || !CreatePipe(&in, &out, &security, 2048L)) {
2001-04-27 16:41:53 +00:00
return NULL;
}
memset(&startup, 0, sizeof(STARTUPINFO));
memset(&process, 0, sizeof(PROCESS_INFORMATION));
2001-04-27 16:41:53 +00:00
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) {
2001-04-27 16:41:53 +00:00
startup.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
startup.hStdOutput = out;
} else {
2001-04-27 16:41:53 +00:00
startup.hStdInput = in;
startup.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
}
cmd = (char*)malloc(strlen(command)+strlen(TWG(comspec))+sizeof(" /c "));
2001-07-01 20:08:21 +00:00
sprintf(cmd, "%s /c %s", TWG(comspec), command);
if (!CreateProcess(NULL, cmd, &security, &security, security.bInheritHandle, NORMAL_PRIORITY_CLASS, NULL, NULL, &startup, &process)) {
2001-04-27 16:41:53 +00:00
return NULL;
}
2001-07-01 20:08:21 +00:00
free(cmd);
2001-04-27 16:41:53 +00:00
CloseHandle(process.hThread);
proc = process_get(NULL);
if (read) {
2001-07-09 16:44:40 +00:00
in = dupHandle(in, FALSE);
2001-04-27 16:41:53 +00:00
fno = _open_osfhandle((long)in, _O_RDONLY | mode);
CloseHandle(out);
} else {
2001-07-09 16:44:40 +00:00
out = dupHandle(out, FALSE);
2001-04-27 16:41:53 +00:00
fno = _open_osfhandle((long)out, _O_WRONLY | mode);
CloseHandle(in);
}
stream = _fdopen(fno, type);
proc->prochnd = process.hProcess;
proc->stream = stream;
return stream;
}
TSRM_API int pclose(FILE* stream)
{
2001-04-27 16:41:53 +00:00
DWORD termstat = 0;
ProcessPair* process;
if ((process = process_get(stream)) == NULL) {
2001-04-27 16:41:53 +00:00
return 0;
}
fflush(process->stream);
fclose(process->stream);
2001-07-09 16:44:40 +00:00
WaitForSingleObject(process->prochnd, INFINITE);
2001-04-27 16:41:53 +00:00
GetExitCodeProcess(process->prochnd, &termstat);
process->stream = NULL;
CloseHandle(process->prochnd);
return termstat;
}
2001-07-09 16:44:40 +00:00
#endif