1 /* exec.c -- Implementation of -exec, -execdir, -ok, -okdir.
2 Copyright (C) 1990, 1991, 1992, 1993, 1994, 2000, 2003,
3 2004, 2005, 2006, 2007, 2008, 2009,
4 2010 Free Software Foundation, Inc.
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 /* config.h must be included first. */
39 /* findutils headers */
46 # define _(Text) gettext (Text)
51 # define N_(String) gettext_noop (String)
53 /* See locate.c for explanation as to why not use (String) */
54 # define N_(String) String
58 /* Initialize exec->wd_for_exec.
60 We save in exec->wd_for_exec the directory whose path relative to
64 initialize_wd_for_exec (struct exec_val *execp, int cwd_fd, const char *dir)
66 execp->wd_for_exec = xmalloc (sizeof (*execp->wd_for_exec));
67 execp->wd_for_exec->name = NULL;
68 execp->wd_for_exec->desc = openat (cwd_fd, dir, O_RDONLY);
69 if (execp->wd_for_exec->desc < 0)
71 set_cloexec_flag (execp->wd_for_exec->desc, true);
77 record_exec_dir (struct exec_val *execp)
79 if (!execp->state.todo)
81 /* working directory not already known, so must be a *dir variant,
82 and this must be the first arg we added. However, this may
83 be -execdir foo {} \; (i.e. not multiple). */
84 assert (!execp->state.todo);
86 /* Record the WD. If we're using -L or fts chooses to do so for
87 any other reason, state.cwd_dir_fd may in fact not be the
88 directory containing the target file. When this happens,
89 rel_path will contain directory components (since it is the
90 path from state.cwd_dir_fd to the target file).
92 We deal with this by extracting any directory part and using
93 that to adjust what goes into execp->wd_for_exec.
95 if (strchr (state.rel_pathname, '/'))
97 char *dir = mdir_name (state.rel_pathname);
98 bool result = initialize_wd_for_exec (execp, state.cwd_dir_fd, dir);
104 return initialize_wd_for_exec (execp, state.cwd_dir_fd, ".");
114 impl_pred_exec (const char *pathname,
115 struct stat *stat_buf,
116 struct predicate *pred_ptr)
118 struct exec_val *execp = &pred_ptr->args.exec_vec;
122 const bool local = is_exec_in_local_dir (pred_ptr->pred_func);
129 /* For -execdir/-okdir predicates, the parser did not fill in
130 the wd_for_exec member of struct exec_val. So for those
131 predicates, we do so now.
133 if (!record_exec_dir (execp))
135 error (EXIT_FAILURE, errno,
136 _("Failed to save working directory in order to "
137 "run a command on %s"),
138 safely_quote_err_filename (0, pathname));
141 target = buf = base_name (state.rel_pathname);
142 if ('/' == target[0])
144 /* find / execdir ls -d {} \; */
156 /* For the others (-exec, -ok), the parser should
157 have set wd_for_exec to initial_wd, indicating
158 that the exec should take place from find's initial
161 assert (execp->wd_for_exec == initial_wd);
169 /* Push the argument onto the current list.
170 * The command may or may not be run at this point,
171 * depending on the command line length limits.
173 bc_push_arg (&execp->ctl,
175 target, strlen (target)+1,
179 /* remember that there are pending execdirs. */
180 if (execp->state.todo)
181 state.execdirs_outstanding = true;
183 /* POSIX: If the primary expression is punctuated by a plus
184 * sign, the primary shall always evaluate as true
192 for (i=0; i<execp->num_args; ++i)
194 bc_do_insert (&execp->ctl,
196 execp->replace_vec[i],
197 strlen (execp->replace_vec[i]),
199 target, strlen (target),
203 /* Actually invoke the command. */
204 bc_do_exec (&execp->ctl, &execp->state);
205 if (WIFEXITED(execp->last_child_status))
207 if (0 == WEXITSTATUS(execp->last_child_status))
208 result = true; /* The child succeeded. */
217 free_cwd (execp->wd_for_exec);
229 /* 1) fork to get a child; parent remembers the child pid
230 2) child execs the command requested
231 3) parent waits for child; checks for proper pid of child
235 ret errno status(h) status(l)
237 pid x signal# 0177 stopped
238 pid x exit arg 0 term by _exit
239 pid x 0 signal # term by signal
240 -1 EINTR parent got signal
241 -1 other some other kind of error
243 Return true only if the pid matches, status(l) is
244 zero, and the exit arg (status high) is 0.
245 Otherwise return false, possibly printing an error message. */
247 prep_child_for_exec (bool close_stdin, const struct saved_cwd *wd)
252 const char inputfile[] = "/dev/null";
256 error (0, errno, _("Cannot close standard input"));
261 if (open (inputfile, O_RDONLY
262 #if defined O_LARGEFILE
267 /* This is not entirely fatal, since
268 * executing the child with a closed
269 * stdin is almost as good as executing it
270 * with its stdin attached to /dev/null.
272 error (0, errno, "%s", safely_quote_err_filename (0, inputfile));
273 /* do not set ok=false, it is OK to continue anyway. */
278 /* Even if DebugSearch is set, don't announce our change of
279 * directory, since we're not going to emit a subsequent
280 * announcement of a call to stat() anyway, as we're about to exec
283 if (0 != restore_cwd (wd))
285 error (0, errno, _("Failed to change directory"));
293 launch (struct buildcmd_control *ctl, void *usercontext, int argc, char **argv)
296 static int first_time = 1;
297 struct exec_val *execp = usercontext;
299 /* Make sure output of command doesn't get mixed with find output. */
303 /* Make sure to listen for the kids. */
307 signal (SIGCHLD, SIG_DFL);
312 error (EXIT_FAILURE, errno, _("cannot fork"));
315 /* We are the child. */
316 assert (NULL != execp->wd_for_exec);
317 if (!prep_child_for_exec (execp->close_stdin, execp->wd_for_exec))
323 if (fd_leak_check_is_enabled ())
325 complain_about_leaky_fds ();
329 if (bc_args_exceed_testing_limit (argv))
332 execvp (argv[0], argv);
333 /* TODO: use a pipe to pass back the errno value, like xargs does */
334 error (0, errno, "%s",
335 safely_quote_err_filename (0, argv[0]));
339 while (waitpid (child_pid, &(execp->last_child_status), 0) == (pid_t) -1)
343 error (0, errno, _("error waiting for %s"),
344 safely_quote_err_filename (0, argv[0]));
345 state.exit_status = 1;
350 if (WIFSIGNALED (execp->last_child_status))
352 error (0, 0, _("%s terminated by signal %d"),
353 quotearg_n_style (0, options.err_quoting_style, argv[0]),
354 WTERMSIG (execp->last_child_status));
358 /* -exec \; just returns false if the invoked command fails.
359 * -exec {} + returns true if the invoked command fails, but
360 * sets the program exit status.
362 state.exit_status = 1;
368 if (0 == WEXITSTATUS (execp->last_child_status))
376 /* -exec \; just returns false if the invoked command fails.
377 * -exec {} + returns true if the invoked command fails, but
378 * sets the program exit status.
380 state.exit_status = 1;
382 /* The child failed, but this is the exec callback. We
383 * don't want to run the child again in this case anwyay.
385 return 1; /* FAIL (but don't try again) */