source: main/trunk/greenstone2/runtime-src/src/recpt/os_process_windows.cpp@ 22173

Last change on this file since 22173 was 22173, checked in by davidb, 14 years ago

Some initial development on the ability to have bi-directional pipes to spawned processes (with no DOS windows being opened up in the case of Windows). Think popen2()

  • Property svn:executable set to *
File size: 6.9 KB
Line 
1/**********************************************************************
2 *
3 * os_process_windows.c -- Windows version of osprocess. See os_process.h
4 * for more details
5 *
6 * Copyright (C) 2010 The New Zealand Digital Library Project
7 *
8 * A component of the Greenstone digital library software
9 * from the New Zealand Digital Library Project at the
10 * University of Waikato, New Zealand.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 *********************************************************************/
27
28#ifdef __WIN32__
29
30#if defined(GSDL_USE_OBJECTSPACE)
31# include <ospace/std/iostream>
32#elif defined(GSDL_USE_IOS_H)
33# include <iostream.h>
34#else
35# include <iostream>
36using namespace std;
37#endif
38
39#include "os_process_windows.h"
40
41//#include <stdio.h>
42
43osprocesswindows::osprocesswindows(char* cmdline)
44 : osprocess(cmdline)
45{}
46
47osprocesswindows::osprocesswindows(char* cmdline, OSProcessPipeMode mode)
48 : child_stdout_read_(NULL), child_stdin_write_(NULL),
49 osprocess(cmdline,mode)
50{
51 HANDLE child_stdin_read = NULL;
52 HANDLE child_stdout_write = NULL;
53
54 SECURITY_ATTRIBUTES saAttr;
55 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
56 saAttr.bInheritHandle = TRUE;
57 saAttr.lpSecurityDescriptor = NULL;
58
59 // Create a pipe for the child process's STDOUT.
60 if (!CreatePipe(&child_stdout_read_, &child_stdout_write, &saAttr, 0)) {
61 cerr << "osprocesswindows::osprocesswindows(): Failed to create stdout pipe for child process" << endl;
62 }
63
64 // Ensure the read handle to the pipe for STDOUT is not inherited.
65 if (!SetHandleInformation(child_stdout_read_, HANDLE_FLAG_INHERIT, 0)) {
66 cerr << "osprocesswindows::osprocesswindows(): Failed to set handle information for stdout pipe for child process" << endl;
67 }
68
69 // Create a pipe for the child process's STDIN.
70 if (!CreatePipe(&child_stdin_read, &child_stdin_write_, &saAttr, 0)) {
71 cerr << "osprocesswindows::osprocesswindows(): Failed to create stdin pipe for child process" << endl;
72 }
73
74 // Ensure the write handle to the pipe for STDIN is not inherited.
75 if (!SetHandleInformation(child_stdin_write_, HANDLE_FLAG_INHERIT, 0)) {
76 cerr << "osprocesswindows::osprocesswindows(): Failed to set handle information for stdin pipe for child process" << endl;
77 }
78
79 STARTUPINFOA si;
80 memset(&si, 0, sizeof(si));
81 memset(&pi_, 0, sizeof(pi_));
82
83 si.cb = sizeof(si);
84
85 // These two lines help prevent a DOS window popping up
86 // when the process is created
87 si.dwFlags |= STARTF_USESHOWWINDOW;
88 si.wShowWindow = SW_HIDE;
89
90 si.dwFlags |= STARTF_USESTDHANDLES;
91
92 // any error messages in child process to to same place as parent process
93 // e.g. in the case of running as a CGI script, the Web server error log
94 si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
95
96 // Output from the child process comes to the parent process, down the
97 // OUT pipe
98 si.hStdOutput = child_stdout_write;
99
100 // Input to the child process can be sent from the parent process, down the
101 // In pipe
102 si.hStdInput = child_stdin_read;
103
104 int rv = CreateProcess(NULL, // no application name
105 cmdline,
106 NULL,
107 NULL, // no process or thread security attribues
108 TRUE, // Inherit handles
109 0, // Creation flag
110 NULL, // No environment block
111 ".", // current working directory
112 &si,
113 &pi_); // process info filled out as a result
114 if (!rv) {
115 cerr << "os_process_windows(): Error creating process" << endl;
116 }
117
118 // close the handles that aren't used by the parent process
119
120 if (!CloseHandle(child_stdout_write)) {
121 cerr << "os_process_windows(): Error closing StdOutWr Handle" << endl;
122 }
123
124 if (!CloseHandle(child_stdin_read)) {
125 cerr << "os_process_windows(): Error closing StdInRd Handle" << endl;
126 }
127}
128
129
130osprocesswindows::~osprocesswindows()
131{
132 // Close process and thread handles
133 CloseHandle( pi_.hProcess );
134 pi_.hProcess = NULL;
135
136 CloseHandle( pi_.hThread );
137 pi_.hThread = NULL;
138}
139
140
141/*
142bool osprocesswindows::eop()
143{
144}
145
146bool osprocesswindows::eop(OSProcessPipeMode)
147{
148}
149*/
150
151
152
153int osprocesswindows::write(const char* buffer, const int buffer_len)
154{
155 DWORD actual_write_len;
156
157 bool write_ok
158 = WriteFile(child_stdin_write_, buffer, buffer_len, &actual_write_len, NULL);
159 if (!write_ok) {
160 cerr << "osproesswindows::write() Error: failed to write data" << endl;
161 }
162 return actual_write_len;
163}
164
165
166int osprocesswindows::read(char* buffer, const int buffer_len)
167{
168 DWORD actual_read_len;
169
170 bool read_ok
171 = ReadFile(child_stdout_read_, buffer, buffer_len, &actual_read_len, NULL);
172 if (!read_ok) {
173 cerr << "osproesswindows::read() Error: failed to read data" << endl;
174 }
175
176 return actual_read_len;
177}
178
179
180bool osprocesswindows::close() {
181 return true;
182}
183
184bool osprocesswindows::close(OSProcessPipeMode mode)
185{
186 // Close the pipe handle so the child process stops reading.
187
188 if (!CloseHandle(child_stdin_write_)) {
189 cerr << "osprocesswindows::close(): Failed to close stdin write handle on pipe to child process" << endl;
190 return false;
191 }
192
193 if (!CloseHandle(child_stdout_read_)) {
194 cerr << "osprocesswindows::close(): Failed to close handle stdout read on pipe to chlild process" << endl;
195 return false;
196 }
197
198
199 return true;
200}
201
202
203
204
205
206//#ifdef TEST_OS_PROCESS_WINDOWS
207#if 0
208
209int main ()
210{
211 char* input_line = NULL;
212 char* prog_name = "c:\\Windows\\system32\\java.exe";
213 char* cmd_line = "java";
214
215 //char* input_line = "echo hi there\n";
216 //char* prog_name = "c:\\cygwin\\bin\\cat.exe";
217 //char* cmd_line = "cat";
218
219 osprocesswindows osprocess(cmd_line,uniRead);
220
221 printf("Content-type: text/html\n\n");
222
223 printf( "<html>\n");
224 printf( " <head>\n");
225 printf( " <title>Testing</title>\n");
226 printf( " </head>\n");
227 printf( " <body>\n");
228
229
230 const int BufferSize = 1024;
231 char buffer[BufferSize];
232
233 int bytes_read = 0;
234 do {
235 bytes_read = osprocess.read(buffer,BufferSize);
236 if (bytes_read>0) {
237 fwrite(buffer,1,bytes_read,stdout);
238 }
239 } while (bytes_read==BufferSize);
240
241
242 printf( " </body>\n");
243 printf( "</html>\n");
244
245 return 0;
246}
247
248#endif
249
250#endif
Note: See TracBrowser for help on using the repository browser.