1 /*===========================================================================
2 Copyright (c) 1998-2000, The Santa Cruz Operation
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
8 *Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
11 *Redistributions in binary form must reproduce the above copyright notice,
12 this list of conditions and the following disclaimer in the documentation
13 and/or other materials provided with the distribution.
15 *Neither name of The Santa Cruz Operation nor the names of its contributors
16 may be used to endorse or promote products derived from this software
17 without specific prior written permission.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
20 IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
23 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31 =========================================================================*/
36 #include <sys/types.h>
38 #include "global.h" /* pid_t, RETSIGTYPE, shell, and mybasename() */
40 #define tst(a,b) (*mode == 'r'? (b) : (a))
44 /* HBB 20010312: make this a bit safer --- don't blindly assume it's 1 */
46 # define CLOSE_ON_EXEC FD_CLOEXEC
48 # define CLOSE_ON_EXEC 1
52 # include <io.h> /* for setmode() */
55 static char const rcsid[] = "$Id: mypopen.c,v 1.14 2006/04/21 10:40:29 broeker Exp $";
57 static pid_t popen_pid[20];
58 static RETSIGTYPE (*tstat)(int);
61 myopen(char *path, int flag, int mode)
63 /* opens a file descriptor and then sets close-on-exec for the file */
66 /* 20020103: if file is not explicitly in Binary mode, make
67 * sure we override silly Cygwin behaviour of automatic binary
68 * mode for files in "binary mounted" paths */
69 #if O_BINARY != O_TEXT
70 if (! (flag | O_BINARY))
74 fd = open(path, flag, mode);
76 fd = open(path, flag);
78 #ifdef __DJGPP__ /* FIXME: test feature, not platform */
79 /* HBB 20010312: DOS GCC doesn't have FD_CLOEXEC (yet), so it
80 * always fails this call. Have to skip that step */
84 if(fd != -1 && (fcntl(fd, F_SETFD, CLOSE_ON_EXEC) != -1))
89 /* Ensure that if the fcntl fails and fd is valid, then
90 the file is closed properly. In general this should
102 myfopen(char *path, char *mode)
104 /* opens a file pointer and then sets close-on-exec for the file */
107 fp = fopen(path, mode);
110 if (fp && ! strchr(mode, 'b')) {
111 SETMODE(fileno(fp), O_TEXT);
115 #ifdef __DJGPP__ /* FIXME: test feature, not platform */
116 /* HBB 20010312: DOS GCC doesn't have FD_CLOEXEC (yet), so it
117 * always fails this call. Have to skip that step */
120 if(fp && (fcntl(fileno(fp), F_SETFD, CLOSE_ON_EXEC) != -1))
129 mypopen(char *cmd, char *mode)
132 /* HBB 20010312: Has its own implementation of popen(), which
133 * is better suited to the platform than cscope's */
134 return (popen)(cmd, mode);
138 int myside, yourside;
143 myside = tst(p[WTR], p[RDR]);
144 yourside = tst(p[RDR], p[WTR]);
145 if((pid = fork()) == 0) {
146 /* myside and yourside reverse roles in child */
149 /* close all pipes from other popen's */
150 for (poptr = popen_pid; poptr < popen_pid+20; poptr++) {
152 (void) close(poptr - popen_pid);
158 dup2(yourside, stdio);
160 fcntl(yourside, F_DUPFD, stdio);
163 execlp(shell, mybasename(shell), "-c", cmd, (void *)0);
166 tstat = signal(SIGTSTP, SIG_DFL);
169 popen_pid[myside] = pid;
170 (void) close(yourside);
171 return(fdopen(myside, mode));
175 /* HBB 20010705: renamed from 'pclose', which would collide with
176 * system-supplied function of same name */
183 sighandler_t hstat, istat, qstat;
186 /* HBB 20010705: This system has its own pclose(), which we
187 * don't want to replace */
188 return (pclose)(ptr);
192 istat = signal(SIGINT, SIG_IGN);
193 qstat = signal(SIGQUIT, SIG_IGN);
194 hstat = signal(SIGHUP, SIG_IGN);
195 while((r = wait(&status)) != popen_pid[f] && r != -1)
199 (void) signal(SIGINT, istat);
200 (void) signal(SIGQUIT, qstat);
201 (void) signal(SIGHUP, hstat);
202 (void) signal(SIGTSTP, tstat);
203 /* mark this pipe closed */