source: main/trunk/greenstone2/runtime-src/src/recpt/os_process_unix.cpp@ 22178

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

slipped up with '=' instead of '=='. Now fixed.

  • Property svn:executable set to *
File size: 5.8 KB
Line 
1/**********************************************************************
2 *
3 * os_process_unix.cpp -- Unix 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#ifndef __WIN32__ // i.e Unix
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 <unistd.h>
40
41#include "os_process_unix.h"
42
43osprocessunix::osprocessunix(char* cmdline, OSProcessPipeMode mode)
44 : child_stdout_read_(-1), child_stdin_write_(-1),
45 osprocess(cmdline,mode)
46{
47
48 // Create a pipe for the child process's STDOUT.
49 int stdout_pipe_fd[2];
50
51 if (pipe(stdout_pipe_fd)!=0) {
52 cerr << "osprocessunix::osprocessunix(): Failed to create stdout pipe for child process" << endl;
53 return;
54 }
55
56 child_stdout_read_ = stdout_pipe_fd[READ_PIPE_INDEX];
57 int child_stdout_write = stdout_pipe_fd[WRITE_PIPE_INDEX];
58
59
60 // Create a pipe for the child process's STDIN.
61 int stdin_pipe_fd[2];
62
63 if (pipe(stdin_pipe_fd)!=0) {
64 cerr << "osprocessunix::osprocessunix(): Failed to create stdin pipe for child process" << endl;
65 return;
66 }
67
68 int child_stdin_read = stdin_pipe_fd[READ_PIPE_INDEX];
69 child_stdin_write_ = stdin_pipe_fd[WRITE_PIPE_INDEX];
70
71
72 pid_ = fork();
73 if (pid_ < 0) {
74 cerr << "osprocessunix::osprocessunix(): Failed to create child process" << endl;
75 return;
76 }
77
78 if (pid_ == 0) {
79 // Child process
80
81 // Sort out input pipe
82 // child has no buisness accessing write end of input pipe => close
83 ::close(child_stdin_write_);
84 child_stdin_write_=-1;
85
86 if ((mode == uniWrite) || (mode == biReadWrite)) {
87 // wire up child's stdin read so its input comes from the parent's pipe
88 dup2(child_stdin_read, FD_STDIN);
89 }
90 else {
91 // Parent is doing uniRead, which means we're not interested
92 // in the child reading any input from the parent
93 // => child input remains coming from stdin
94 ::close(child_stdin_read);
95 }
96
97 // Sort out output pipe
98 // child has no buisness accessing read end of output pipe => close
99 ::close(child_stdout_read_);
100 child_stdout_read_=-1;
101
102 if ((mode == uniRead) || (mode == biReadWrite)) {
103 // wire up child's stdout write so it is send down the pipe to the parent
104 dup2(child_stdout_write, FD_STDOUT);
105 }
106 else {
107 // Parent is doing uniWrite, which means we're not interested
108 // in any output produced by the child process
109 // => child output remains going to stdout
110 ::close(child_stdout_write);
111 }
112
113
114 // execvp?
115 execve(cmdline, NULL, NULL);
116
117
118 }
119 else {
120 // Parent process
121
122 // Sort out input pipe
123 // parent has no buisness accessing read end of input pipe => close
124 ::close(child_stdin_read);
125
126 // Sort out output pipe
127 // parent has no buisness accessing write end of output pipe => close
128 ::close(child_stdout_write);
129
130
131 switch(mode)
132 {
133 case uniRead:
134 ::close(child_stdin_write_);
135 child_stdin_write_ = -1;
136 break;
137 case uniWrite:
138 ::close(child_stdout_read_);
139 child_stdout_read_ = -1;
140 break;
141 case biReadWrite:
142 // nothing to do
143 // the pipes are set up just the way we want them
144 break;
145 }
146 }
147}
148
149osprocessunix::~osprocessunix()
150{
151 // close any file handles that are still open
152 close();
153}
154
155
156int osprocessunix::write(char* buffer, const int buffer_len)
157{
158
159 int actual_write_len = ::write(child_stdin_write_, buffer, buffer_len);
160
161 if (actual_write_len<0) {
162 cerr << "osproessunix::write() Error: failed to write data" << endl;
163 }
164
165 return actual_write_len;
166}
167
168int osprocessunix::read(char* buffer, const int buffer_len)
169{
170 int actual_read_len = ::read(child_stdout_read_, buffer, buffer_len);
171
172 if (actual_read_len<0) {
173 cerr << "osproessunix::read() Error: failed to read data" << endl;
174 }
175
176 return actual_read_len;
177}
178
179
180
181bool osprocessunix::close_write_pipe(OSProcessWarnStatus warn_status)
182{
183 int write_close_rv = 0;
184
185 if (child_stdin_write_ != -1) {
186 write_close_rv = ::close(child_stdin_write_);
187 child_stdin_write_ = -1;
188 }
189 else if (warn_status == withWarning) {
190 cerr << "osprocessunix::close_write_pipe(): Warning - Tried to close already closed pipe" << endl;
191 }
192
193 return (write_close_rv==0);
194}
195
196
197bool osprocessunix::close_read_pipe(OSProcessWarnStatus warn_status)
198{
199 int read_close_rv = 0;
200
201 if (child_stdout_read_ != -1) {
202 read_close_rv = ::close(child_stdout_read_);
203 child_stdout_read_ = -1;
204 }
205 else if (warn_status == withWarning) {
206 cerr << "osprocessunix::close_read_pipe(): Warning - Tried to close already closed pipe" << endl;
207 }
208
209 return (read_close_rv==0);
210}
211
212
213
214
215
216
217#endif
Note: See TracBrowser for help on using the repository browser.