Exemplo n.º 1
0
int
main (int argc, char **argv)
{
  int end_of_leading_options = 0; /* First arg after any -H/-L etc. */
  struct predicate *eval_tree;

  if (argv[0])
    set_program_name (argv[0]);
  else
    set_program_name ("find");

  record_initial_cwd ();

  state.already_issued_stat_error_msg = false;
  state.exit_status = 0;
  state.execdirs_outstanding = false;
  state.cwd_dir_fd = AT_FDCWD;

  if (fd_leak_check_is_enabled ())
    {
      remember_non_cloexec_fds ();
    }

  state.shared_files = sharefile_init ("w");
  if (NULL == state.shared_files)
    {
      error (EXIT_FAILURE, errno,
	     _("Failed initialise shared-file hash table"));
    }

  /* Set the option defaults before we do the locale initialisation as
   * check_nofollow() needs to be executed in the POSIX locale.
   */
  set_option_defaults (&options);

#ifdef HAVE_SETLOCALE
  setlocale (LC_ALL, "");
#endif

  bindtextdomain (PACKAGE, LOCALEDIR);
  textdomain (PACKAGE);
  if (atexit (close_stdout))
    {
      error (EXIT_FAILURE, errno, _("The atexit library function failed"));
    }

  /* Check for -P, -H or -L options.  Also -D and -O, which are
   * both GNU extensions.
   */
  end_of_leading_options = process_leading_options (argc, argv);

  if (options.debug_options & DebugStat)
    options.xstat = debug_stat;

#ifdef DEBUG
  fprintf (stderr, "cur_day_start = %s", ctime (&options.cur_day_start));
#endif /* DEBUG */


  /* We are now processing the part of the "find" command line
   * after the -H/-L options (if any).
   */
  eval_tree = build_expression_tree (argc, argv, end_of_leading_options);

  /* safely_chdir() needs to check that it has ended up in the right place.
   * To avoid bailing out when something gets automounted, it checks if
   * the target directory appears to have had a directory mounted on it as
   * we chdir()ed.  The problem with this is that in order to notice that
   * a file system was mounted, we would need to lstat() all the mount points.
   * That strategy loses if our machine is a client of a dead NFS server.
   *
   * Hence if safely_chdir() and wd_sanity_check() can manage without needing
   * to know the mounted device list, we do that.
   */
  if (!options.open_nofollow_available)
    {
#ifdef STAT_MOUNTPOINTS
      init_mounted_dev_list ();
#endif
    }


  /* process_all_startpoints processes the starting points named on
   * the command line.  A false return value from it means that we
   * failed to restore the original context.  That means it would not
   * be safe to call cleanup() since we might complete an execdir in
   * the wrong directory for example.
   */
  if (process_all_startpoints (argc-end_of_leading_options,
			       argv+end_of_leading_options))
    {
      /* If "-exec ... {} +" has been used, there may be some
       * partially-full command lines which have been built,
       * but which are not yet complete.   Execute those now.
       */
      show_success_rates (eval_tree);
      cleanup ();
    }
  return state.exit_status;
}
Exemplo n.º 2
0
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) */
    }

}
Exemplo n.º 3
0
/* CAUTION: this is the entry point for the oldfind executable, which is not the binary that
 * will actually get installed.   See ftsfind.c. */
int
main (int argc, char **argv)
{
  int i;
  int end_of_leading_options = 0; /* First arg after any -H/-L etc. */
  struct predicate *eval_tree;

  if (argv[0])
    set_program_name (argv[0]);
  else
    set_program_name ("find");

  state.exit_status = 0;

  if (fd_leak_check_is_enabled ())
    {
      remember_non_cloexec_fds ();
    }

  record_initial_cwd ();

  state.already_issued_stat_error_msg = false;
  state.shared_files = sharefile_init ("w");
  if (NULL == state.shared_files)
    {
      error (EXIT_FAILURE, errno,
	     _("Failed to initialize shared-file hash table"));
    }

  /* Set the option defaults before we do the locale
   * initialisation as check_nofollow () needs to be executed in the
   * POSIX locale.
   */
  set_option_defaults (&options);

#ifdef HAVE_SETLOCALE
  setlocale (LC_ALL, "");
#endif
  bindtextdomain (PACKAGE, LOCALEDIR);
  textdomain (PACKAGE);
  if (atexit (close_stdin))
    {
      error (EXIT_FAILURE, errno, _("The atexit library function failed"));
    }

  /* Check for -P, -H or -L options. */
  end_of_leading_options = process_leading_options (argc, argv);

  if (options.debug_options & DebugStat)
    options.xstat = debug_stat;

#ifdef DEBUG
  fprintf (stderr, "cur_day_start = %s", ctime (&options.cur_day_start));
#endif /* DEBUG */

  /* state.cwd_dir_fd has to be initialized before we call build_expression_tree ()
   * because command-line parsing may lead us to stat some files.
   */
  state.cwd_dir_fd = AT_FDCWD;

  /* We are now processing the part of the "find" command line
   * after the -H/-L options (if any).
   */
  eval_tree = build_expression_tree (argc, argv, end_of_leading_options);


  /* safely_chdir () needs to check that it has ended up in the right place.
   * To avoid bailing out when something gets automounted, it checks if
   * the target directory appears to have had a directory mounted on it as
   * we chdir ()ed.  The problem with this is that in order to notice that
   * a file system was mounted, we would need to lstat () all the mount points.
   * That strategy loses if our machine is a client of a dead NFS server.
   *
   * Hence if safely_chdir () and wd_sanity_check () can manage without needing
   * to know the mounted device list, we do that.
   */
  if (!options.open_nofollow_available)
    {
#ifdef STAT_MOUNTPOINTS
      init_mounted_dev_list (0);
#endif
    }


  set_stat_placeholders (&starting_stat_buf);
  if ((*options.xstat) (".", &starting_stat_buf) != 0)
    error (EXIT_FAILURE, errno, _("cannot stat current directory"));

  /* If no paths are given, default to ".".  */
  for (i = end_of_leading_options; i < argc && !looks_like_expression (argv[i], true); i++)
    {
      process_top_path (argv[i], 0, starting_stat_buf.st_ino);
    }

  /* If there were no path arguments, default to ".". */
  if (i == end_of_leading_options)
    {
      /*
       * We use a temporary variable here because some actions modify
       * the path temporarily.  Hence if we use a string constant,
       * we get a coredump.  The best example of this is if we say
       * "find -printf %H" (note, not "find . -printf %H").
       */
      char defaultpath[2] = ".";
      process_top_path (defaultpath, 0, starting_stat_buf.st_ino);
    }

  /* If "-exec ... {} +" has been used, there may be some
   * partially-full command lines which have been built,
   * but which are not yet complete.   Execute those now.
   */
  show_success_rates (eval_tree);
  cleanup ();
  return state.exit_status;
}