source: main/trunk/greenstone2/runtime-src/src/recpt/os_process_unix.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: 5.9 KB
RevLine 
[22173]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)
[22174]44 : child_stdout_read_(-1), child_stdin_write_(-1),
[22173]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
[22177]72 pid_ = fork();
73 if (pid_ < 0) {
[22173]74 cerr << "osprocessunix::osprocessunix(): Failed to create child process" << endl;
75 return;
76 }
77
[22177]78 if (pid_ == 0) {
[22173]79 // Child process
80
81 // Sort out input pipe
82 // child has no buisness accessing write end of input pipe => close
[22177]83 ::close(child_stdin_write_);
84 child_stdin_write_=-1;
[22173]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 {
[22177]91 // Parent is doing uniRead, which means we're not interested
92 // in the child reading any input from the parent
[22173]93 // => child input remains coming from stdin
[22174]94 ::close(child_stdin_read);
[22173]95 }
96
97 // Sort out output pipe
98 // child has no buisness accessing read end of output pipe => close
[22174]99 ::close(child_stdout_read_);
[22177]100 child_stdout_read_=-1;
101
[22173]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 {
[22177]107 // Parent is doing uniWrite, which means we're not interested
108 // in any output produced by the child process
[22173]109 // => child output remains going to stdout
[22174]110 ::close(child_stdout_write);
[22173]111 }
112
[22177]113
114 // execvp?
115 cerr << "Away to execve: " << cmdline << endl;
[22174]116
[22177]117 execve(cmdline, NULL, NULL);
118
[22173]119
120 }
121 else {
122 // Parent process
123
124 // Sort out input pipe
125 // parent has no buisness accessing read end of input pipe => close
[22174]126 ::close(child_stdin_read);
[22173]127
128 // Sort out output pipe
129 // parent has no buisness accessing write end of output pipe => close
[22174]130 ::close(child_stdout_write);
[22173]131
132
133 switch(mode)
134 {
135 case uniRead:
[22174]136 ::close(child_stdin_write_);
[22177]137 child_stdin_write_ = -1;
[22173]138 break;
139 case uniWrite:
[22174]140 ::close(child_stdout_read_);
[22177]141 child_stdout_read_ = -1;
[22173]142 break;
143 case biReadWrite:
144 // nothing to do
145 // the pipes are set up just the way we want them
146 break;
147 }
148 }
149}
150
151osprocessunix::~osprocessunix()
[22177]152{
153 // close any file handles that are still open
154 close();
155}
[22173]156
157
158int osprocessunix::write(char* buffer, const int buffer_len)
159{
160
[22174]161 int actual_write_len = ::write(child_stdin_write_, buffer, buffer_len);
[22173]162
[22174]163 if (actual_write_len<0) {
[22173]164 cerr << "osproessunix::write() Error: failed to write data" << endl;
165 }
166
167 return actual_write_len;
168}
169
170int osprocessunix::read(char* buffer, const int buffer_len)
171{
[22174]172 int actual_read_len = ::read(child_stdout_read_, buffer, buffer_len);
[22173]173
174 if (actual_read_len<0) {
175 cerr << "osproessunix::read() Error: failed to read data" << endl;
176 }
177
178 return actual_read_len;
179}
180
181
182
[22177]183bool osprocessunix::close_write_pipe(OSProcessWarnStatus warn_status)
[22174]184{
[22177]185 int write_close_rv = 0;
186
187 if (child_stdin_write_ != -1) {
188 write_close_rv = ::close(child_stdin_write_);
189 child_stdin_write_ = -1;
190 }
191 else if (warn_status = withWarning) {
192 cerr << "osprocessunix::close_write_pipe(): Warning - Tried to close already closed pipe" << endl;
193 }
194
195 return (write_close_rv==0);
[22174]196}
[22173]197
[22177]198
199bool osprocessunix::close_read_pipe(OSProcessWarnStatus warn_status)
[22174]200{
[22177]201 int read_close_rv = 0;
202
203
204 if (child_stdout_read_ != -1) {
205 read_close_rv = ::close(child_stdout_read_);
206 child_stdout_read_ = -1;
207 }
208 else if (warn_status == withWarning) {
209 cerr << "osprocessunix::close_read_pipe(): Warning - Tried to close already closed pipe" << endl;
210 }
211
212 return (read_close_rv==0);
[22174]213}
[22173]214
215
216
[22177]217
218
219
[22173]220#endif
Note: See TracBrowser for help on using the repository browser.