1 /* exec.c -- Implementation of -exec, -execdir, -ok, -okdir.
2 Copyright (C) 1990-2022 Free Software Foundation, Inc.
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18 /* config.h must be included first. */
19 #include <config.h>
20
21 /* system headers. */
22 #include <assert.h>
23 #include <errno.h>
24 #include <fcntl.h>
25 #include <signal.h>
26 #include <sys/wait.h>
27
28
29 /* gnulib headers */
30 #include "cloexec.h"
31 #include "dirname.h"
32 #include "error.h"
33 #include "fcntl--.h"
34 #include "save-cwd.h"
35 #include "xalloc.h"
36
37 /* findutils headers */
38 #include "buildcmd.h"
39 #include "defs.h"
40 #include "die.h"
41 #include "fdleak.h"
42 #include "system.h"
43
44
45 /* Initialize exec->wd_for_exec.
46
47 We save in exec->wd_for_exec the directory whose path relative to
48 cwd_df is dir.
49 */
50 static bool
51 initialize_wd_for_exec (struct exec_val *execp, int cwd_fd, const char *dir)
52 {
53 execp->wd_for_exec = xmalloc (sizeof (*execp->wd_for_exec));
54 execp->wd_for_exec->name = NULL;
55 execp->wd_for_exec->desc = openat (cwd_fd, dir, O_RDONLY);
56 if (execp->wd_for_exec->desc < 0)
57 return false;
58 set_cloexec_flag (execp->wd_for_exec->desc, true);
59 return true;
60 }
61
62
63 static bool
64 record_exec_dir (struct exec_val *execp)
65 {
66 if (!execp->state.todo)
67 {
68 /* working directory not already known, so must be a *dir variant,
69 and this must be the first arg we added. However, this may
70 be -execdir foo {} \; (i.e. not multiple). */
71 assert (!execp->state.todo);
72
73 /* Record the WD. If we're using -L or fts chooses to do so for
74 any other reason, state.cwd_dir_fd may in fact not be the
75 directory containing the target file. When this happens,
76 rel_path will contain directory components (since it is the
77 path from state.cwd_dir_fd to the target file).
78
79 We deal with this by extracting any directory part and using
80 that to adjust what goes into execp->wd_for_exec.
81 */
82 if (strchr (state.rel_pathname, '/'))
83 {
84 char *dir = mdir_name (state.rel_pathname);
85 bool result = initialize_wd_for_exec (execp, state.cwd_dir_fd, dir);
86 free (dir);
87 return result;
88 }
89 else
90 {
91 return initialize_wd_for_exec (execp, state.cwd_dir_fd, ".");
92 }
93 }
94 return true;
95 }
96
97
98
99
100 bool
101 impl_pred_exec (const char *pathname,
102 struct stat *stat_buf,
103 struct predicate *pred_ptr)
104 {
105 struct exec_val *execp = &pred_ptr->args.exec_vec;
106 char *buf = NULL;
107 const char *target;
108 bool result;
109 const bool local = is_exec_in_local_dir (pred_ptr->pred_func);
110 const char *prefix;
111 size_t pfxlen;
112
113 (void) stat_buf;
114 if (local)
115 {
116 /* For -execdir/-okdir predicates, the parser did not fill in
117 the wd_for_exec member of struct exec_val. So for those
118 predicates, we do so now.
119 */
120 if (!record_exec_dir (execp))
121 {
122 die (EXIT_FAILURE, errno,
123 _("Failed to save working directory in order to "
124 "run a command on %s"),
125 safely_quote_err_filename (0, pathname));
126 /*NOTREACHED*/
127 }
128 target = buf = base_name (state.rel_pathname);
129 if ('/' == target[0])
130 {
131 /* find / execdir ls -d {} \; */
132 prefix = NULL;
133 pfxlen = 0;
134 }
135 else
136 {
137 prefix = "./";
138 pfxlen = 2u;
139 }
140 }
141 else
142 {
143 /* For the others (-exec, -ok), the parser should
144 have set wd_for_exec to initial_wd, indicating
145 that the exec should take place from find's initial
146 working directory.
147 */
148 assert (execp->wd_for_exec == initial_wd);
149 target = pathname;
150 prefix = NULL;
151 pfxlen = 0u;
152 }
153
154 if (execp->multiple)
155 {
156 /* Push the argument onto the current list.
157 * The command may or may not be run at this point,
158 * depending on the command line length limits.
159 */
160 bc_push_arg (&execp->ctl,
161 &execp->state,
162 target, strlen (target)+1,
163 prefix, pfxlen,
164 0);
165
166 /* remember that there are pending execdirs. */
167 if (execp->state.todo)
168 state.execdirs_outstanding = true;
169
170 /* POSIX: If the primary expression is punctuated by a plus
171 * sign, the primary shall always evaluate as true
172 */
173 result = true;
174 }
175 else
176 {
177 int i;
178
179 for (i=0; i<execp->num_args; ++i)
180 {
181 bc_do_insert (&execp->ctl,
182 &execp->state,
183 execp->replace_vec[i],
184 strlen (execp->replace_vec[i]),
185 prefix, pfxlen,
186 target, strlen (target),
187 0);
188 }
189
190 /* Actually invoke the command. */
191 bc_do_exec (&execp->ctl, &execp->state);
192 if (WIFEXITED(execp->last_child_status))
193 {
194 if (0 == WEXITSTATUS(execp->last_child_status))
195 result = true; /* The child succeeded. */
196 else
197 result = false;
198 }
199 else
200 {
201 result = false;
202 }
203 if (local)
204 free_cwd (execp->wd_for_exec);
205 }
206 if (buf)
207 {
208 assert (local);
209 free (buf);
210 }
211 return result;
212 }
213
214
215
216 /* 1) fork to get a child; parent remembers the child pid
217 2) child execs the command requested
218 3) parent waits for child; checks for proper pid of child
219
220 Possible returns:
221
222 ret errno status(h) status(l)
223
224 pid x signal# 0177 stopped
225 pid x exit arg 0 term by _exit
226 pid x 0 signal # term by signal
227 -1 EINTR parent got signal
228 -1 other some other kind of error
229
230 Return true only if the pid matches, status(l) is
231 zero, and the exit arg (status high) is 0.
232 Otherwise return false, possibly printing an error message. */
233 static bool
234 prep_child_for_exec (bool close_stdin, const struct saved_cwd *wd)
235 {
236 bool ok = true;
237 if (close_stdin)
238 {
239 const char inputfile[] = "/dev/null";
240
241 if (close (0) < 0)
242 {
243 error (0, errno, _("Cannot close standard input"));
244 ok = false;
245 }
246 else
247 {
248 if (open (inputfile, O_RDONLY
249 #if defined O_LARGEFILE
250 |O_LARGEFILE
251 #endif
252 ) < 0)
253 {
254 /* This is not entirely fatal, since
255 * executing the child with a closed
256 * stdin is almost as good as executing it
257 * with its stdin attached to /dev/null.
258 */
259 error (0, errno, "%s", safely_quote_err_filename (0, inputfile));
260 /* do not set ok=false, it is OK to continue anyway. */
261 }
262 }
263 }
264
265 /* Even if DebugSearch is set, don't announce our change of
266 * directory, since we're not going to emit a subsequent
267 * announcement of a call to stat() anyway, as we're about to exec
268 * something.
269 */
270 if (0 != restore_cwd (wd))
271 {
272 error (0, errno, _("Failed to change directory%s%s"),
273 (wd->desc < 0 && wd->name) ? ": " : "",
274 (wd->desc < 0 && wd->name) ? wd->name : "");
275 ok = false;
276 }
277 return ok;
278 }
279
280
281 int
282 launch (struct buildcmd_control *ctl, void *usercontext, int argc, char **argv)
283 {
284 pid_t child_pid;
285 static int first_time = 1;
286 struct exec_val *execp = usercontext;
287
288 (void) ctl; /* silence compiler warning */
289 (void) argc; /* silence compiler warning */
290
291 if (options.debug_options & DebugExec)
292 {
293 int i;
294 fprintf (stderr, "DebugExec: launching process (argc=%" PRIuMAX "):",
295 (uintmax_t) execp->state.cmd_argc - 1);
296 for (i=0; i<execp->state.cmd_argc -1; ++i)
297 {
298 fprintf (stderr, " %s",
299 safely_quote_err_filename (0, execp->state.cmd_argv[i]));
300 }
301 fprintf (stderr, "\n");
302 }
303
304 /* Make sure output of command doesn't get mixed with find output. */
305 fflush (stdout);
306 fflush (stderr);
307
308 /* Make sure to listen for the kids. */
309 if (first_time)
310 {
311 first_time = 0;
312 signal (SIGCHLD, SIG_DFL);
313 }
314
315 child_pid = fork ();
316 if (child_pid == -1)
317 die (EXIT_FAILURE, errno, _("cannot fork"));
318 if (child_pid == 0)
319 {
320 /* We are the child. */
321 assert (NULL != execp->wd_for_exec);
322 if (!prep_child_for_exec (execp->close_stdin, execp->wd_for_exec))
323 {
324 _exit (1);
325 }
326 else
327 {
328 if (fd_leak_check_is_enabled ())
329 {
330 complain_about_leaky_fds ();
331 }
332 }
333
334 if (bc_args_exceed_testing_limit (argv))
335 errno = E2BIG;
336 else
337 execvp (argv[0], argv);
338 /* TODO: use a pipe to pass back the errno value, like xargs does */
339 error (0, errno, "%s",
340 safely_quote_err_filename (0, argv[0]));
341 _exit (1);
342 }
343
344 while (waitpid (child_pid, &(execp->last_child_status), 0) == (pid_t) -1)
345 {
346 if (errno != EINTR)
347 {
348 error (0, errno, _("error waiting for %s"),
349 safely_quote_err_filename (0, argv[0]));
350 state.exit_status = EXIT_FAILURE;
351 return 0; /* FAIL */
352 }
353 }
354
355 if (WIFSIGNALED (execp->last_child_status))
356 {
357 error (0, 0, _("%s terminated by signal %d"),
358 quotearg_n_style (0, options.err_quoting_style, argv[0]),
359 WTERMSIG (execp->last_child_status));
360
361 if (execp->multiple)
362 {
363 /* -exec \; just returns false if the invoked command fails.
364 * -exec {} + returns true if the invoked command fails, but
365 * sets the program exit status.
366 */
367 state.exit_status = EXIT_FAILURE;
368 }
369
370 return 1; /* OK */
371 }
372
373 int ex = WEXITSTATUS (execp->last_child_status);
374 if (options.debug_options & DebugExec)
375 {
376 /* pid_t is of type long on Solaris 11. Cast CHILD_PID for use with
377 * %ld as long as gnulib doesn't provide portable PRIdPID. */
378 fprintf (stderr,
379 "DebugExec: process (PID=%ld) terminated with exit status: %d\n",
380 (long) child_pid, ex);
381 }
382
383 if (0 == ex)
384 {
385 return 1; /* OK */
386 }
387 else
388 {
389 if (execp->multiple)
390 {
391 /* -exec \; just returns false if the invoked command fails.
392 * -exec {} + returns true if the invoked command fails, but
393 * sets the program exit status.
394 */
395 state.exit_status = EXIT_FAILURE;
396 }
397 /* The child failed, but this is the exec callback. We
398 * don't want to run the child again in this case anwyay.
399 */
400 return 1; /* FAIL (but don't try again) */
401 }
402
403 }