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

Revision 22177, 6.6 KB (checked in by davidb, 10 years ago)

Further development of the os_process classes

  • Property svn:executable set to *
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 any file handles that are still open
133  close();
134
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
173 
174bool osprocessunix::close_write_pipe(OSProcessWarnStatus warn_status)
175{
176  bool write_close_ok = true;
177
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    }
189  }
190  else if (warning_status == withWarning) {
191    cerr << "osprocesswindows::close_write_pipe(): Warning - Tried to close already closed pipe" << endl;
192  }
193
194  return write_close_ok;
195}
196
197
198bool osprocessunix::close_read_pipe(OSProcessWarnStatus warn_status)
199{
200  bool read_close_ok = true;
201 
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}
219
220
221
222
223
224
225
226
227#endif
Note: See TracBrowser for help on using the browser.