/* */
This source file includes following definitions.
- execute
- myexecvp
- myfork
- join
1 /*===========================================================================
2 Copyright (c) 1998-2000, The Santa Cruz Operation
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7
8 *Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
10
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.
14
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.
18
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
26 INTERRUPTION)
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
30 DAMAGE.
31 =========================================================================*/
32
33 /** @file
34 * process execution functions
35 *
36 * cscope - interactive C symbol cross-reference
37 */
38
39 #include <unistd.h>
40 #include "global-cscope.h"
41 #include <stdarg.h>
42 #include <sys/types.h> /* pid_t */
43 #ifdef __DJGPP__
44 #include <process.h>
45 #endif
46 #if defined(USE_NCURSES) && !defined(RENAMED_NCURSES)
47 #include <ncurses.h>
48 #else
49 #include <curses.h>
50 #endif
51
52 #if defined(__MSDOS__) || (defined(_WIN32) && !defined(__CYGWIN__))
53 #define HAVE_FORK 0
54 #else
55 #include <sys/wait.h>
56 #define HAVE_FORK 1
57 #endif
58
59 static char const rcsid[] = "$Id: exec.c,v 1.3 2012/10/13 07:02:04 shigio Exp $";
60
61 static sighandler_t oldsigquit; /**< old value of quit signal */
62 static sighandler_t oldsighup; /**< old value of hangup signal */
63 static sighandler_t oldsigtstp; /**< old value of @VAR{SIGTSTP} */
64
65 #if HAVE_FORK /* none of these is needed, there */
66 static int join(pid_t p);
67 static int myexecvp(char *a, char **args);
68 static pid_t myfork(void);
69 #endif
70
71 /** execute forks and executes a program or shell script, waits for it to
72 * finish, and returns its exit code.
73 */
74
75 /*VARARGS1*/
76 int
77 execute(char *a, ...) /* note: "exec" is already defined on u370 */
78 {
79 va_list ap;
80 int exitcode = -1; /* initialize, to avoid warning */
81 char *argv[BUFSIZ];
82 pid_t p;
83
84 /* fork and exec the program or shell script */
85 endwin(); /* restore the terminal modes */
86 mousecleanup();
87 fflush(stdout);
88 va_start(ap, a);
89 for (p = 0; (argv[p] = va_arg(ap, char *)) != 0; p++)
90 ;
91 #if !HAVE_FORK
92 /* HBB 20010313: in MSDOG, everything is completely different.
93 * No fork()/exec()/wait(), but rather a single libc call: */
94 exitcode = spawnvp(P_WAIT, a, argv);
95 #else
96 if ((p = myfork()) == 0) {
97 myexecvp(a, argv); /* child */
98 }
99 else {
100 exitcode = join(p); /* parent */
101 }
102 #endif /* MSDOS */
103
104 /* the menu and scrollbar may be changed by the command executed */
105 #if UNIXPC || !TERMINFO
106 # ifndef __DJGPP__ /* leave CRLF handling as is */
107 nonl();
108 # endif
109 raw(); /* endwin() turns off cbreak mode so restore it */
110 noecho();
111 #endif
112 mousemenu();
113 drawscrollbar(topline, nextline);
114 va_end(ap);
115 return(exitcode);
116 }
117
118 #if HAVE_FORK /* None of the following functions is used there */
119
120 /** myexecvp is an interface to the @NAME{execvp} system call to
121 * modify @CODE{argv[0]} to reference the last component of its path-name.
122 */
123 static int
124 myexecvp(char *a, char **args)
125 {
126 char msg[MSGLEN + 1];
127
128 /* modify argv[0] to reference the last component of its path name */
129 args[0] = mybasename(args[0]);
130
131 /* execute the program or shell script */
132 execvp(a, args); /* returns only on failure */
133 snprintf(msg, sizeof(msg), "\nCannot exec %s", a);
134 perror(msg); /* display the reason */
135 askforreturn(); /* wait until the user sees the message */
136 myexit(1); /* exit the child */
137 /* NOTREACHED */
138 }
139
140 /** myfork acts like fork but also handles signals */
141
142 static pid_t
143 myfork(void)
144 {
145 pid_t p; /* process number */
146
147 p = fork();
148
149 /* the parent ignores the interrupt, quit, and hangup signals */
150 if (p > 0) {
151 oldsigquit = signal(SIGQUIT, SIG_IGN);
152 oldsighup = signal(SIGHUP, SIG_IGN);
153 #ifdef SIGTSTP
154 oldsigtstp = signal(SIGTSTP, SIG_DFL);
155 #endif
156 }
157 /* so they can be used to stop the child */
158 else if (p == 0) {
159 signal(SIGINT, SIG_DFL);
160 signal(SIGQUIT, SIG_DFL);
161 signal(SIGHUP, SIG_DFL);
162 #ifdef SIGTSTP
163 signal(SIGTSTP, SIG_DFL);
164 #endif
165 }
166 /* check for fork failure */
167 if (p == -1) {
168 myperror("Cannot fork");
169 }
170 return p;
171 }
172
173 /** join is the compliment of fork */
174
175 static int
176 join(pid_t p)
177 {
178 int status;
179 pid_t w;
180
181 /* wait for the correct child to exit */
182 do {
183 w = wait(&status);
184 } while (p != -1 && w != p);
185
186 /* restore signal handling */
187 signal(SIGQUIT, oldsigquit);
188 signal(SIGHUP, oldsighup);
189 #ifdef SIGTSTP
190 signal(SIGTSTP, oldsigtstp);
191 #endif
192
193 /* return the child's exit code */
194 return(status >> 8);
195 }
196
197 #endif /* !MSDOS */
/* */