/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * bsd/bsd.h: Interface definitions to BSD compatibility functions for SVR4. */ #ifndef _BSD_BSD_H #define _BSD_BSD_H #include #ifndef __cplusplus typedef void (*SIG_PF) (int); #endif #ifdef __cplusplus extern "C" SIG_PF bsd_signal(int a, SIG_PF b); #else extern void (*bsd_signal(int, void (*) (int))) (int); #endif extern void bsd_signals(void); #endif /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * Copyright 2019, Joyent, Inc. * Copyright 2019 RackTop Systems. */ #ifndef _MK_DEFS_H #define _MK_DEFS_H /* * Included files */ #include /* * Defined macros */ #define SKIPSPACE(x) while (*x && \ ((*x == (int)space_char) || \ (*x == (int)tab_char) || \ (*x == (int)comma_char))) { \ x++; \ } #define SKIPWORD(x) while (*x && \ (*x != (int)space_char) && \ (*x != (int)tab_char) && \ (*x != (int)newline_char) && \ (*x != (int)comma_char) && \ (*x != (int)equal_char)) { \ x++; \ } #define SKIPTOEND(x) while (*x && \ (*x != (int)newline_char)) { \ x++; \ } #define PMAKE_DEF_MAX_JOBS 2 /* Default number of parallel jobs. */ #define OUT_OF_DATE(a, b) \ (((a) < (b)) || (((a) == file_doesnt_exist) && \ ((b) == file_doesnt_exist))) #define OUT_OF_DATE_SEC(a, b) \ (((a).tv_sec < (b).tv_sec) || \ (((a).tv_sec == file_doesnt_exist.tv_sec) && \ ((b).tv_sec == file_doesnt_exist.tv_sec))) #define SETVAR(name, value, append) \ setvar_daemon(name, value, append, no_daemon, \ true, debug_level) #define MAX(a, b) (((a) > (b))?(a):(b)) /* * New feature added to SUN5_0 make, invoke the vanilla svr4 make when * the USE_SVR4_MAKE environment variable is set. */ #define SVR4_MAKE "/usr/ccs/lib/svr4.make" #define USE_SVR4_MAKE "USE_SVR4_MAKE" /* * The standard MAXHOSTNAMELEN is 64. We want 32. */ #define MAX_HOSTNAMELEN 32 /* * typedefs & structs */ typedef enum { no_state, scan_name_state, scan_command_state, enter_dependencies_state, enter_conditional_state, enter_equal_state, illegal_bytes_state, illegal_eoln_state, poorly_formed_macro_state, exit_state } Reader_state; struct _Name_vector { struct _Name *names[64]; struct _Chain *target_group[64]; short used; struct _Name_vector *next; }; struct _Running { struct _Running *next; Doname state; struct _Name *target; struct _Name *true_target; struct _Property *command; struct _Name *sprodep_value; char *sprodep_env; int recursion_level; Boolean do_get; Boolean implicit; Boolean redo; int auto_count; struct _Name **automatics; pid_t pid; int job_msg_id; char *stdout_file; char *stderr_file; struct _Name *temp_file; int conditional_cnt; struct _Name **conditional_targets; Boolean make_refd; }; typedef enum { serial_mode, parallel_mode } DMake_mode; typedef enum { txt1_mode, txt2_mode, html1_mode } DMake_output_mode; struct _Recursive_make { struct _Recursive_make *next; /* Linked list */ wchar_t *target; /* Name of target */ wchar_t *oldline; /* Original line in .nse_depinfo */ wchar_t *newline; /* New line in .nse_depinfo */ /* * string built from value of * conditional macros used by * this target */ wchar_t *cond_macrostring; /* This target is no longer recursive */ Boolean removed; }; struct _Dyntarget { struct _Dyntarget *next; struct _Name *name; }; /* * Typedefs for all structs */ typedef struct _Cmd_line *Cmd_line, Cmd_line_rec; typedef struct _Dependency *Dependency, Dependency_rec; typedef struct _Macro *Macro, Macro_rec; typedef struct _Name_vector *Name_vector, Name_vector_rec; typedef struct _Percent *Percent, Percent_rec; typedef struct _Dyntarget *Dyntarget; typedef struct _Recursive_make *Recursive_make, Recursive_make_rec; typedef struct _Running *Running, Running_rec; /* * extern declarations for all global variables. * The actual declarations are in globals.cc */ extern Boolean allrules_read; extern Name posix_name; extern Name svr4_name; extern Boolean sdot_target; extern Boolean all_parallel; extern Boolean assign_done; extern Boolean build_failed_seen; extern Name built_last_make_run; extern Name c_at; extern Boolean command_changed; extern Boolean commands_done; extern Chain conditional_targets; extern Name conditionals; extern Boolean continue_after_error; extern Property current_line; extern Name current_make_version; extern Name current_target; extern short debug_level; extern Cmd_line default_rule; extern Name default_rule_name; extern Name default_target_to_build; extern Boolean depinfo_already_read; extern Name dmake_group; extern Name dmake_max_jobs; extern Name dmake_mode; extern DMake_mode dmake_mode_type; extern Name dmake_output_mode; extern DMake_output_mode output_mode; extern Name dmake_odir; extern Name dmake_rcfile; extern Name done; extern Name dot; extern Name dot_keep_state; extern Name dot_keep_state_file; extern Name empty_name; extern Boolean fatal_in_progress; extern int file_number; extern Name force; extern Name ignore_name; extern Boolean ignore_errors; extern Boolean ignore_errors_all; extern Name init; extern int job_msg_id; extern Boolean keep_state; extern Name make_state; extern timestruc_t make_state_before; extern Boolean make_state_locked; extern Dependency makefiles_used; extern Name makeflags; extern Name make_version; extern char mbs_buffer2[]; extern char *mbs_ptr; extern char *mbs_ptr2; extern Boolean no_action_was_taken; extern Boolean no_parallel; extern Name no_parallel_name; extern Name not_auto; extern Boolean only_parallel; extern Boolean parallel; extern Name parallel_name; extern Name localhost_name; extern int parallel_process_cnt; extern Percent percent_list; extern Dyntarget dyntarget_list; extern Name plus; extern Name pmake_machinesfile; extern Name precious; extern Name primary_makefile; extern Boolean quest; extern short read_trace_level; extern Boolean reading_dependencies; extern int recursion_level; extern Name recursive_name; extern short report_dependencies_level; extern Boolean report_pwd; extern Boolean rewrite_statefile; extern Running running_list; extern char *sccs_dir_path; extern Name sccs_get_name; extern Name sccs_get_posix_name; extern Cmd_line sccs_get_rule; extern Cmd_line sccs_get_org_rule; extern Cmd_line sccs_get_posix_rule; extern Name get_name; extern Name get_posix_name; extern Cmd_line get_rule; extern Cmd_line get_posix_rule; extern Boolean all_precious; extern Boolean report_cwd; extern Boolean silent_all; extern Boolean silent; extern Name silent_name; extern char *stderr_file; extern char *stdout_file; extern Boolean stdout_stderr_same; extern Dependency suffixes; extern Name suffixes_name; extern Name sunpro_dependencies; extern Boolean target_variants; extern const char *tmpdir; extern const char *temp_file_directory; extern Name temp_file_name; extern short temp_file_number; extern wchar_t *top_level_target; extern Boolean touch; extern Boolean trace_reader; extern Boolean build_unconditional; extern pathpt vroot_path; extern Name wait_name; extern wchar_t wcs_buffer2[]; extern wchar_t *wcs_ptr; extern wchar_t *wcs_ptr2; extern long int hostid; extern Boolean path_reset; extern Boolean rebuild_arg0; /* * Declarations of system defined variables */ /* On linux this variable is defined in 'signal.h' */ extern char *sys_siglist[]; /* * Declarations of system supplied functions */ extern int file_lock(char *, char *, int *, int); /* * Declarations of functions declared and used by make */ extern void add_pending(Name target, int recursion_level, Boolean do_get, Boolean implicit, Boolean redo); extern void add_running(Name target, Name true_target, Property command, int recursion_level, int auto_count, Name *automatics, Boolean do_get, Boolean implicit); extern void add_serial(Name target, int recursion_level, Boolean do_get, Boolean implicit); extern void add_subtree(Name target, int recursion_level, Boolean do_get, Boolean implicit); extern void append_or_replace_macro_in_dyn_array( ASCII_Dyn_Array *Ar, char *macro); extern void await_parallel(Boolean waitflg); extern void build_suffix_list(Name target_suffix); extern Boolean check_auto_dependencies(Name target, int auto_count, Name *automatics); extern void check_state(Name temp_file_name); extern void cond_macros_into_string(Name np, String_rec *buffer); extern void construct_target_string(); extern void create_xdrs_ptr(void); extern void depvar_add_to_list(Name name, Boolean cmdline); extern Doname doname(Name target, Boolean do_get, Boolean implicit, Boolean automatic = false); extern Doname doname_check(Name target, Boolean do_get, Boolean implicit, Boolean automatic); extern Doname doname_parallel(Name target, Boolean do_get, Boolean implicit); extern Doname dosys(Name command, Boolean ignore_error, Boolean call_make, Boolean silent_error, Boolean always_exec, Name target); extern void dump_make_state(void); extern void dump_target_list(void); extern void enter_conditional(Name target, Name name, Name value, Boolean append); extern void enter_dependencies(Name target, Chain target_group, Name_vector depes, Cmd_line command, Separator separator); extern void enter_dependency(Property line, Name depe, Boolean automatic); extern void enter_equal(Name name, Name value, Boolean append); extern Percent enter_percent(Name target, Chain target_group, Name_vector depes, Cmd_line command); extern Dyntarget enter_dyntarget(Name target); extern Name_vector enter_name(String string, Boolean tail_present, wchar_t *string_start, wchar_t *string_end, Name_vector current_names, Name_vector *extra_names, Boolean *target_group_seen); extern Boolean exec_vp(char *name, char **argv, char **envp, Boolean ignore_error); extern Doname execute_parallel(Property line, Boolean waitflg, Boolean local = false); extern Doname execute_serial(Property line); extern timestruc_t& exists(Name target); extern void fatal(const char *, ...) __NORETURN; extern void fatal_reader(char *, ...) __NORETURN; extern Doname find_ar_suffix_rule(Name target, Name true_target, Property *command, Boolean rechecking); extern Doname find_double_suffix_rule(Name target, Property *command, Boolean rechecking); extern Doname find_percent_rule(Name target, Property *command, Boolean rechecking); extern int find_run_directory(char *cmd, char *cwd, char *dir, char **pgm, char **run, char *path); extern Doname find_suffix_rule(Name target, Name target_body, Name target_suffix, Property *command, Boolean rechecking); extern Chain find_target_groups(Name_vector target_list, int i, Boolean reset); extern void finish_children(Boolean docheck); extern void finish_running(void); extern void free_chain(Name_vector ptr); extern void gather_recursive_deps(void); extern char *get_current_path(void); extern int get_job_msg_id(void); extern wchar_t *getmem_wc(int size); extern void handle_interrupt(int); extern Boolean is_running(Name target); extern void load_cached_names(void); extern Boolean parallel_ok(Name target, Boolean line_prop_must_exists); extern void print_dependencies(Name target, Property line); extern void send_job_start_msg(Property line); extern void send_rsrc_info_msg(int max_jobs, char *hostname, char *username); extern void print_value(Name value, Daemon daemon); extern timestruc_t& read_archive(Name target); extern int read_dir(Name dir, wchar_t *pattern, Property line, wchar_t *library); extern void read_directory_of_file(Name file); extern int read_make_machines(Name make_machines_name); extern Boolean read_simple_file(Name makefile_name, Boolean chase_path, Boolean doname_it, Boolean complain, Boolean must_exist, Boolean report_file, Boolean lock_makefile); extern void remove_recursive_dep(Name target); extern void report_recursive_dep(Name target, char *line); extern void report_recursive_done(void); extern void report_recursive_init(void); extern Recursive_make find_recursive_target(Name target); extern void reset_locals(Name target, Property old_locals, Property conditional, int index); extern void set_locals(Name target, Property old_locals); extern void setvar_append(Name name, Name value); extern void setvar_envvar(void); extern void special_reader(Name target, Name_vector depes, Cmd_line command); extern void startup_rxm(); extern Doname target_can_be_built(Name target); extern char *time_to_string(const timestruc_t &time); extern void update_target(Property line, Doname result); extern void warning(char *, ...); extern void write_state_file(int report_recursive, Boolean exiting); extern Name vpath_translation(Name cmd); extern char *make_install_prefix(void); #define DEPINFO_FMT_VERSION "VERS2$" #define VER_LEN strlen(DEPINFO_FMT_VERSION) #endif /* _MK_DEFS_H */ #ifndef _MKSH_DEFS_H #define _MKSH_DEFS_H /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include /* MB_LEN_MAX */ #include #include /* wchar_t */ #include /* strcmp() */ #include /* MAXPATHLEN */ #include /* time_t, caddr_t */ #include /* pathpt */ #include /* timestruc_t */ #include /* errno */ #include /* * A type and some utilities for boolean values */ #define false BOOLEAN_false #define true BOOLEAN_true typedef enum { false = 0, true = 1, failed = 0, succeeded = 1 } Boolean; #define BOOLEAN(expr) ((expr) ? true : false) /* * Some random constants (in an enum so dbx knows their values) */ enum { update_delay = 30, /* time between rstat checks */ ar_member_name_len = 1024, hashsize = 2048 /* size of hash table */ }; /* * Symbols that defines all the different char constants make uses */ enum { ampersand_char = '&', asterisk_char = '*', at_char = '@', backquote_char = '`', backslash_char = '\\', bar_char = '|', braceleft_char = '{', braceright_char = '}', bracketleft_char = '[', bracketright_char = ']', colon_char = ':', comma_char = ',', dollar_char = '$', doublequote_char = '"', equal_char = '=', exclam_char = '!', greater_char = '>', hat_char = '^', hyphen_char = '-', less_char = '<', newline_char = '\n', nul_char = '\0', numbersign_char = '#', parenleft_char = '(', parenright_char = ')', percent_char = '%', period_char = '.', plus_char = '+', question_char = '?', quote_char = '\'', semicolon_char = ';', slash_char = '/', space_char = ' ', tab_char = '\t', tilde_char = '~' }; /* * For make i18n. Codeset independent. * Setup character semantics by identifying all the special characters * of make, and assigning each an entry in the char_semantics[] vector. */ enum { ampersand_char_entry = 0, /* 0 */ asterisk_char_entry, /* 1 */ at_char_entry, /* 2 */ backquote_char_entry, /* 3 */ backslash_char_entry, /* 4 */ bar_char_entry, /* 5 */ bracketleft_char_entry, /* 6 */ bracketright_char_entry, /* 7 */ colon_char_entry, /* 8 */ dollar_char_entry, /* 9 */ doublequote_char_entry, /* 10 */ equal_char_entry, /* 11 */ exclam_char_entry, /* 12 */ greater_char_entry, /* 13 */ hat_char_entry, /* 14 */ hyphen_char_entry, /* 15 */ less_char_entry, /* 16 */ newline_char_entry, /* 17 */ numbersign_char_entry, /* 18 */ parenleft_char_entry, /* 19 */ parenright_char_entry, /* 20 */ percent_char_entry, /* 21 */ plus_char_entry, /* 22 */ question_char_entry, /* 23 */ quote_char_entry, /* 24 */ semicolon_char_entry, /* 25 */ no_semantics_entry /* 26 */ }; /* * CHAR_SEMANTICS_ENTRIES should be the number of entries above. * The last entry in char_semantics[] should be blank. */ #define CHAR_SEMANTICS_ENTRIES 27 /* #define CHAR_SEMANTICS_STRING "&*@`\\|[]:$=!>-\n#()%+?;^<'\"" */ /* * Some utility macros */ #define ALLOC(x) ((struct _##x *)getmem(sizeof (struct _##x))) #define ALLOC_WC(x) ((wchar_t *)getmem((x) * SIZEOFWCHAR_T)) #define FIND_LENGTH -1 #define GETNAME(a,b) getname_fn((a), (b), false) #define IS_EQUAL(a,b) (!strcmp((a), (b))) #define IS_EQUALN(a,b,n) (!strncmp((a), (b), (n))) #define IS_WEQUAL(a,b) (!wcscmp((a), (b))) #define IS_WEQUALN(a,b,n) (!wcsncmp((a), (b), (n))) #define MBLEN(a) mblen((a), MB_LEN_MAX) #define MBSTOWCS(a,b) (void) mbstowcs_with_check((a), (b), MAXPATHLEN) #define MBTOWC(a,b) mbtowc((a), (b), MB_LEN_MAX) #define SIZEOFWCHAR_T (sizeof (wchar_t)) #define VSIZEOF(v) (sizeof (v) / sizeof ((v)[0])) #define WCSTOMBS(a,b) (void) wcstombs((a), (b), (MAXPATHLEN * MB_LEN_MAX)) #define WCTOMB(a,b) (void) wctomb((a), (b)) #define HASH(v, c) (v = (v)*31 + (unsigned int)(c)) extern void mbstowcs_with_check(wchar_t *pwcs, const char *s, size_t n); /* * Bits stored in funny vector to classify chars */ enum { dollar_sem = 0001, meta_sem = 0002, percent_sem = 0004, wildcard_sem = 0010, command_prefix_sem = 0020, special_macro_sem = 0040, colon_sem = 0100, parenleft_sem = 0200 }; /* * Type returned from doname class functions */ typedef enum { build_dont_know = 0, build_failed, build_ok, build_in_progress, build_running, /* PARALLEL & DISTRIBUTED */ build_pending, /* PARALLEL & DISTRIBUTED */ build_serial, /* PARALLEL & DISTRIBUTED */ build_subtree /* PARALLEL & DISTRIBUTED */ } Doname; /* * The String struct defines a string with the following layout * "xxxxxxxxxxxxxxxCxxxxxxxxxxxxxxx________" * ^ ^ ^ ^ * | | | | * buffer.start text.p text.end buffer.end * text.p points to the next char to read/write. */ struct _String { struct Text { wchar_t *p; /* Read/Write pointer */ wchar_t *end; /* Read limit pointer */ } text; struct Physical_buffer { wchar_t *start; /* Points to start of buffer */ wchar_t *end; /* End of physical buffer */ } buffer; Boolean free_after_use:1; }; #define STRING_BUFFER_LENGTH 1024 #define INIT_STRING_FROM_STACK(str, buf) { \ str.buffer.start = (buf); \ str.text.p = (buf); \ str.text.end = NULL; \ str.buffer.end = (buf) \ + (sizeof (buf)/SIZEOFWCHAR_T); \ str.free_after_use = false; \ } #define APPEND_NAME(np, dest, len) append_string((np)->string_mb, (dest), (len)); class Wstring { public: struct _String string; wchar_t string_buf[STRING_BUFFER_LENGTH]; public: Wstring(); Wstring(struct _Name * name); ~Wstring(); void init(struct _Name * name); void init(wchar_t * name, unsigned length); unsigned length() { return wcslen(string.buffer.start); }; void append_to_str(struct _String * str, unsigned off, unsigned length); wchar_t * get_string() { return string.buffer.start; }; wchar_t * get_string(unsigned off) { return string.buffer.start + off; }; Boolean equaln(wchar_t * str, unsigned length); Boolean equal(wchar_t * str); Boolean equal(wchar_t * str, unsigned off); Boolean equal(wchar_t * str, unsigned off, unsigned length); Boolean equaln(Wstring * str, unsigned length); Boolean equal(Wstring * str); Boolean equal(Wstring * str, unsigned off); Boolean equal(Wstring * str, unsigned off, unsigned length); }; /* * Used for storing the $? list and also for the "target + target:" * construct. */ struct _Chain { struct _Chain *next; struct _Name *name; struct _Percent *percent_member; }; /* * Stores one command line for a rule */ struct _Cmd_line { struct _Cmd_line *next; struct _Name *command_line; Boolean make_refd:1; /* $(MAKE) referenced? */ /* * Remember any command line prefixes given */ Boolean ignore_command_dependency:1; /* `?' */ Boolean assign:1; /* `=' */ Boolean ignore_error:1; /* `-' */ Boolean silent:1; /* `@' */ Boolean always_exec:1; /* `+' */ }; /* * Linked list of targets/files */ struct _Dependency { struct _Dependency *next; struct _Name *name; Boolean automatic:1; Boolean stale:1; Boolean built:1; }; /* * The specials are markers for targets that the reader should special case */ typedef enum { no_special, built_last_make_run_special, default_special, get_posix_special, get_special, ignore_special, keep_state_file_special, keep_state_special, make_version_special, no_parallel_special, parallel_special, posix_special, precious_special, sccs_get_posix_special, sccs_get_special, silent_special, suffixes_special, svr4_special, localhost_special } Special; typedef enum { no_colon, one_colon, two_colon, equal_seen, conditional_seen, none_seen } Separator; /* * Magic values for the timestamp stored with each name object */ extern const timestruc_t file_no_time; extern const timestruc_t file_doesnt_exist; extern const timestruc_t file_is_dir; extern const timestruc_t file_min_time; extern const timestruc_t file_max_time; /* * Each Name has a list of properties * The properties are used to store information that only * a subset of the Names need */ typedef enum { no_prop, conditional_prop, line_prop, macro_prop, makefile_prop, member_prop, recursive_prop, sccs_prop, suffix_prop, target_prop, time_prop, vpath_alias_prop, long_member_name_prop, macro_append_prop, env_mem_prop } Property_id; typedef enum { no_daemon = 0, chain_daemon } Daemon; struct _Env_mem { char *value; }; struct _Macro_appendix { struct _Name *value; struct _Name *value_to_append; }; struct _Macro { /* * For "ABC = xyz" constructs * Name "ABC" get one macro prop */ struct _Name *value; Boolean exported:1; Boolean read_only:1; /* * This macro is defined conditionally */ Boolean is_conditional:1; /* * The list for $? is stored as a structured list that * is translated into a string iff it is referenced. * This is why some macro values need a daemon. */ Daemon daemon:2; }; struct _Macro_list { struct _Macro_list *next; char *macro_name; char *value; }; enum sccs_stat { DONT_KNOW_SCCS = 0, NO_SCCS, HAS_SCCS }; struct _Name { struct _Property *prop; /* List of properties */ char *string_mb; /* Multi-byte name string */ struct { unsigned int length; } hash; struct { timestruc_t time; /* Modification */ int stat_errno; /* error from "stat" */ off_t size; /* Of file */ mode_t mode; /* Of file */ Boolean is_file:1; Boolean is_dir:1; Boolean is_sym_link:1; Boolean is_precious:1; enum sccs_stat has_sccs:2; } stat; /* * Count instances of :: definitions for this target */ short colon_splits; /* * We only clear the automatic depes once per target per report */ short temp_file_number; /* * Count how many conditional macros this target has defined */ short conditional_cnt; /* * A conditional macro was used when building this target */ Boolean depends_on_conditional:1; /* * Pointer to list of conditional macros which were used to build * this target */ struct _Macro_list *conditional_macro_list; Boolean has_member_depe:1; Boolean is_member:1; /* * This target is a directory that has been read */ Boolean has_read_dir:1; /* * This name is a macro that is now being expanded */ Boolean being_expanded:1; /* * This name is a magic name that the reader must know about */ Special special_reader:5; Doname state:3; Separator colons:3; Boolean has_depe_list_expanded:1; Boolean suffix_scan_done:1; Boolean has_complained:1; /* For sccs */ /* * This target has been built during this make run */ Boolean ran_command:1; Boolean with_squiggle:1; /* for .SUFFIXES */ Boolean without_squiggle:1; /* for .SUFFIXES */ Boolean has_read_suffixes:1; /* Suffix list cached*/ Boolean has_suffixes:1; Boolean has_target_prop:1; Boolean has_vpath_alias_prop:1; Boolean dependency_printed:1; /* For dump_make_state() */ Boolean dollar:1; /* In namestring */ Boolean meta:1; /* In namestring */ Boolean percent:1; /* In namestring */ Boolean wildcard:1; /* In namestring */ Boolean has_parent:1; Boolean is_target:1; Boolean has_built:1; Boolean colon:1; /* In namestring */ Boolean parenleft:1; /* In namestring */ Boolean has_recursive_dependency:1; Boolean has_regular_dependency:1; Boolean is_double_colon:1; Boolean is_double_colon_parent:1; Boolean has_long_member_name:1; /* * allowed to run in parallel */ Boolean parallel:1; /* * not allowed to run in parallel */ Boolean no_parallel:1; /* * used in dependency_conflict */ Boolean checking_subtree:1; Boolean added_pattern_conditionals:1; /* * rechecking target for possible rebuild */ Boolean rechecking_target:1; /* * build this target in silent mode */ Boolean silent_mode:1; /* * build this target in ignore error mode */ Boolean ignore_error_mode:1; Boolean dont_activate_cond_values:1; /* * allowed to run serially on local host */ Boolean localhost:1; }; /* * Stores the % matched default rules */ struct _Percent { struct _Percent *next; struct _Name **patterns; struct _Name *name; struct _Percent *dependencies; struct _Cmd_line *command_template; struct _Chain *target_group; int patterns_total; Boolean being_expanded; }; struct Conditional { /* * For "foo := ABC [+]= xyz" constructs * Name "foo" gets one conditional prop */ struct _Name *target; struct _Name *name; struct _Name *value; int sequence; Boolean append:1; }; struct Line { /* * For "target : dependencies" constructs * Name "target" gets one line prop */ struct _Cmd_line *command_template; struct _Cmd_line *command_used; struct _Dependency *dependencies; timestruc_t dependency_time; struct _Chain *target_group; Boolean is_out_of_date:1; Boolean sccs_command:1; Boolean command_template_redefined:1; Boolean dont_rebuild_command_used:1; /* * Values for the dynamic macros */ struct _Name *target; struct _Name *star; struct _Name *less; struct _Name *percent; struct _Chain *query; }; struct Makefile { /* * Names that reference makefiles gets one prop */ wchar_t *contents; off_t size; }; struct Member { /* * For "lib(member)" and "lib((entry))" constructs * Name "lib(member)" gets one member prop * Name "lib((entry))" gets one member prop * The member field is filled in when the prop is refd */ struct _Name *library; struct _Name *entry; struct _Name *member; }; struct Recursive { /* * For "target: .RECURSIVE dir makefiles" constructs * Used to keep track of recursive calls to make * Name "target" gets one recursive prop */ struct _Name *directory; struct _Name *target; struct _Dependency *makefiles; Boolean has_built; Boolean in_depinfo; }; struct Sccs { /* * Each file that has a SCCS s. file gets one prop */ struct _Name *file; }; struct Suffix { /* * Cached list of suffixes that can build this target * suffix is built from .SUFFIXES */ struct _Name *suffix; struct _Cmd_line *command_template; }; struct Target { /* * For "target:: dependencies" constructs * The "::" construct is handled by converting it to * "foo: 1@foo" + "1@foo: dependecies" * "1@foo" gets one target prop * This target prop cause $@ to be bound to "foo" * not "1@foo" when the rule is evaluated */ struct _Name *target; }; struct STime { /* * Save the original time for :: targets */ timestruc_t time; }; struct Vpath_alias { /* * If a file was found using the VPATH it gets * a vpath_alias prop */ struct _Name *alias; }; struct Long_member_name { /* * Targets with a truncated member name carries * the full lib(member) name for the state file */ struct _Name *member_name; }; union Body { struct _Macro macro; struct Conditional conditional; struct Line line; struct Makefile makefile; struct Member member; struct Recursive recursive; struct Sccs sccs; struct Suffix suffix; struct Target target; struct STime time; struct Vpath_alias vpath_alias; struct Long_member_name long_member_name; struct _Macro_appendix macro_appendix; struct _Env_mem env_mem; }; #define PROPERTY_HEAD_SIZE (sizeof (struct _Property)-sizeof (union Body)) struct _Property { struct _Property *next; Property_id type:4; union Body body; }; /* Structure for dynamic "ascii" arrays */ struct ASCII_Dyn_Array { char *start; size_t size; }; struct _Envvar { struct _Name *name; struct _Name *value; struct _Envvar *next; char *env_string; Boolean already_put:1; }; /* * Macros for the reader */ #define GOTO_STATE(new_state) { \ SET_STATE(new_state); \ goto enter_state; \ } #define SET_STATE(new_state) state = (new_state) #define UNCACHE_SOURCE() if (source != NULL) { \ source->string.text.p = source_p; \ } #define CACHE_SOURCE(comp) if (source != NULL) { \ source_p = source->string.text.p - \ (comp); \ source_end = source->string.text.end; \ } #define GET_NEXT_BLOCK_NOCHK(source) { UNCACHE_SOURCE(); \ source = get_next_block_fn(source); \ CACHE_SOURCE(0) \ } #define GET_NEXT_BLOCK(source) { GET_NEXT_BLOCK_NOCHK(source); \ if (source != NULL && source->error_converting) { \ GOTO_STATE(illegal_bytes_state); \ } \ } #define GET_CHAR() ((source == NULL) || \ (source_p >= source_end) ? 0 : *source_p) struct _Source { struct _String string; struct _Source *previous; off_t bytes_left_in_file; short fd; Boolean already_expanded:1; Boolean error_converting:1; char *inp_buf; char *inp_buf_end; char *inp_buf_ptr; }; typedef enum { reading_nothing, reading_makefile, reading_statefile, rereading_statefile, reading_cpp_file } Makefile_type; /* * Typedefs for all structs */ typedef struct _Chain *Chain, Chain_rec; typedef struct _Envvar *Envvar, Envvar_rec; typedef struct _Macro_list *Macro_list, Macro_list_rec; typedef struct _Name *Name, Name_rec; typedef struct _Property *Property, Property_rec; typedef struct _Source *Source, Source_rec; typedef struct _String *String, String_rec; /* * name records hash table. */ struct Name_set { private: // single node in a tree struct entry { entry(Name name_, entry *parent_) : name(name_), parent(parent_), left(0), right(0), depth(1) {} Name name; entry *parent; entry *left; entry *right; unsigned depth; void setup_depth() { unsigned rdepth = (right != 0) ? right->depth : 0; unsigned ldepth = (left != 0) ? left->depth : 0; depth = 1 + ((ldepth > rdepth) ? ldepth : rdepth); } }; public: // make iterator a friend of Name_set to have access to struct entry struct iterator; friend struct Name_set::iterator; // iterator over tree nodes struct iterator { public: // constructors iterator() : node(0) {} iterator(entry *node_) : node(node_) {} iterator(const iterator&) = default; // dereference operator Name operator->() const { return node->name; } // conversion operator operator Name() { return node->name; } // assignment operator iterator& operator=(const iterator &o) { node = o.node; return *this; } // equality/inequality operators int operator==(const iterator &o) const { return (node == o.node); } int operator!=(const iterator &o) const { return (node != o.node); } // pre/post increment operators iterator& operator++(); iterator operator++(int) { iterator it = *this; ++*this; return it; } private: // the node iterator points to entry *node; }; public: // constructor Name_set() : root(0) {} // lookup, insert and remove operations Name lookup(const char *key); Name insert(const char *key, Boolean &found); void insert(Name name); // begin/end iterators iterator begin() const; iterator end() const { return iterator(); } private: // rebalance given node void rebalance(entry *node); private: // tree root entry *root; }; /* * extern declarations for all global variables. * The actual declarations are in globals.cc */ extern char char_semantics[]; extern wchar_t char_semantics_char[]; extern Macro_list cond_macro_list; extern Boolean conditional_macro_used; extern Boolean do_not_exec_rule; /* `-n' */ extern Boolean dollarget_seen; extern Boolean dollarless_flag; extern Name dollarless_value; extern char **environ; extern Envvar envvar; extern int exit_status; extern wchar_t *file_being_read; /* Variable gnu_style=true if env. var. SUN_MAKE_COMPAT_MODE=GNU (RFE 4866328) */ extern Boolean gnu_style; extern Name_set hashtab; extern Name host_arch; extern Name host_mach; extern int line_number; extern char *make_state_lockfile; extern Boolean make_word_mentioned; extern Makefile_type makefile_type; extern char mbs_buffer[]; extern Name path_name; extern Boolean posix; extern Name query; extern Boolean query_mentioned; extern Name hat; extern Boolean reading_environment; extern Name shell_name; extern Boolean svr4; extern Name target_arch; extern Name target_mach; extern Boolean tilde_rule; extern wchar_t wcs_buffer[]; extern Boolean working_on_targets; extern Name virtual_root; extern Boolean vpath_defined; extern Name vpath_name; extern Boolean make_state_locked; extern Boolean out_err_same; extern pid_t childPid; /* * RFE 1257407: make does not use fine granularity time info available from stat. * High resolution time comparison. */ inline int operator==(const timestruc_t &t1, const timestruc_t &t2) { return ((t1.tv_sec == t2.tv_sec) && (t1.tv_nsec == t2.tv_nsec)); } inline int operator!=(const timestruc_t &t1, const timestruc_t &t2) { return ((t1.tv_sec != t2.tv_sec) || (t1.tv_nsec != t2.tv_nsec)); } inline int operator>(const timestruc_t &t1, const timestruc_t &t2) { if (t1.tv_sec == t2.tv_sec) { return (t1.tv_nsec > t2.tv_nsec); } return (t1.tv_sec > t2.tv_sec); } inline int operator>=(const timestruc_t &t1, const timestruc_t &t2) { if (t1.tv_sec == t2.tv_sec) { return (t1.tv_nsec >= t2.tv_nsec); } return (t1.tv_sec > t2.tv_sec); } inline int operator<(const timestruc_t &t1, const timestruc_t &t2) { if (t1.tv_sec == t2.tv_sec) { return (t1.tv_nsec < t2.tv_nsec); } return (t1.tv_sec < t2.tv_sec); } inline int operator<=(const timestruc_t &t1, const timestruc_t &t2) { if (t1.tv_sec == t2.tv_sec) { return (t1.tv_nsec <= t2.tv_nsec); } return (t1.tv_sec < t2.tv_sec); } #endif /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _MKSH_DOSYS_H #define _MKSH_DOSYS_H #include #include extern Boolean await(Boolean, Boolean, Name, wchar_t *, pid_t, void *, int); extern int doexec(wchar_t *, Boolean, char *, char *, pathpt, int); extern int doshell(wchar_t *, Boolean, char *, char *, int); extern void redirect_io(char *, char *); extern void sh_command2string(String, String); #endif /* _MKSH_DOSYS_H */ #ifndef _MKSH_GLOBALS_H #define _MKSH_GLOBALS_H /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1994 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #endif #ifndef _MKSH_I18N_H #define _MKSH_I18N_H /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1994 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include extern int get_char_semantics_entry(wchar_t ch); extern char get_char_semantics_value(wchar_t ch); #endif #ifndef _MKSH_INIT_H #define _MKSH_INIT_H /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1995 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ int libmksh_init() void libmksh_fini(); #endif /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2002 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _MKSH_MACRO_H #define _MKSH_MACRO_H #include extern void expand_macro(Source, String, wchar_t *, Boolean); extern void expand_value(Name, String, Boolean); extern Name getvar(Name); extern Property setvar_daemon(Name, Name, Boolean, Daemon, Boolean, short); #endif /* _MKSH_MACRO_H */ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * Copyright 2019 RackTop Systems. */ #ifndef _MKSH_MISC_H #define _MKSH_MISC_H #include extern void append_char(wchar_t, String); extern Property append_prop(Name, Property_id); extern void append_string(wchar_t *, String, int); extern void enable_interrupt(void (*) (int)); extern char *errmsg(int); extern void fatal_mksh(const char *, ...) __NORETURN; extern void fatal_reader_mksh(const char *, ...) __NORETURN; extern char *get_current_path_mksh(void); extern Property get_prop(Property, Property_id); extern char *getmem(size_t); extern Name getname_fn(wchar_t *name, int len, Boolean dont_enter, Boolean *foundp = NULL); extern void store_name(Name); extern void free_name(Name); extern void handle_interrupt_mksh(int); extern Property maybe_append_prop(Name, Property_id); extern void retmem(wchar_t *); extern void retmem_mb(caddr_t); extern void setup_char_semantics(void); extern void setup_interrupt(void (*) (int)); extern void warning_mksh(char *, ...); extern void append_string(char *, String, int); extern wchar_t *get_wstring(char *); #endif /* _MKSH_MISC_H */ #ifndef _MKSH_MKSH_H #define _MKSH_MKSH_H /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * Included files */ #include #include #endif /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1994 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _MKSH_READ_H #define _MKSH_READ_H #include extern Source get_next_block_fn(Source source); #endif /* _MKSH_READ_H */ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1999 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _ARGS_H_ #define _ARGS_H_ #include #include #include #include #include #include #include #include #include typedef enum { rw_read, rw_write} rwt, *rwpt; extern void translate_with_thunk(char *, int (*) (char *), pathpt, pathpt, rwt); union Args { struct { int mode; } access; struct { int mode; } chmod; struct { int user; int group; } chown; struct { int mode; } creat; struct { char **argv; char **environ; } execve; struct { struct stat *buffer; } lstat; struct { int mode; } mkdir; struct { char *name; int mode; } mount; struct { int flags; int mode; } open; struct { char *buffer; int buffer_size; } readlink; struct { struct stat *buffer; } stat; struct { int length; } truncate; struct { struct timeval *time; } utimes; }; extern union Args vroot_args; extern int vroot_result; #endif /* _ARGS_H_ */ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1994 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _REPORT_H_ #define _REPORT_H_ #include extern FILE *get_report_file(void); extern char *get_target_being_reported_for(void); extern void report_dependency(const char *name); extern int file_lock(char *name, char *lockname, int *file_locked, int timeout); #define SUNPRO_DEPENDENCIES "SUNPRO_DEPENDENCIES" #define LD "LD" #define COMP "COMP" /* * These relate to Sun's ancient source control system that predated TeamWare, * named NSE. They appear to be used regardless of its presence, however, and * so linger. */ #define NSE_DEPINFO ".nse_depinfo" #define NSE_DEPINFO_LOCK ".nse_depinfo.lock" #endif /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _VROOT_H_ #define _VROOT_H_ #include #include #define VROOT_DEFAULT ((pathpt)-1) typedef struct { char *path; short length; } pathcellt, *pathcellpt, patht; typedef patht *pathpt; extern void add_dir_to_path(const char *, pathpt *, int); extern void flush_path_cache(void); extern void flush_vroot_cache(void); extern const char *get_path_name(void); extern char *get_vroot_path(char **, char **, char **); extern const char *get_vroot_name(void); extern int open_vroot(char *, int, int, pathpt, pathpt); extern pathpt parse_path_string(char *, int); extern void scan_path_first(void); extern void scan_vroot_first(void); extern void set_path_style(int); extern int access_vroot(char *, int, pathpt, pathpt); extern int execve_vroot(char *, char **, char **, pathpt, pathpt); extern int lstat_vroot(char *, struct stat *, pathpt, pathpt); extern int stat_vroot(char *, struct stat *, pathpt, pathpt); extern int readlink_vroot(char *, char *, int, pathpt, pathpt); #endif /* _VROOT_H_ */