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

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

Further expansion of functionality (and testing) or os_process classes

  • Property svn:executable set to *
File size: 7.1 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(OSProcessPipeMode mode,
48 char* prog_name, char* argv[]=NULL,
49 char* envp[])
50 : child_stdout_read_(NULL), child_stdin_write_(NULL),
51 osprocess(mode,prog_name,argv,envp)
52{
53 HANDLE child_stdin_read = NULL;
54 HANDLE child_stdout_write = NULL;
55
56 SECURITY_ATTRIBUTES saAttr;
57 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
58 saAttr.bInheritHandle = TRUE;
59 saAttr.lpSecurityDescriptor = NULL;
60
61 // Create a pipe for the child process's STDOUT.
62 if (!CreatePipe(&child_stdout_read_, &child_stdout_write, &saAttr, 0)) {
63 cerr << "osprocesswindows::osprocesswindows(): Failed to create stdout pipe for child process" << endl;
64 }
65
66 // Ensure the read handle to the pipe for STDOUT is not inherited.
67 if (!SetHandleInformation(child_stdout_read_, HANDLE_FLAG_INHERIT, 0)) {
68 cerr << "osprocesswindows::osprocesswindows(): Failed to set handle information for stdout pipe for child process" << endl;
69 }
70
71 // Create a pipe for the child process's STDIN.
72 if (!CreatePipe(&child_stdin_read, &child_stdin_write_, &saAttr, 0)) {
73 cerr << "osprocesswindows::osprocesswindows(): Failed to create stdin pipe for child process" << endl;
74 }
75
76 // Ensure the write handle to the pipe for STDIN is not inherited.
77 if (!SetHandleInformation(child_stdin_write_, HANDLE_FLAG_INHERIT, 0)) {
78 cerr << "osprocesswindows::osprocesswindows(): Failed to set handle information for stdin pipe for child process" << endl;
79 }
80
81 STARTUPINFOA si;
82 memset(&si, 0, sizeof(si));
83 memset(&pi_, 0, sizeof(pi_));
84
85 si.cb = sizeof(si);
86
87 // These two lines help prevent a DOS window popping up
88 // when the process is created
89 si.dwFlags |= STARTF_USESHOWWINDOW;
90 si.wShowWindow = SW_HIDE;
91
92 si.dwFlags |= STARTF_USESTDHANDLES;
93
94 // any error messages in child process to to same place as parent process
95 // e.g. in the case of running as a CGI script, the Web server error log
96 si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
97
98 // Output from the child process comes to the parent process, down the
99 // OUT pipe
100 si.hStdOutput = child_stdout_write;
101
102 // Input to the child process can be sent from the parent process, down the
103 // In pipe
104 si.hStdInput = child_stdin_read;
105
106 text_t cmd_line = "";
107 if (argv != NULL) {
108 int i=0;
109 while (argv[i] != NULL) {
110 if (i>0) {
111 cmd_line += " ";
112 }
113 cmd_line += "\"" + argv[i] + "\"";
114 i++;
115 }
116 }
117
118 char* cmd_line_cstr = cmd_line.getcstr();
119
120 int rv = CreateProcess(NULL, // no application name
121 cmd_line_cstr,
122 NULL,
123 NULL, // no process or thread security attribues
124 TRUE, // Inherit handles
125 0, // Creation flag
126 NULL, // No environment block
127 ".", // current working directory
128 &si,
129 &pi_); // process info filled out as a result
130
131 delete [] cmd_line_cstr;
132
133 if (!rv) {
134 cerr << "os_process_windows(): Error creating child process" << endl;
135 }
136
137 // close the handles that aren't used by the parent process
138
139 if (!CloseHandle(child_stdout_write)) {
140 cerr << "os_process_windows(): Error closing child's StdOut Write Handle" << endl;
141 }
142
143 if (!CloseHandle(child_stdin_read)) {
144 cerr << "os_process_windows(): Error closing child's StdIn Read Handle" << endl;
145 }
146}
147
148
149osprocesswindows::~osprocesswindows()
150{
151 // close any file handles that are still open
152 close();
153
154 // Close process and thread handles
155 CloseHandle( pi_.hProcess );
156 pi_.hProcess = NULL;
157
158 CloseHandle( pi_.hThread );
159 pi_.hThread = NULL;
160}
161
162
163
164int osprocesswindows::write(const char* buffer, const int buffer_len)
165{
166 DWORD actual_write_len;
167
168 bool write_ok
169 = WriteFile(child_stdin_write_, buffer, buffer_len, &actual_write_len, NULL);
170 if (!write_ok) {
171 cerr << "osproesswindows::write() Error: failed to write data" << endl;
172 }
173 return actual_write_len;
174}
175
176
177int osprocesswindows::read(char* buffer, const int buffer_len)
178{
179 DWORD actual_read_len;
180
181 bool read_ok
182 = ReadFile(child_stdout_read_, buffer, buffer_len, &actual_read_len, NULL);
183 if (!read_ok) {
184 cerr << "osproesswindows::read() Error: failed to read data" << endl;
185 }
186
187 return actual_read_len;
188}
189
190
191void osprocesswindows::wait()
192{
193 WaitForSingleObject(pi_.hProcess, INFINITE);
194}
195
196
197bool osprocessunix::close_write_pipe(OSProcessWarnStatus warn_status)
198{
199 bool write_close_ok = true;
200
201 if (child_stdout_read_ != NULL) {
202
203 write_close_ok = CloseHandle(child_stdin_write_);
204
205 if (write_close_ok) {
206 child_stdin_write_ = NULL;
207 }
208 else {
209 // not OK
210 cerr << "osprocesswindows::close(): Error - Failed to close stdin write handle on pipe to child process" << endl;
211 }
212 }
213 else if (warning_status == withWarning) {
214 cerr << "osprocesswindows::close_write_pipe(): Warning - Tried to close already closed pipe" << endl;
215 }
216
217 return write_close_ok;
218}
219
220
221bool osprocessunix::close_read_pipe(OSProcessWarnStatus warn_status)
222{
223 bool read_close_ok = true;
224
225 if (child_stdout_read_ != NULL) {
226
227 read_close_ok = CloseHandle(child_stdout_read_);
228
229 if (read_close_ok) {
230 child_stdout_read_ = NULL;
231 }
232 else {
233 cerr << "osprocesswindows::close(): Error - Failed to close handle stdout read on pipe to chlild process" << endl;
234 }
235 }
236 else if (warn_status == withWarning) {
237 cerr << "osprocesswindows::close_read_pipe(): Warning - Tried to close already closed pipe" << endl;
238 }
239
240 return read_close_ok;
241}
242
243
244
245
246
247
248
249
250#endif
Note: See TracBrowser for help on using the repository browser.