summaryrefslogtreecommitdiff
path: root/find/pred.c
diff options
context:
space:
mode:
Diffstat (limited to 'find/pred.c')
-rw-r--r--find/pred.c335
1 files changed, 0 insertions, 335 deletions
diff --git a/find/pred.c b/find/pred.c
index 3b15a6e5..4aaebe24 100644
--- a/find/pred.c
+++ b/find/pred.c
@@ -20,7 +20,6 @@
#include "defs.h"
#include <fnmatch.h>
-#include <signal.h>
#include <math.h>
#include <pwd.h>
#include <grp.h>
@@ -40,7 +39,6 @@
#include "human.h"
#include "filemode.h"
#include "printquoted.h"
-#include "buildcmd.h"
#include "yesno.h"
#include "listfile.h"
#include "stat-time.h"
@@ -48,10 +46,7 @@
#include "dircallback.h"
#include "error.h"
#include "verify.h"
-#include "fdleak.h"
#include "areadlink.h"
-#include "cloexec.h"
-#include "save-cwd.h"
#include <selinux/selinux.h>
@@ -68,11 +63,6 @@
# define N_(String) String
#endif
-#if defined SIGCLD && !defined SIGCHLD
-# define SIGCHLD SIGCLD
-#endif
-
-
#ifdef CLOSEDIR_VOID
/* Fake a return value. */
#define CLOSEDIR(d) (closedir (d), 0)
@@ -425,166 +415,6 @@ pred_empty (const char *pathname, struct stat *stat_buf, struct predicate *pred_
}
-/* Initialise exec->wd_for_exec.
-
- We save in exec->wd_for_exec the directory whose path relative to
- cwd_df is dir.
- */
-static bool
-initialise_wd_for_exec (struct exec_val *execp, int cwd_fd, const char *dir)
-{
- execp->wd_for_exec = xmalloc (sizeof (*execp->wd_for_exec));
- execp->wd_for_exec->name = NULL;
- execp->wd_for_exec->desc = openat (cwd_fd, dir, O_RDONLY);
- if (execp->wd_for_exec->desc < 0)
- return false;
- set_cloexec_flag (execp->wd_for_exec->desc, true);
- return true;
-}
-
-
-static bool
-record_exec_dir (struct exec_val *execp)
-{
- if (!execp->state.todo)
- {
- /* Record the WD. If we're using -L or fts chooses to do so for
- any other reason, state.cwd_dir_fd may in fact not be the
- directory containing the target file. When this happens,
- rel_path will contain directory components (since it is the
- path from state.cwd_dir_fd to the target file).
-
- We deal with this by extracting any directory part and using
- that to adjust what goes into execp->wd_for_exec.
- */
- if (strchr (state.rel_pathname, '/'))
- {
- char *dir = mdir_name (state.rel_pathname);
- bool result = initialise_wd_for_exec (execp, state.cwd_dir_fd, dir);
- free (dir);
- return result;
- }
- else
- {
- return initialise_wd_for_exec (execp, state.cwd_dir_fd, ".");
- }
- }
- return true;
-}
-
-
-static bool
-impl_pred_exec (const char *pathname,
- struct stat *stat_buf,
- struct predicate *pred_ptr)
-{
- struct exec_val *execp = &pred_ptr->args.exec_vec;
- char *buf = NULL;
- const char *target;
- bool result;
- const bool local = is_exec_in_local_dir (pred_ptr->pred_func);
- const char *prefix;
- size_t pfxlen;
-
- (void) stat_buf;
- if (local)
- {
- /* For -execdir/-okdir predicates, the parser did not fill in
- the wd_for_exec member of sturct exec_val. So for those
- predicates, we do so now.
- */
- if (!record_exec_dir (execp))
- {
- error (EXIT_FAILURE, errno,
- _("Failed to save working directory in order to "
- "run a command on %s"),
- safely_quote_err_filename (0, pathname));
- /*NOTREACHED*/
- }
- target = buf = base_name (state.rel_pathname);
- if ('/' == target[0])
- {
- /* find / execdir ls -d {} \; */
- prefix = NULL;
- pfxlen = 0;
- }
- else
- {
- prefix = "./";
- pfxlen = 2u;
- }
- }
- else
- {
- /* For the others (-exec, -ok), the parser should
- have set wd_for_exec to initial_wd, indicating
- that the exec should take place from find's initial
- working directory.
- */
- assert (execp->wd_for_exec == initial_wd);
- target = pathname;
- prefix = NULL;
- pfxlen = 0u;
- }
-
- if (execp->multiple)
- {
- /* Push the argument onto the current list.
- * The command may or may not be run at this point,
- * depending on the command line length limits.
- */
- bc_push_arg (&execp->ctl,
- &execp->state,
- target, strlen (target)+1,
- prefix, pfxlen,
- 0);
-
- /* remember that there are pending execdirs. */
- state.execdirs_outstanding = true;
-
- /* POSIX: If the primary expression is punctuated by a plus
- * sign, the primary shall always evaluate as true
- */
- result = true;
- }
- else
- {
- int i;
-
- for (i=0; i<execp->num_args; ++i)
- {
- bc_do_insert (&execp->ctl,
- &execp->state,
- execp->replace_vec[i],
- strlen (execp->replace_vec[i]),
- prefix, pfxlen,
- target, strlen (target),
- 0);
- }
-
- /* Actually invoke the command. */
- bc_do_exec (&execp->ctl, &execp->state);
- if (WIFEXITED(execp->last_child_status))
- {
- if (0 == WEXITSTATUS(execp->last_child_status))
- result = true; /* The child succeeded. */
- else
- result = false;
- }
- else
- {
- result = false;
- }
- }
- if (buf)
- {
- assert (local);
- free (buf);
- }
- return result;
-}
-
-
bool
pred_exec (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
{
@@ -1915,172 +1745,7 @@ pred_context (const char *pathname, struct stat *stat_buf,
}
-/* 1) fork to get a child; parent remembers the child pid
- 2) child execs the command requested
- 3) parent waits for child; checks for proper pid of child
-
- Possible returns:
-
- ret errno status(h) status(l)
-
- pid x signal# 0177 stopped
- pid x exit arg 0 term by _exit
- pid x 0 signal # term by signal
- -1 EINTR parent got signal
- -1 other some other kind of error
-
- Return true only if the pid matches, status(l) is
- zero, and the exit arg (status high) is 0.
- Otherwise return false, possibly printing an error message. */
-
-
-static bool
-prep_child_for_exec (bool close_stdin, const struct saved_cwd *wd)
-{
- bool ok = true;
- if (close_stdin)
- {
- const char inputfile[] = "/dev/null";
-
- if (close (0) < 0)
- {
- error (0, errno, _("Cannot close standard input"));
- ok = false;
- }
- else
- {
- if (open (inputfile, O_RDONLY
-#if defined O_LARGEFILE
- |O_LARGEFILE
-#endif
- ) < 0)
- {
- /* This is not entirely fatal, since
- * executing the child with a closed
- * stdin is almost as good as executing it
- * with its stdin attached to /dev/null.
- */
- error (0, errno, "%s", safely_quote_err_filename (0, inputfile));
- /* do not set ok=false, it is OK to continue anyway. */
- }
- }
- }
-
- /* Even if DebugSearch is set, don't announce our change of
- * directory, since we're not going to emit a subsequent
- * announcement of a call to stat() anyway, as we're about to exec
- * something.
- */
- if (0 != restore_cwd (wd))
- {
- error (0, errno, _("Failed to change directory"));
- ok = false;
- }
- return ok;
-}
-
-
-
-
-
-
-int
-launch (struct buildcmd_control *ctl, void *usercontext, int argc, char **argv)
-{
- pid_t child_pid;
- static int first_time = 1;
- struct exec_val *execp = usercontext;
-
- /* Make sure output of command doesn't get mixed with find output. */
- fflush (stdout);
- fflush (stderr);
-
- /* Make sure to listen for the kids. */
- if (first_time)
- {
- first_time = 0;
- signal (SIGCHLD, SIG_DFL);
- }
-
- child_pid = fork ();
- if (child_pid == -1)
- error (EXIT_FAILURE, errno, _("cannot fork"));
- if (child_pid == 0)
- {
- /* We are the child. */
- assert (NULL != execp->wd_for_exec);
- if (!prep_child_for_exec (execp->close_stdin, execp->wd_for_exec))
- {
- _exit (1);
- }
- else
- {
- if (fd_leak_check_is_enabled ())
- {
- complain_about_leaky_fds ();
- }
- }
-
- if (bc_args_exceed_testing_limit (argv))
- errno = E2BIG;
- else
- execvp (argv[0], argv);
- /* TODO: use a pipe to pass back the errno value, like xargs does */
- error (0, errno, "%s",
- safely_quote_err_filename (0, argv[0]));
- _exit (1);
- }
-
- while (waitpid (child_pid, &(execp->last_child_status), 0) == (pid_t) -1)
- {
- if (errno != EINTR)
- {
- error (0, errno, _("error waiting for %s"),
- safely_quote_err_filename (0, argv[0]));
- state.exit_status = 1;
- return 0; /* FAIL */
- }
- }
-
- if (WIFSIGNALED (execp->last_child_status))
- {
- error (0, 0, _("%s terminated by signal %d"),
- quotearg_n_style (0, options.err_quoting_style, argv[0]),
- WTERMSIG (execp->last_child_status));
-
- if (execp->multiple)
- {
- /* -exec \; just returns false if the invoked command fails.
- * -exec {} + returns true if the invoked command fails, but
- * sets the program exit status.
- */
- state.exit_status = 1;
- }
-
- return 1; /* OK */
- }
-
- if (0 == WEXITSTATUS (execp->last_child_status))
- {
- return 1; /* OK */
- }
- else
- {
- if (execp->multiple)
- {
- /* -exec \; just returns false if the invoked command fails.
- * -exec {} + returns true if the invoked command fails, but
- * sets the program exit status.
- */
- state.exit_status = 1;
- }
- /* The child failed, but this is the exec callback. We
- * don't want to run the child again in this case anwyay.
- */
- return 1; /* FAIL (but don't try again) */
- }
-}
static bool