(root)/
findutils-4.9.0/
find/
defs.h
       1  /* defs.h -- data types and declarations.
       2     Copyright (C) 1990-2022 Free Software Foundation, Inc.
       3  
       4     This program is free software: you can redistribute it and/or modify
       5     it under the terms of the GNU General Public License as published by
       6     the Free Software Foundation, either version 3 of the License, or
       7     (at your option) any later version.
       8  
       9     This program is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12     GNU General Public License for more details.
      13  
      14     You should have received a copy of the GNU General Public License
      15     along with this program.  If not, see <https://www.gnu.org/licenses/>.
      16  */
      17  
      18  
      19  #ifndef INC_DEFS_H
      20  # define INC_DEFS_H 1
      21  
      22  # if !defined ALREADY_INCLUDED_CONFIG_H
      23  /*
      24   * Savannah bug #20128: if we include some system header and it
      25   * includes some other second system header, the second system header
      26   * may in fact turn out to be a file provided by gnulib.  For that
      27   * situation, we need to have already included <config.h> so that the
      28   * Gnulib files have access to the information probed by their
      29   * configure script fragments.  So <config.h> should be the first
      30   * thing included.
      31   */
      32  #  error "<config.h> should be #included before defs.h, and indeed before any other header"
      33  Please stop compiling the program now
      34  # endif
      35  
      36  
      37  # include <sys/types.h>
      38  
      39  /* XXX: some of these includes probably don't belong in a common header file */
      40  # include <sys/stat.h>
      41  # include <stdio.h>		/* for FILE* */
      42  # include <string.h>
      43  # include <stdlib.h>
      44  # include <unistd.h>
      45  # include <time.h>
      46  # include <limits.h>		/* for CHAR_BIT */
      47  # include <stdbool.h>		/* for bool */
      48  # include <stdint.h>		/* for uintmax_t */
      49  # include <sys/stat.h> /* S_ISUID etc. */
      50  # include <selinux/selinux.h>
      51  
      52  
      53  
      54  # ifndef CHAR_BIT
      55  #  define CHAR_BIT 8
      56  # endif
      57  
      58  # include <inttypes.h>
      59  
      60  # include "regex.h"
      61  # include "timespec.h"
      62  # include "buildcmd.h"
      63  # include "quotearg.h"
      64  # include "sharefile.h"
      65  # include "gcc-function-attributes.h"
      66  
      67  int optionl_stat (const char *name, struct stat *p);
      68  int optionp_stat (const char *name, struct stat *p);
      69  int optionh_stat (const char *name, struct stat *p);
      70  int debug_stat   (const char *file, struct stat *bufp);
      71  
      72  void set_stat_placeholders (struct stat *p);
      73  int get_statinfo (const char *pathname, const char *name, struct stat *p);
      74  
      75  
      76  # define MODE_WXUSR	(S_IWUSR | S_IXUSR)
      77  # define MODE_R		(S_IRUSR | S_IRGRP | S_IROTH)
      78  # define MODE_RW		(S_IWUSR | S_IWGRP | S_IWOTH | MODE_R)
      79  # define MODE_RWX	(S_IXUSR | S_IXGRP | S_IXOTH | MODE_RW)
      80  # define MODE_ALL	(S_ISUID | S_ISGID | S_ISVTX | MODE_RWX)
      81  
      82  
      83  struct predicate;
      84  struct options;
      85  
      86  /* Pointer to a predicate function. */
      87  typedef bool (*PRED_FUNC)(const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr);
      88  
      89  /* The number of seconds in a day. */
      90  # define DAYSECS	    86400
      91  
      92  /* Argument structures for predicates. */
      93  
      94  enum comparison_type
      95  {
      96    COMP_GT,
      97    COMP_LT,
      98    COMP_EQ
      99  };
     100  
     101  enum permissions_type
     102  {
     103    PERM_AT_LEAST,
     104    PERM_ANY,
     105    PERM_EXACT
     106  };
     107  
     108  enum predicate_type
     109  {
     110    NO_TYPE,
     111    PRIMARY_TYPE,
     112    UNI_OP,
     113    BI_OP,
     114    OPEN_PAREN,
     115    CLOSE_PAREN
     116  };
     117  
     118  enum predicate_precedence
     119  {
     120    NO_PREC,
     121    COMMA_PREC,
     122    OR_PREC,
     123    AND_PREC,
     124    NEGATE_PREC,
     125    MAX_PREC
     126  };
     127  
     128  struct long_val
     129  {
     130    enum comparison_type kind;
     131    bool negative;	 /* Defined only when representing time_t.  */
     132    uintmax_t l_val;
     133  };
     134  
     135  struct perm_val
     136  {
     137    enum permissions_type kind;
     138    mode_t val[2];
     139  };
     140  
     141  /* samefile_file_id is used to support the -samefile test.
     142   */
     143  struct samefile_file_id
     144  {
     145    ino_t ino;
     146    dev_t dev;
     147    int   fd;
     148  };
     149  
     150  struct size_val
     151  {
     152    enum comparison_type kind;
     153    int blocksize;
     154    uintmax_t size;
     155  };
     156  
     157  /* Supported file types for the -type/-xtype options.  */
     158  enum file_type
     159    {
     160      FTYPE_BLK,
     161      FTYPE_CHR,
     162      FTYPE_DIR,
     163      FTYPE_REG,
     164  # ifdef S_IFLNK
     165      FTYPE_LNK,
     166  # endif
     167  # ifdef S_IFIFO
     168      FTYPE_FIFO,
     169  # endif
     170  # ifdef S_IFSOCK
     171      FTYPE_SOCK,
     172  # endif
     173  # ifdef S_IFDOOR
     174      FTYPE_DOOR,
     175  # endif
     176      FTYPE_COUNT
     177    };
     178  
     179  enum xval
     180    {
     181      XVAL_ATIME, XVAL_BIRTHTIME, XVAL_CTIME, XVAL_MTIME, XVAL_TIME
     182    };
     183  
     184  struct time_val
     185  {
     186    enum xval            xval;
     187    enum comparison_type kind;
     188    struct timespec      ts;
     189  };
     190  
     191  
     192  struct exec_val
     193  {
     194    bool multiple;		/* -exec {} \+ denotes multiple argument. */
     195    struct buildcmd_control ctl;
     196    struct buildcmd_state   state;
     197    char **replace_vec;		/* Command arguments (for ";" style) */
     198    int num_args;
     199    bool close_stdin;		/* If true, close stdin in the child. */
     200    struct saved_cwd *wd_for_exec; /* What directory to perform the exec in. */
     201    int last_child_status;	/* Status of the most recent child. */
     202  };
     203  
     204  /* The format string for a -printf or -fprintf is chopped into one or
     205     more `struct segment', linked together into a list.
     206     Each stretch of plain text is a segment, and
     207     each \c and `%' conversion is a segment. */
     208  
     209  /* Special values for the `kind' field of `struct segment'. */
     210  enum SegmentKind
     211    {
     212      KIND_PLAIN=0,		/* Segment containing just plain text. */
     213      KIND_STOP=1,		/* \c -- stop printing and flush output. */
     214      KIND_FORMAT,		/* Regular format */
     215    };
     216  
     217  struct segment
     218  {
     219    enum SegmentKind segkind;     /* KIND_FORMAT, KIND_PLAIN, KIND_STOP */
     220    char format_char[2];		/* Format chars if kind is KIND_FORMAT */
     221    char *text;			/* Plain text or `%' format string. */
     222    int text_len;			/* Length of `text'. */
     223    struct segment *next;		/* Next segment for this predicate. */
     224  };
     225  
     226  struct format_val
     227  {
     228    struct segment *segment;	/* Linked list of segments. */
     229    FILE *stream;			/* Output stream to print on. */
     230    const char *filename;		/* We need the filename for error messages. */
     231    bool dest_is_tty;		/* True if the destination is a terminal. */
     232    struct quoting_options *quote_opts;
     233  };
     234  
     235  /* Profiling information for a predicate */
     236  struct predicate_performance_info
     237  {
     238    unsigned long visits;
     239    unsigned long successes;
     240  };
     241  
     242  /* evaluation cost of a predicate */
     243  enum EvaluationCost
     244  {
     245    NeedsNothing,
     246    NeedsInodeNumber,
     247    NeedsType,
     248    NeedsStatInfo,
     249    NeedsLinkName,
     250    NeedsAccessInfo,
     251    NeedsSyncDiskHit,
     252    NeedsEventualExec,
     253    NeedsImmediateExec,
     254    NeedsUserInteraction,
     255    NeedsUnknown,
     256    NumEvaluationCosts
     257  };
     258  
     259  struct predicate
     260  {
     261    /* Pointer to the function that implements this predicate.  */
     262    PRED_FUNC pred_func;
     263  
     264    /* Used for debugging */
     265    const char *p_name;
     266  
     267    /* The type of this node.  There are two kinds.  The first is real
     268       predicates ("primaries") such as -perm, -print, or -exec.  The
     269       other kind is operators for combining predicates. */
     270    enum predicate_type p_type;
     271  
     272    /* The precedence of this node.  Only has meaning for operators. */
     273    enum predicate_precedence p_prec;
     274  
     275    /* True if this predicate node produces side effects.
     276       If side_effects are produced
     277       then optimization will not be performed */
     278    bool side_effects;
     279  
     280    /* True if this predicate node requires default print be turned off. */
     281    bool no_default_print;
     282  
     283    /* True if this predicate node requires a stat system call to execute. */
     284    bool need_stat;
     285  
     286    /* True if this predicate node requires knowledge of the file type. */
     287    bool need_type;
     288  
     289    /* True if this predicate node requires knowledge of the inode number. */
     290    bool need_inum;
     291  
     292    enum EvaluationCost p_cost;
     293  
     294    /* est_success_rate is a number between 0.0 and 1.0 */
     295    float est_success_rate;
     296  
     297    /* True if this predicate should display control characters literally */
     298    bool literal_control_chars;
     299  
     300    /* True if this predicate didn't originate from the user. */
     301    bool artificial;
     302  
     303    /* The raw text of the argument of this predicate. */
     304    const char *arg_text;
     305  
     306    /* Information needed by the predicate processor.
     307       Next to each member are listed the predicates that use it. */
     308    union
     309    {
     310      const char *str;		/* fstype [i]lname [i]name [i]path */
     311      struct re_pattern_buffer *regex; /* regex */
     312      struct exec_val exec_vec;	/* exec ok */
     313      struct long_val numinfo;	/* gid inum links  uid */
     314      struct size_val size;	/* size */
     315      uid_t uid;			/* user */
     316      gid_t gid;			/* group */
     317      struct time_val reftime;	/* newer newerXY anewer cnewer mtime atime ctime mmin amin cmin */
     318      struct perm_val perm;	/* perm */
     319      struct samefile_file_id samefileid; /* samefile */
     320      bool types[FTYPE_COUNT];	/* file type(s) */
     321      struct format_val printf_vec; /* printf fprintf fprint ls fls print0 fprint0 print */
     322      char *scontext; /* security context */
     323    } args;
     324  
     325    /* The next predicate in the user input sequence,
     326       which represents the order in which the user supplied the
     327       predicates on the command line. */
     328    struct predicate *pred_next;
     329  
     330    /* The right and left branches from this node in the expression
     331       tree, which represents the order in which the nodes should be
     332       processed. */
     333    struct predicate *pred_left;
     334    struct predicate *pred_right;
     335  
     336    struct predicate_performance_info perf;
     337  
     338    const struct parser_table* parser_entry;
     339  };
     340  
     341  /* ftsfind.c */
     342  bool is_fts_enabled(int *ftsoptions);
     343  
     344  /* find library function declarations.  */
     345  
     346  /* find global function declarations.  */
     347  
     348  /* SymlinkOption represents the choice of
     349   * -P, -L or -P (default) on the command line.
     350   */
     351  enum SymlinkOption
     352    {
     353      SYMLINK_NEVER_DEREF,	/* Option -P */
     354      SYMLINK_ALWAYS_DEREF,	/* Option -L */
     355      SYMLINK_DEREF_ARGSONLY	/* Option -H */
     356    };
     357  
     358  void set_follow_state (enum SymlinkOption opt);
     359  void cleanup(void);
     360  
     361  /* fstype.c */
     362  char *filesystem_type (const struct stat *statp, const char *path);
     363  bool is_used_fs_type(const char *name);
     364  dev_t * get_mounted_devices (size_t *);
     365  
     366  
     367  
     368  enum arg_type
     369    {
     370      ARG_OPTION,			/* regular options like -maxdepth */
     371      ARG_NOOP,			/* does nothing, returns true, internal use only */
     372      ARG_POSITIONAL_OPTION,	/* options whose position is important (-follow) */
     373      ARG_TEST,			/* a like -name */
     374      ARG_SPECIAL_PARSE,		/* complex to parse, don't eat the test name before calling parse_xx(). */
     375      ARG_PUNCTUATION,		/* like -o or ( */
     376      ARG_ACTION			/* like -print */
     377    };
     378  
     379  
     380  struct parser_table;
     381  /* Pointer to a parser function. */
     382  typedef bool (*PARSE_FUNC)(const struct parser_table *p,
     383  			   char *argv[], int *arg_ptr);
     384  struct parser_table
     385  {
     386    enum arg_type type;
     387    const char *parser_name;
     388    PARSE_FUNC parser_func;
     389    PRED_FUNC    pred_func;
     390  };
     391  
     392  /* parser.c */
     393  const struct parser_table* find_parser (const char *search_name);
     394  bool parse_print (const struct parser_table*, char *argv[], int *arg_ptr);
     395  void pred_sanity_check (const struct predicate *predicates);
     396  void check_option_combinations (const struct predicate *p);
     397  void parse_begin_user_args (char **args, int argno, const struct predicate *last, const struct predicate *predicates);
     398  void parse_end_user_args (char **args, int argno, const struct predicate *last, const struct predicate *predicates);
     399  bool parse_openparen  (const struct parser_table* entry, char *argv[], int *arg_ptr);
     400  bool parse_closeparen (const struct parser_table* entry, char *argv[], int *arg_ptr);
     401  
     402  /* pred.c */
     403  
     404  typedef bool PREDICATEFUNCTION(const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr);
     405  
     406  PREDICATEFUNCTION pred_amin;
     407  PREDICATEFUNCTION pred_and;
     408  PREDICATEFUNCTION pred_anewer;
     409  PREDICATEFUNCTION pred_atime;
     410  PREDICATEFUNCTION pred_closeparen;
     411  PREDICATEFUNCTION pred_cmin;
     412  PREDICATEFUNCTION pred_cnewer;
     413  PREDICATEFUNCTION pred_comma;
     414  PREDICATEFUNCTION pred_ctime;
     415  PREDICATEFUNCTION pred_delete;
     416  PREDICATEFUNCTION pred_empty;
     417  PREDICATEFUNCTION pred_exec;
     418  PREDICATEFUNCTION pred_execdir;
     419  PREDICATEFUNCTION pred_executable;
     420  PREDICATEFUNCTION pred_false;
     421  PREDICATEFUNCTION pred_fls;
     422  PREDICATEFUNCTION pred_fprint;
     423  PREDICATEFUNCTION pred_fprint0;
     424  PREDICATEFUNCTION pred_fprintf;
     425  PREDICATEFUNCTION pred_fstype;
     426  PREDICATEFUNCTION pred_gid;
     427  PREDICATEFUNCTION pred_group;
     428  PREDICATEFUNCTION pred_ilname;
     429  PREDICATEFUNCTION pred_iname;
     430  PREDICATEFUNCTION pred_inum;
     431  PREDICATEFUNCTION pred_ipath;
     432  PREDICATEFUNCTION pred_links;
     433  PREDICATEFUNCTION pred_lname;
     434  PREDICATEFUNCTION pred_ls;
     435  PREDICATEFUNCTION pred_mmin;
     436  PREDICATEFUNCTION pred_mtime;
     437  PREDICATEFUNCTION pred_name;
     438  PREDICATEFUNCTION pred_negate;
     439  PREDICATEFUNCTION pred_newer;
     440  PREDICATEFUNCTION pred_newerXY;
     441  PREDICATEFUNCTION pred_nogroup;
     442  PREDICATEFUNCTION pred_nouser;
     443  PREDICATEFUNCTION pred_ok;
     444  PREDICATEFUNCTION pred_okdir;
     445  PREDICATEFUNCTION pred_openparen;
     446  PREDICATEFUNCTION pred_or;
     447  PREDICATEFUNCTION pred_path;
     448  PREDICATEFUNCTION pred_perm;
     449  PREDICATEFUNCTION pred_print;
     450  PREDICATEFUNCTION pred_print0;
     451  PREDICATEFUNCTION pred_prune;
     452  PREDICATEFUNCTION pred_readable;
     453  PREDICATEFUNCTION pred_regex;
     454  PREDICATEFUNCTION pred_samefile;
     455  PREDICATEFUNCTION pred_size;
     456  PREDICATEFUNCTION pred_true;
     457  PREDICATEFUNCTION pred_type;
     458  PREDICATEFUNCTION pred_uid;
     459  PREDICATEFUNCTION pred_used;
     460  PREDICATEFUNCTION pred_user;
     461  PREDICATEFUNCTION pred_writable;
     462  PREDICATEFUNCTION pred_xtype;
     463  PREDICATEFUNCTION pred_context;
     464  
     465  bool pred_quit (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
     466    _GL_ATTRIBUTE_NORETURN;
     467  
     468  
     469  
     470  char *find_pred_name (PRED_FUNC pred_func);
     471  
     472  
     473  void print_predicate (FILE *fp, const struct predicate *p);
     474  void print_tree (FILE*, struct predicate *node, int indent);
     475  void print_list (FILE*, struct predicate *node);
     476  void print_optlist (FILE *fp, const struct predicate *node);
     477  void show_success_rates(const struct predicate *node);
     478  
     479  
     480  /* tree.c */
     481  bool matches_start_point(const char * glob, bool foldcase);
     482  struct predicate * build_expression_tree (int argc, char *argv[], int end_of_leading_options);
     483  struct predicate * get_eval_tree (void);
     484  struct predicate *get_new_pred_noarg (const struct parser_table *entry);
     485  struct predicate *get_new_pred (const struct parser_table *entry);
     486  struct predicate *get_new_pred_chk_op (const struct parser_table *entry,
     487  					      const char *arg);
     488  float  calculate_derived_rates (struct predicate *p);
     489  
     490  /* util.c */
     491  struct predicate *insert_primary (const struct parser_table *entry, const char *arg);
     492  struct predicate *insert_primary_noarg (const struct parser_table *entry);
     493  struct predicate *insert_primary_withpred (const struct parser_table *entry, PRED_FUNC fptr, const char *arg);
     494  void usage (int status) _GL_ATTRIBUTE_NORETURN;
     495  extern bool check_nofollow(void);
     496  void complete_pending_execs(struct predicate *p);
     497  void complete_pending_execdirs (void);
     498  const char *safely_quote_err_filename (int n, char const *arg);
     499  void record_initial_cwd (void);
     500  bool is_exec_in_local_dir(const PRED_FUNC pred_func);
     501  
     502  void fatal_target_file_error (int errno_value, const char *name) _GL_ATTRIBUTE_NORETURN;
     503  void fatal_nontarget_file_error (int errno_value, const char *name) _GL_ATTRIBUTE_NORETURN;
     504  void nonfatal_target_file_error (int errno_value, const char *name);
     505  void nonfatal_nontarget_file_error (int errno_value, const char *name);
     506  
     507  
     508  int process_leading_options (int argc, char *argv[]);
     509  void set_option_defaults (struct options *p);
     510  
     511  # if 0
     512  #  define apply_predicate(pathname, stat_buf_ptr, node)	\
     513    (*(node)->pred_func)((pathname), (stat_buf_ptr), (node))
     514  # else
     515  bool apply_predicate(const char *pathname, struct stat *stat_buf, struct predicate *p);
     516  # endif
     517  
     518  # define pred_is(node, fn) ( ((node)->pred_func) == (fn) )
     519  
     520  
     521  /* util.c. */
     522  bool following_links (void);
     523  bool digest_mode (mode_t *mode, const char *pathname, const char *name, struct stat *pstat, bool leaf);
     524  bool default_prints (struct predicate *pred);
     525  bool looks_like_expression (const char *arg, bool leading);
     526  
     527  
     528  enum DebugOption
     529    {
     530      DebugNone             = 0,
     531      DebugExpressionTree   = 1 << 0,
     532      DebugStat             = 1 << 1,
     533      DebugSearch           = 1 << 2,
     534      DebugTreeOpt          = 1 << 3,
     535      DebugHelp             = 1 << 4,
     536      DebugExec             = 1 << 5,
     537      DebugSuccessRates     = 1 << 6,
     538      DebugTime             = 1 << 7,
     539  
     540      DebugAll              = ~DebugNone & ~DebugHelp, /* all but help */
     541    };
     542  
     543  struct options
     544  {
     545    /* If true, process directory before contents.  True unless -depth given. */
     546    bool do_dir_first;
     547    /* If true, -depth was EXPLICITLY set (as opposed to having been turned
     548     * on by -delete, for example).
     549     */
     550     bool explicit_depth;
     551  
     552    /* If >=0, don't descend more than this many levels of subdirectories. */
     553    int maxdepth;
     554  
     555    /* If >=0, don't process files above this level. */
     556    int mindepth;
     557  
     558    /* If true, do not assume that files in directories with nlink == 2
     559       are non-directories. */
     560    bool no_leaf_check;
     561  
     562    /* If true, don't cross filesystem boundaries. */
     563    bool stay_on_filesystem;
     564  
     565    /* If true, we ignore the problem where we find that a directory entry
     566     * no longer exists by the time we get around to processing it.
     567     */
     568    bool ignore_readdir_race;
     569  
     570    /* If true, pass control characters through.  If false, escape them
     571     * or turn them into harmless things.
     572     */
     573    bool literal_control_chars;
     574  
     575    /* If true, we issue warning messages
     576     */
     577    bool warnings;
     578  
     579    /* If true, avoid POSIX-incompatible behaviours
     580     * (this functionality is currently incomplete
     581     * and at the moment affects mainly warning messages).
     582     */
     583    bool posixly_correct;
     584  
     585    struct timespec      start_time;		/* Time at start of execution.  */
     586  
     587    /* Either one day before now (the default), or the start of today (if -daystart is given). */
     588    struct timespec      cur_day_start;
     589  
     590    /* If true, cur_day_start has been adjusted to the start of the day. */
     591    bool full_days;
     592  
     593    int output_block_size;	/* Output block size.  */
     594  
     595    /* bitmask for debug options */
     596    unsigned long debug_options;
     597  
     598    enum SymlinkOption symlink_handling;
     599  
     600  
     601    /* Pointer to the function used to stat files. */
     602    int (*xstat) (const char *name, struct stat *statbuf);
     603  
     604  
     605    /* Indicate if we can implement safely_chdir() using the O_NOFOLLOW
     606     * flag to open(2).
     607     */
     608    bool open_nofollow_available;
     609  
     610    /* The variety of regular expression that we support.
     611     * The default is POSIX Basic Regular Expressions, but this
     612     * can be changed with the positional option, -regextype.
     613     */
     614    int regex_options;
     615  
     616    /* function used to get file context */
     617    int (*x_getfilecon) (int, const char *, char **);
     618  
     619    /* Optimisation level.  One is the default.
     620     */
     621    unsigned short optimisation_level;
     622  
     623  
     624    /* How should we quote filenames in error messages and so forth?
     625     */
     626    enum quoting_style err_quoting_style;
     627  
     628    /* Read starting points from FILE (instead of argv).  */
     629    const char *files0_from;
     630  
     631    /* True if actions like -ok, -okdir need a user confirmation via stdin.  */
     632    bool ok_prompt_stdin;
     633  };
     634  
     635  
     636  struct state
     637  {
     638    /* Current depth; 0 means current path is a command line arg. */
     639    int curdepth;
     640  
     641    /* If true, we have called stat on the current path. */
     642    bool have_stat;
     643  
     644    /* If true, we know the type of the current path. */
     645    bool have_type;
     646    mode_t type;			/* this is the actual type */
     647  
     648    /* The file being operated on, relative to the current directory.
     649       Used for stat, readlink, remove, and opendir.  */
     650    const char *rel_pathname;
     651  
     652    /* The directory fd to which rel_pathname is relative.  This is relevant
     653     * when we're navigating the hierarchy with fts() and using FTS_CWDFD.
     654     */
     655    int cwd_dir_fd;
     656  
     657    /* Length of starting path. */
     658    int starting_path_length;
     659  
     660    /* If true, don't descend past current directory.
     661       Can be set by -prune, -maxdepth, and -xdev/-mount. */
     662    bool stop_at_current_level;
     663  
     664    /* Status value to return to system. */
     665    int exit_status;
     666  
     667    /* True if there are any execdirs.  This saves us a pair of fchdir()
     668     * calls for every directory we leave if it is false.  This is just
     669     * an optimisation.  Set to true if you want to be conservative.
     670     */
     671    bool execdirs_outstanding;
     672  
     673    /* Shared files, opened via the interface in sharefile.h. */
     674    sharefile_handle shared_files;
     675  
     676    /* Avoid multiple error messages for the same file. */
     677    bool already_issued_stat_error_msg;
     678  };
     679  
     680  /* exec.c */
     681  bool impl_pred_exec (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr);
     682  int launch (struct buildcmd_control *ctl, void *usercontext, int argc, char **argv);
     683  
     684  /* finddata.c */
     685  extern struct options options;
     686  extern struct state state;
     687  extern struct saved_cwd *initial_wd;
     688  
     689  #endif