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

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

Further development of the os_process classes

  • Property svn:executable set to *
File size: 6.6 KB
RevLine 
[22173]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{
[22177]132 // close any file handles that are still open
133 close();
134
[22173]135 // Close process and thread handles
136 CloseHandle( pi_.hProcess );
137 pi_.hProcess = NULL;
138
139 CloseHandle( pi_.hThread );
140 pi_.hThread = NULL;
141}
142
143
144
145int osprocesswindows::write(const char* buffer, const int buffer_len)
146{
147 DWORD actual_write_len;
148
149 bool write_ok
150 = WriteFile(child_stdin_write_, buffer, buffer_len, &actual_write_len, NULL);
151 if (!write_ok) {
152 cerr << "osproesswindows::write() Error: failed to write data" << endl;
153 }
154 return actual_write_len;
155}
156
157
158int osprocesswindows::read(char* buffer, const int buffer_len)
159{
160 DWORD actual_read_len;
161
162 bool read_ok
163 = ReadFile(child_stdout_read_, buffer, buffer_len, &actual_read_len, NULL);
164 if (!read_ok) {
165 cerr << "osproesswindows::read() Error: failed to read data" << endl;
166 }
167
168 return actual_read_len;
169}
170
171
172
[22177]173
174bool osprocessunix::close_write_pipe(OSProcessWarnStatus warn_status)
[22173]175{
[22177]176 bool write_close_ok = true;
[22173]177
[22177]178 if (child_stdout_read_ != NULL) {
179
180 write_close_ok = CloseHandle(child_stdin_write_);
181
182 if (write_close_ok) {
183 child_stdin_write_ = NULL;
184 }
185 else {
186 // not OK
187 cerr << "osprocesswindows::close(): Error - Failed to close stdin write handle on pipe to child process" << endl;
188 }
[22173]189 }
[22177]190 else if (warning_status == withWarning) {
191 cerr << "osprocesswindows::close_write_pipe(): Warning - Tried to close already closed pipe" << endl;
192 }
[22173]193
[22177]194 return write_close_ok;
[22173]195}
196
197
[22177]198bool osprocessunix::close_read_pipe(OSProcessWarnStatus warn_status)
[22173]199{
[22177]200 bool read_close_ok = true;
[22173]201
[22177]202 if (child_stdout_read_ != NULL) {
203
204 read_close_ok = CloseHandle(child_stdout_read_);
205
206 if (read_close_ok) {
207 child_stdout_read_ = NULL;
208 }
209 else {
210 cerr << "osprocesswindows::close(): Error - Failed to close handle stdout read on pipe to chlild process" << endl;
211 }
212 }
213 else if (warn_status == withWarning) {
214 cerr << "osprocesswindows::close_read_pipe(): Warning - Tried to close already closed pipe" << endl;
215 }
216
217 return read_close_ok;
218}
[22173]219
220
221
222
223
224
225
226
227#endif
Note: See TracBrowser for help on using the repository browser.