packaging: remove old options to find hidden files
[platform/upstream/findutils.git] / find / exec.c
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.
5
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.
10
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.
15
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/>.
18 */
19
20 /* config.h must be included first. */
21 #include <config.h>
22
23 /* system headers. */
24 #include <assert.h>
25 #include <errno.h>
26 #include <fcntl.h>
27 #include <signal.h>
28 #include <sys/wait.h>
29
30
31 /* gnulib headers */
32 #include "cloexec.h"
33 #include "dirname.h"
34 #include "error.h"
35 #include "gettext.h"
36 #include "save-cwd.h"
37 #include "xalloc.h"
38
39 /* findutils headers */
40 #include "buildcmd.h"
41 #include "defs.h"
42 #include "fdleak.h"
43
44 #if ENABLE_NLS
45 # include <libintl.h>
46 # define _(Text) gettext (Text)
47 #else
48 # define _(Text) Text
49 #endif
50 #ifdef gettext_noop
51 # define N_(String) gettext_noop (String)
52 #else
53 /* See locate.c for explanation as to why not use (String) */
54 # define N_(String) String
55 #endif
56
57
58 /* Initialize exec->wd_for_exec.
59
60    We save in exec->wd_for_exec the directory whose path relative to
61    cwd_df is dir.
62  */
63 static bool
64 initialize_wd_for_exec (struct exec_val *execp, int cwd_fd, const char *dir)
65 {
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)
70     return false;
71   set_cloexec_flag (execp->wd_for_exec->desc, true);
72   return true;
73 }
74
75
76 static bool
77 record_exec_dir (struct exec_val *execp)
78 {
79   if (!execp->state.todo)
80     {
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);
85
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).
91
92          We deal with this by extracting any directory part and using
93          that to adjust what goes into execp->wd_for_exec.
94       */
95       if (strchr (state.rel_pathname, '/'))
96         {
97           char *dir = mdir_name (state.rel_pathname);
98           bool result = initialize_wd_for_exec (execp, state.cwd_dir_fd, dir);
99           free (dir);
100           return result;
101         }
102       else
103         {
104           return initialize_wd_for_exec (execp, state.cwd_dir_fd, ".");
105         }
106     }
107   return true;
108 }
109
110
111
112
113 bool
114 impl_pred_exec (const char *pathname,
115                 struct stat *stat_buf,
116                 struct predicate *pred_ptr)
117 {
118   struct exec_val *execp = &pred_ptr->args.exec_vec;
119   char *buf = NULL;
120   const char *target;
121   bool result;
122   const bool local = is_exec_in_local_dir (pred_ptr->pred_func);
123   char *prefix;
124   size_t pfxlen;
125
126   (void) stat_buf;
127   if (local)
128     {
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.
132       */
133       if (!record_exec_dir (execp))
134         {
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));
139           /*NOTREACHED*/
140         }
141       target = buf = base_name (state.rel_pathname);
142       if ('/' == target[0])
143         {
144           /* find / execdir ls -d {} \; */
145           prefix = NULL;
146           pfxlen = 0;
147         }
148       else
149         {
150           prefix = "./";
151           pfxlen = 2u;
152         }
153     }
154   else
155     {
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
159          working directory.
160       */
161       assert (execp->wd_for_exec == initial_wd);
162       target = pathname;
163       prefix = NULL;
164       pfxlen = 0u;
165     }
166
167   if (execp->multiple)
168     {
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.
172        */
173       bc_push_arg (&execp->ctl,
174                    &execp->state,
175                    target, strlen (target)+1,
176                    prefix, pfxlen,
177                    0);
178
179       /* remember that there are pending execdirs. */
180       if (execp->state.todo)
181         state.execdirs_outstanding = true;
182
183       /* POSIX: If the primary expression is punctuated by a plus
184        * sign, the primary shall always evaluate as true
185        */
186       result = true;
187     }
188   else
189     {
190       int i;
191
192       for (i=0; i<execp->num_args; ++i)
193         {
194           bc_do_insert (&execp->ctl,
195                         &execp->state,
196                         execp->replace_vec[i],
197                         strlen (execp->replace_vec[i]),
198                         prefix, pfxlen,
199                         target, strlen (target),
200                         0);
201         }
202
203       /* Actually invoke the command. */
204       bc_do_exec (&execp->ctl, &execp->state);
205       if (WIFEXITED(execp->last_child_status))
206         {
207           if (0 == WEXITSTATUS(execp->last_child_status))
208             result = true;        /* The child succeeded. */
209           else
210             result = false;
211         }
212       else
213         {
214           result = false;
215         }
216       if (local)
217         free_cwd (execp->wd_for_exec);
218     }
219   if (buf)
220     {
221       assert (local);
222       free (buf);
223     }
224   return result;
225 }
226
227
228
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
232
233     Possible returns:
234
235     ret         errno   status(h)   status(l)
236
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
242
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. */
246 static bool
247 prep_child_for_exec (bool close_stdin, const struct saved_cwd *wd)
248 {
249   bool ok = true;
250   if (close_stdin)
251     {
252       const char inputfile[] = "/dev/null";
253
254       if (close (0) < 0)
255         {
256           error (0, errno, _("Cannot close standard input"));
257           ok = false;
258         }
259       else
260         {
261           if (open (inputfile, O_RDONLY
262 #if defined O_LARGEFILE
263                    |O_LARGEFILE
264 #endif
265                    ) < 0)
266             {
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.
271                */
272               error (0, errno, "%s", safely_quote_err_filename (0, inputfile));
273               /* do not set ok=false, it is OK to continue anyway. */
274             }
275         }
276     }
277
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
281    * something.
282    */
283   if (0 != restore_cwd (wd))
284     {
285       error (0, errno, _("Failed to change directory"));
286       ok = false;
287     }
288   return ok;
289 }
290
291
292 int
293 launch (struct buildcmd_control *ctl, void *usercontext, int argc, char **argv)
294 {
295   pid_t child_pid;
296   static int first_time = 1;
297   struct exec_val *execp = usercontext;
298
299   /* Make sure output of command doesn't get mixed with find output. */
300   fflush (stdout);
301   fflush (stderr);
302
303   /* Make sure to listen for the kids.  */
304   if (first_time)
305     {
306       first_time = 0;
307       signal (SIGCHLD, SIG_DFL);
308     }
309
310   child_pid = fork ();
311   if (child_pid == -1)
312     error (EXIT_FAILURE, errno, _("cannot fork"));
313   if (child_pid == 0)
314     {
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))
318         {
319           _exit (1);
320         }
321       else
322         {
323           if (fd_leak_check_is_enabled ())
324             {
325               complain_about_leaky_fds ();
326             }
327         }
328
329       if (bc_args_exceed_testing_limit (argv))
330         errno = E2BIG;
331       else
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]));
336       _exit (1);
337     }
338
339   while (waitpid (child_pid, &(execp->last_child_status), 0) == (pid_t) -1)
340     {
341       if (errno != EINTR)
342         {
343           error (0, errno, _("error waiting for %s"),
344                  safely_quote_err_filename (0, argv[0]));
345           state.exit_status = 1;
346           return 0;             /* FAIL */
347         }
348     }
349
350   if (WIFSIGNALED (execp->last_child_status))
351     {
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));
355
356       if (execp->multiple)
357         {
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.
361            */
362           state.exit_status = 1;
363         }
364
365       return 1;                 /* OK */
366     }
367
368   if (0 == WEXITSTATUS (execp->last_child_status))
369     {
370       return 1;                 /* OK */
371     }
372   else
373     {
374       if (execp->multiple)
375         {
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.
379            */
380           state.exit_status = 1;
381         }
382       /* The child failed, but this is the exec callback.  We
383        * don't want to run the child again in this case anwyay.
384        */
385       return 1;                 /* FAIL (but don't try again) */
386     }
387
388 }