2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
27 * $TOG: Process.C /main/6 1998/04/06 13:26:21 mgreess $
29 * RESTRICTED CONFIDENTIAL INFORMATION:
31 * The information in this document is subject to special
32 * restrictions in a confidential disclosure agreement bertween
33 * HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
34 * document outside HP, IBM, Sun, USL, SCO, or Univel wihtout
35 * Sun's specific written approval. This documment and all copies
36 * and derivative works thereof must be returned or destroyed at
39 * Copyright 1993 Sun Microsystems, Inc. All rights reserved.
52 ** file included for INFTIM
54 #if defined(SunOS) || defined(USL) || defined(__uxp__)
58 #elif defined(_AIX) || defined(linux)
59 #define INFTIM (-1) /* Infinite timeout */
65 #include <DtMail/Threads.hh>
66 #include <DtMail/IO.hh>
68 static const int DEFAULT_SIZE = 64 << 10;
75 flags = fcntl(fd, F_GETFL);
76 } while(flags < 0 && errno == EINTR);
86 status = fcntl(fd, F_SETFL, flags);
87 } while (status < 0 && errno == EINTR);
93 RunProg(const char * program,
95 const char * stdin_data,
96 const unsigned long stdin_size,
98 unsigned long & stdout_size,
100 unsigned long & stderr_size)
102 // See if we are supposed to do I/O with the child.
108 size_t stdout_bufsize = 0;
109 unsigned long stderr_bufsize = 0;
113 SetNoBlock(stdin_fd[1]);
118 SetNoBlock(stdout_fd[0]);
123 SetNoBlock(stderr_fd[0]);
126 // We will fork and set up the file descriptors in the
130 #if defined(POSIX_THREADS)
131 pid_t child = fork1();
133 pid_t child = fork();
140 if (child == 0) { // The real child process.
142 SafeDup2(stdin_fd[0], STDIN_FILENO);
148 SafeDup2(stdout_fd[1], STDOUT_FILENO);
154 SafeDup2(stderr_fd[1], STDERR_FILENO);
159 SafeExecvp(program, argv);
162 else { // This is still us.
164 int stdin_written = 0;
168 memset(fds, 0, sizeof(fds));
170 fds[0].fd = stdin_fd[1];
171 fds[0].events = POLLOUT;
175 fds[1].fd = stdout_fd[0];
176 fds[1].events = POLLIN;
178 *stdout_data = (char *)malloc(DEFAULT_SIZE);
179 stdout_bufsize = DEFAULT_SIZE;
187 fds[2].fd = stderr_fd[0];
188 fds[2].events = POLLIN;
190 *stderr_data = (char *)malloc(DEFAULT_SIZE);
191 stderr_bufsize = DEFAULT_SIZE;
198 // set up the initial events we way we care about. Note that
199 // fds[1] and fds[2] may not be used -- nfds may be less than 3
206 // check to make sure there is really some work to do
207 // walk through the fds structure. If we get to the end
208 // without finding anything to do, i will be == nfds
209 for (i = 0; i < nfds; i++) {
210 if (fds[i].fd >= 0) break;
213 // there was no work to do
218 // we probably don't want to wait forever, so we can try
219 // and reap the child here, just in case it exits...
220 result = poll(fds, nfds, INFTIM);
223 // poll error -- what do we do?
224 if (errno == EINTR) continue;
226 // not much else to do -- poll really shouldn't fail...
230 if ((fds[0].revents & POLLOUT) &&
231 stdin_data && stdin_written < stdin_size) {
232 int status = SafeWrite(stdin_fd[1], stdin_data + stdin_written,
233 (size_t) stdin_size - stdin_written);
235 stdin_written += status;
238 if (stdin_written >= stdin_size) {
239 // we're done with the input
246 // We will now try to read 4K from each requested file
249 if (stdout_data && (fds[1].revents & POLLIN)) {
250 int status = SafeRead(stdout_fd[0], *stdout_data + stdout_size,
253 if (status < 0 && errno != EAGAIN) {
258 stdout_size += status;
259 if ((stdout_size + 4096) > stdout_bufsize) {
260 stdout_bufsize += DEFAULT_SIZE;
261 *stdout_data = (char *)realloc(*stdout_data, stdout_bufsize);
266 if (stderr_data && (fds[2].revents & POLLIN)) {
267 int status = SafeRead(stderr_fd[0], *stderr_data + stderr_size,
270 if (status < 0 && errno != EAGAIN) {
275 stderr_size += status;
278 if ((stderr_size + 4096) > stderr_bufsize) {
279 stderr_bufsize += DEFAULT_SIZE;
281 (char*) realloc(*stderr_data, (size_t) stderr_bufsize);
285 if ((fds[0].revents & POLLHUP) ||
286 (fds[1].revents & POLLHUP) ||
287 (fds[2].revents & POLLHUP)) {
293 SafeWaitpid(child, &child_stat, 0);