source: branches/libc-0.6/src/binutils/libiberty/pex-os2.c

Last change on this file was 947, checked in by bird, 22 years ago

do close on exec stuff (paranoia and such).

  • Property cvs2svn:cvs-rev set to 1.4
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 4.8 KB
Line 
1/* Utilities to execute a program in a subprocess (possibly linked by pipes
2 with other subprocesses), and wait for it. OS/2 specialization.
3 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003
4 Free Software Foundation, Inc.
5
6This file is part of the libiberty library.
7Libiberty is free software; you can redistribute it and/or
8modify it under the terms of the GNU Library General Public
9License as published by the Free Software Foundation; either
10version 2 of the License, or (at your option) any later version.
11
12Libiberty is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15Library General Public License for more details.
16
17You should have received a copy of the GNU Library General Public
18License along with libiberty; see the file COPYING.LIB. If not,
19write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
21
22#include "pex-common.h"
23
24#include <stdio.h>
25#include <errno.h>
26#ifdef NEED_DECLARATION_ERRNO
27extern int errno;
28#endif
29#ifdef HAVE_STRING_H
30#include <string.h>
31#endif
32#ifdef HAVE_UNISTD_H
33#include <unistd.h>
34#endif
35#ifdef HAVE_STDLIB_H
36#include <stdlib.h>
37#endif
38#ifdef HAVE_SYS_WAIT_H
39#include <sys/wait.h>
40#endif
41
42#ifndef HAVE_WAITPID
43#define waitpid(pid, status, flags) wait(status)
44#endif
45
46#include <process.h>
47#define INCL_BASE
48#include <os2.h>
49#include <sys/fcntl.h>
50
51int
52pexecute (program, argv, this_pname, temp_base, errmsg_fmt, errmsg_arg, flags)
53 const char *program;
54 char * const *argv;
55 const char *this_pname;
56 const char *temp_base;
57 char **errmsg_fmt, **errmsg_arg;
58 int flags;
59{
60 static int last_pipe_input = STDIN_FILE_NO;
61 int pid;
62 int pdes[2], org_stdin, org_stdout;
63 int input_desc = last_pipe_input;
64 int output_desc = STDOUT_FILE_NO;
65#ifdef __OS2__
66#define pipes_supported 1
67#else
68 int pipes_supported = _osmode != DOS_MODE || (_emx_env & 0x1000);
69
70 if (!pipes_supported && (flags & PEXECUTE_ONE) != PEXECUTE_ONE)
71 {
72 static char *errtpl = "%s: exec %s (pipes not supported)";
73 *errmsg_fmt = (char *) xmalloc (strlen(errtpl) + \
74 strlen(this_pname) + strlen(program));
75 sprintf (*errmsg_fmt, errtpl, this_pname, program);
76 *errmsg_arg = NULL;
77 return -1;
78 }
79#endif
80
81 /* If this isn't the last process, make a pipe for its output,
82 and record it as waiting to be the input to the next process. */
83 if (!(flags & PEXECUTE_LAST))
84 {
85 if (pipe (pdes) < 0)
86 {
87 static char *errtpl = "%s: pipe to/from %s";
88 *errmsg_fmt = (char *) xmalloc (strlen(errtpl) + \
89 strlen(this_pname) + strlen(program));
90 sprintf (*errmsg_fmt, errtpl, this_pname, program);
91 *errmsg_arg = NULL;
92 return -1;
93 }
94 output_desc = pdes[WRITE_PORT];
95 last_pipe_input = pdes[READ_PORT];
96 /* we don't wanna have an extra handles in the child. */
97 fcntl (pdes[READ_PORT], F_SETFD, FD_CLOEXEC);
98 fcntl (pdes[WRITE_PORT], F_SETFD, FD_CLOEXEC);
99 }
100 else
101 last_pipe_input = STDIN_FILE_NO;
102 if (pipes_supported && input_desc != STDIN_FILE_NO)
103 {
104 org_stdin = dup (STDIN_FILE_NO);
105 fcntl (org_stdin, F_SETFD, FD_CLOEXEC);
106 dup2 (input_desc, STDIN_FILE_NO);
107 fcntl (STDIN_FILE_NO, F_SETFD, 0); /* paranoia. but what's the deal with this flag over dup? */
108 close (input_desc);
109 }
110 if (pipes_supported && output_desc != STDOUT_FILE_NO)
111 {
112 org_stdout = dup (STDOUT_FILE_NO);
113 fcntl (org_stdout, F_SETFD, FD_CLOEXEC);
114 dup2 (output_desc, STDOUT_FILE_NO);
115 fcntl (STDOUT_FILE_NO, F_SETFD, 0); /* paranoia. but what's the deal with this flag over dup? */
116 close (output_desc);
117 }
118
119 pid = (flags & PEXECUTE_SEARCH ? spawnvp : spawnv) (P_NOWAIT, program, argv);
120
121 if (pipes_supported && input_desc != STDIN_FILE_NO)
122 {
123 dup2 (org_stdin, STDIN_FILE_NO);
124 fcntl (STDIN_FILE_NO, F_SETFD, 0); /* paranoia. but what's the deal with this flag over dup? */
125 close (org_stdin);
126 }
127 if (pipes_supported && output_desc != STDOUT_FILE_NO)
128 {
129 dup2 (org_stdout, STDOUT_FILE_NO);
130 fcntl (STDOUT_FILE_NO, F_SETFD, 0); /* paranoia. but what's the deal with this flag over dup? */
131 close (org_stdout);
132 }
133 if (pid == -1)
134 {
135 static char *errtpl = "%s: error executing %s";
136 *errmsg_fmt = (char *) xmalloc (strlen(errtpl) + \
137 strlen(this_pname) + strlen(program));
138 sprintf (*errmsg_fmt, errtpl, this_pname, program);
139 *errmsg_arg = NULL;
140 }
141 return pid;
142}
143
144
145int
146pwait (pid, status, flags)
147 int pid;
148 int *status;
149 int flags;
150{
151 /* ??? Here's an opportunity to canonicalize the values in STATUS.
152 Needed? */
153 int rc;
154 do
155 rc = waitpid (pid, status, flags);
156 while (rc < 0 && errno == EINTR);
157 return rc;
158}
Note: See TracBrowser for help on using the repository browser.