void complete_pending_execdirs(int dir_fd) { if (state.execdirs_outstanding) { do_complete_pending_execdirs(get_eval_tree(), dir_fd); state.execdirs_outstanding = false; } }
/* Complete any outstanding commands. */ void cleanup(void) { struct predicate *eval_tree = get_eval_tree(); if (eval_tree) { traverse_tree(eval_tree, complete_pending_execs); complete_pending_execdirs(get_current_dirfd()); traverse_tree(eval_tree, flush_and_close_output_files); } }
static void do_process_predicate (char *pathname, char *base, int mode, ino_t inum, struct stat *pstat) { (void) mode; (void) inum; state.rel_pathname = base; /* cwd_dir_fd was already set by safely_chdir */ apply_predicate (pathname, pstat, get_eval_tree ()); }
static void show_outstanding_execdirs (FILE *fp) { if (options.debug_options & DebugExec) { int seen=0; struct predicate *p; p = get_eval_tree (); fprintf (fp, "Outstanding execdirs:"); while (p) { const char *pfx; if (pred_is (p, pred_execdir)) pfx = "-execdir"; else if (pred_is (p, pred_okdir)) pfx = "-okdir"; else pfx = NULL; if (pfx) { size_t i; const struct exec_val *execp = &p->args.exec_vec; ++seen; fprintf (fp, "%s ", pfx); if (execp->multiple) fprintf (fp, "multiple "); fprintf (fp, "%" PRIuMAX " args: ", (uintmax_t) execp->state.cmd_argc); for (i=0; i<execp->state.cmd_argc; ++i) { fprintf (fp, "%s ", execp->state.cmd_argv[i]); } fprintf (fp, "\n"); } p = p->pred_next; } if (!seen) fprintf (fp, " none\n"); } else { /* No debug output is wanted. */ } }
static void visit (FTS *p, FTSENT *ent, struct stat *pstat) { struct predicate *eval_tree; state.have_stat = (ent->fts_info != FTS_NS) && (ent->fts_info != FTS_NSOK); state.rel_pathname = ent->fts_accpath; state.cwd_dir_fd = p->fts_cwd_fd; /* Apply the predicates to this path. */ eval_tree = get_eval_tree (); apply_predicate (ent->fts_path, pstat, eval_tree); /* Deal with any side effects of applying the predicates. */ if (state.stop_at_current_level) { fts_set (p, ent, FTS_SKIP); } }
static int process_path (char *pathname, char *name, bool leaf, char *parent, mode_t mode, ino_t inum) { struct stat stat_buf; static dev_t root_dev; /* Device ID of current argument pathname. */ int i; struct predicate *eval_tree; eval_tree = get_eval_tree (); /* Assume it is a non-directory initially. */ stat_buf.st_mode = 0; /* The caller usually knows the inode number, either from readdir or * a *stat call. We use that value (the caller passes 0 to indicate * ignorance of the inode number). */ stat_buf.st_ino = inum; state.rel_pathname = name; state.type = 0; state.have_stat = false; state.have_type = false; state.already_issued_stat_error_msg = false; if (!digest_mode (&mode, pathname, name, &stat_buf, leaf)) return 0; if (!S_ISDIR (state.type)) { if (state.curdepth >= options.mindepth) apply_predicate (pathname, &stat_buf, eval_tree); return 0; } /* From here on, we're working on a directory. */ /* Now we really need to stat the directory, even if we know the * type, because we need information like struct stat.st_rdev. */ if (get_statinfo (pathname, name, &stat_buf) != 0) return 0; state.have_stat = true; mode = state.type = stat_buf.st_mode; /* use full info now that we have it. */ state.stop_at_current_level = options.maxdepth >= 0 && state.curdepth >= options.maxdepth; /* If we've already seen this directory on this branch, don't descend it again. */ for (i = 0; i <= dir_curr; i++) if (stat_buf.st_ino == dir_ids[i].ino && stat_buf.st_dev == dir_ids[i].dev) { state.stop_at_current_level = true; issue_loop_warning (name, pathname, i); } if (dir_alloc <= ++dir_curr) { dir_alloc += DIR_ALLOC_STEP; dir_ids = (struct dir_id *) xrealloc ((char *) dir_ids, dir_alloc * sizeof (struct dir_id)); } dir_ids[dir_curr].ino = stat_buf.st_ino; dir_ids[dir_curr].dev = stat_buf.st_dev; if (options.stay_on_filesystem) { if (state.curdepth == 0) root_dev = stat_buf.st_dev; else if (stat_buf.st_dev != root_dev) state.stop_at_current_level = true; } if (options.do_dir_first && state.curdepth >= options.mindepth) apply_predicate (pathname, &stat_buf, eval_tree); if (options.debug_options & DebugSearch) fprintf (stderr, "pathname = %s, stop_at_current_level = %d\n", pathname, state.stop_at_current_level); if (state.stop_at_current_level == false) { /* Scan directory on disk. */ process_dir (pathname, name, strlen (pathname), &stat_buf, parent); } if (options.do_dir_first == false && state.curdepth >= options.mindepth) { /* The fields in 'state' are now out of date. Correct them. */ if (!digest_mode (&mode, pathname, name, &stat_buf, leaf)) return 0; if (0 == dir_curr) { at_top (pathname, mode, stat_buf.st_ino, &stat_buf, do_process_predicate); } else { do_process_predicate (pathname, name, mode, stat_buf.st_ino, &stat_buf); } } dir_curr--; return 1; }