1*abe76290Smillert /* $OpenBSD: sh.h,v 1.77 2023/06/21 22:22:08 millert Exp $ */ 27cb960a2Sdownsj 37cb960a2Sdownsj /* 47cb960a2Sdownsj * Public Domain Bourne/Korn shell 57cb960a2Sdownsj */ 67cb960a2Sdownsj 77cb960a2Sdownsj /* $From: sh.h,v 1.2 1994/05/19 18:32:40 michael Exp michael $ */ 87cb960a2Sdownsj 97cb960a2Sdownsj #include "config.h" /* system and option configuration info */ 107cb960a2Sdownsj 117cb960a2Sdownsj /* Start of common headers */ 127cb960a2Sdownsj 132b1380e7Sjca #include <limits.h> 147cb960a2Sdownsj #include <setjmp.h> 157cb960a2Sdownsj #include <stdarg.h> 164c503bcdSmillert #include <stddef.h> 177cb960a2Sdownsj #include <signal.h> 184a010e0cStb #include <stdbool.h> 1969b9f96bSmillert 207cb960a2Sdownsj /* end of common headers */ 217cb960a2Sdownsj 227cb960a2Sdownsj #define NELEM(a) (sizeof(a) / sizeof((a)[0])) 237cb960a2Sdownsj #define BIT(i) (1<<(i)) /* define bit in flag */ 247cb960a2Sdownsj 25c3e29789Sniklas #define NUFILE 32 /* Number of user-accessible files */ 267cb960a2Sdownsj #define FDBASE 10 /* First file usable by Shell */ 277cb960a2Sdownsj 28fe47dfe3Snicm #define BITS(t) (CHAR_BIT * sizeof(t)) 29fe47dfe3Snicm 307cb960a2Sdownsj /* Make MAGIC a char that might be printed to make bugs more obvious, but 317cb960a2Sdownsj * not a char that is used often. Also, can't use the high bit as it causes 327cb960a2Sdownsj * portability problems (calling strchr(x, 0x80|'x') is error prone). 337cb960a2Sdownsj */ 347cb960a2Sdownsj #define MAGIC (7) /* prefix for *?[!{,} during expand */ 357cb960a2Sdownsj #define ISMAGIC(c) ((unsigned char)(c) == MAGIC) 367cb960a2Sdownsj 3738bcb596Smartijn #define LINE 4096 /* input line size */ 387cb960a2Sdownsj 39772a9c36Smmcc extern const char *kshname; /* $0 */ 40772a9c36Smmcc extern pid_t kshpid; /* $$, shell pid */ 41772a9c36Smmcc extern pid_t procpid; /* pid of executing process */ 42772a9c36Smmcc extern uid_t ksheuid; /* effective uid of shell */ 43772a9c36Smmcc extern int exstat; /* exit status */ 44772a9c36Smmcc extern int subst_exstat; /* exit status of last $(..)/`..` */ 45772a9c36Smmcc extern const char *safe_prompt; /* safe prompt if PS1 substitution fails */ 46772a9c36Smmcc extern char username[]; /* username for \u prompt expansion */ 470ac57757Sschwarze extern int disable_subst; /* disable substitution during evaluation */ 487cb960a2Sdownsj 497cb960a2Sdownsj /* 507cb960a2Sdownsj * Area-based allocation built on malloc/free 517cb960a2Sdownsj */ 527cb960a2Sdownsj typedef struct Area { 53b57c16d2Sespie struct link *freelist; /* free list */ 547cb960a2Sdownsj } Area; 557cb960a2Sdownsj 56fa9dffc6Smmcc extern Area aperm; /* permanent object space */ 577cb960a2Sdownsj #define APERM &aperm 585ae5b57eStedu #define ATEMP &genv->area 597cb960a2Sdownsj 60945abdecSmillert #ifdef KSH_DEBUG 61945abdecSmillert # define kshdebug_init() kshdebug_init_() 62945abdecSmillert # define kshdebug_printf(a) kshdebug_printf_ a 63945abdecSmillert # define kshdebug_dump(a) kshdebug_dump_ a 64945abdecSmillert #else /* KSH_DEBUG */ 65945abdecSmillert # define kshdebug_init() 66945abdecSmillert # define kshdebug_printf(a) 67945abdecSmillert # define kshdebug_dump(a) 68945abdecSmillert #endif /* KSH_DEBUG */ 69945abdecSmillert 707cb960a2Sdownsj /* 717cb960a2Sdownsj * parsing & execution environment 727cb960a2Sdownsj */ 73fa9dffc6Smmcc struct env { 7446f8e29aSmillert short type; /* environment type - see below */ 757cb960a2Sdownsj short flags; /* EF_* */ 767cb960a2Sdownsj Area area; /* temporary allocation area */ 777cb960a2Sdownsj struct block *loc; /* local variables and functions */ 787cb960a2Sdownsj short *savefd; /* original redirected fd's */ 7946f8e29aSmillert struct env *oenv; /* link to previous environment */ 8069b9f96bSmillert sigjmp_buf jbuf; /* long jump back to env creator */ 817cb960a2Sdownsj struct temp *temps; /* temp files */ 82fa9dffc6Smmcc }; 835ae5b57eStedu extern struct env *genv; 847cb960a2Sdownsj 857cb960a2Sdownsj /* struct env.type values */ 8646f8e29aSmillert #define E_NONE 0 /* dummy environment */ 877cb960a2Sdownsj #define E_PARSE 1 /* parsing command # */ 887cb960a2Sdownsj #define E_FUNC 2 /* executing function # */ 897cb960a2Sdownsj #define E_INCL 3 /* including a file via . # */ 907cb960a2Sdownsj #define E_EXEC 4 /* executing command tree */ 917cb960a2Sdownsj #define E_LOOP 5 /* executing for/while # */ 927cb960a2Sdownsj #define E_ERRH 6 /* general error handler # */ 937cb960a2Sdownsj /* # indicates env has valid jbuf (see unwind()) */ 947cb960a2Sdownsj 957cb960a2Sdownsj /* struct env.flag values */ 967cb960a2Sdownsj #define EF_FUNC_PARSE BIT(0) /* function being parsed */ 977cb960a2Sdownsj #define EF_BRKCONT_PASS BIT(1) /* set if E_LOOP must pass break/continue on */ 98f00c5086Smillert #define EF_FAKE_SIGDIE BIT(2) /* hack to get info from unwind to quitenv */ 997cb960a2Sdownsj 1007cb960a2Sdownsj /* Do breaks/continues stop at env type e? */ 1017cb960a2Sdownsj #define STOP_BRKCONT(t) ((t) == E_NONE || (t) == E_PARSE \ 1027cb960a2Sdownsj || (t) == E_FUNC || (t) == E_INCL) 1037cb960a2Sdownsj /* Do returns stop at env type e? */ 1047cb960a2Sdownsj #define STOP_RETURN(t) ((t) == E_FUNC || (t) == E_INCL) 1057cb960a2Sdownsj 10669b9f96bSmillert /* values for siglongjmp(e->jbuf, 0) */ 1077cb960a2Sdownsj #define LRETURN 1 /* return statement */ 1087cb960a2Sdownsj #define LEXIT 2 /* exit statement */ 1097cb960a2Sdownsj #define LERROR 3 /* errorf() called */ 1107cb960a2Sdownsj #define LLEAVE 4 /* untrappable exit/error */ 1117cb960a2Sdownsj #define LINTR 5 /* ^C noticed */ 1127cb960a2Sdownsj #define LBREAK 6 /* break statement */ 1137cb960a2Sdownsj #define LCONTIN 7 /* continue statement */ 1147cb960a2Sdownsj #define LSHELL 8 /* return to interactive shell() */ 1157cb960a2Sdownsj #define LAEXPR 9 /* error in arithmetic expression */ 1167cb960a2Sdownsj 1177cb960a2Sdownsj /* option processing */ 1187cb960a2Sdownsj #define OF_CMDLINE 0x01 /* command line */ 1197cb960a2Sdownsj #define OF_SET 0x02 /* set builtin */ 1207cb960a2Sdownsj #define OF_SPECIAL 0x04 /* a special variable changing */ 1213b015934Smillert #define OF_INTERNAL 0x08 /* set internally by shell */ 1223b015934Smillert #define OF_ANY (OF_CMDLINE | OF_SET | OF_SPECIAL | OF_INTERNAL) 1237cb960a2Sdownsj 1247cb960a2Sdownsj struct option { 1257cb960a2Sdownsj const char *name; /* long name of option */ 1267cb960a2Sdownsj char c; /* character flag (if any) */ 1277cb960a2Sdownsj short flags; /* OF_* */ 1287cb960a2Sdownsj }; 129201e0776Smillert extern const struct option sh_options[]; 1307cb960a2Sdownsj 1317cb960a2Sdownsj /* 1327cb960a2Sdownsj * flags (the order of these enums MUST match the order in misc.c(options[])) 1337cb960a2Sdownsj */ 1347cb960a2Sdownsj enum sh_flag { 1357cb960a2Sdownsj FEXPORT = 0, /* -a: export all */ 1367cb960a2Sdownsj FBRACEEXPAND, /* enable {} globbing */ 1377cb960a2Sdownsj FBGNICE, /* bgnice */ 1387cb960a2Sdownsj FCOMMAND, /* -c: (invocation) execute specified command */ 139f740f764Sderaadt FCSHHISTORY, /* csh-style history enabled */ 1407cb960a2Sdownsj #ifdef EMACS 1417cb960a2Sdownsj FEMACS, /* emacs command editing */ 1427cb960a2Sdownsj #endif 1437cb960a2Sdownsj FERREXIT, /* -e: quit on error */ 1447cb960a2Sdownsj #ifdef EMACS 1457cb960a2Sdownsj FGMACS, /* gmacs command editing */ 1467cb960a2Sdownsj #endif 1477cb960a2Sdownsj FIGNOREEOF, /* eof does not exit */ 1487cb960a2Sdownsj FTALKING, /* -i: interactive */ 149060cee32Sjmc FKEYWORD, /* -k: name=value anywhere */ 1507cb960a2Sdownsj FLOGIN, /* -l: a login shell */ 1517cb960a2Sdownsj FMARKDIRS, /* mark dirs with / in file name completion */ 1527cb960a2Sdownsj FMONITOR, /* -m: job control monitoring */ 1537cb960a2Sdownsj FNOCLOBBER, /* -C: don't overwrite existing files */ 1547cb960a2Sdownsj FNOEXEC, /* -n: don't execute any commands */ 1557cb960a2Sdownsj FNOGLOB, /* -f: don't do file globbing */ 1567cb960a2Sdownsj FNOHUP, /* -H: don't kill running jobs when login shell exits */ 1577cb960a2Sdownsj FNOLOG, /* don't save functions in history (ignored) */ 1587cb960a2Sdownsj FNOTIFY, /* -b: asynchronous job completion notification */ 1597cb960a2Sdownsj FNOUNSET, /* -u: using an unset var is an error */ 1607cb960a2Sdownsj FPHYSICAL, /* -o physical: don't do logical cd's/pwd's */ 161cbb0b321Sjca FPIPEFAIL, /* -o pipefail: all commands in pipeline can affect $? */ 1627cb960a2Sdownsj FPOSIX, /* -o posix: be posixly correct */ 1637cb960a2Sdownsj FPRIVILEGED, /* -p: use suid_profile */ 1647cb960a2Sdownsj FRESTRICTED, /* -r: restricted shell */ 165060cee32Sjmc FSH, /* -o sh: favor sh behaviour */ 1667cb960a2Sdownsj FSTDIN, /* -s: (invocation) parse stdin */ 1677cb960a2Sdownsj FTRACKALL, /* -h: create tracked aliases for all commands */ 1687cb960a2Sdownsj FVERBOSE, /* -v: echo input */ 1697cb960a2Sdownsj #ifdef VI 1707cb960a2Sdownsj FVI, /* vi command editing */ 1717cb960a2Sdownsj FVIRAW, /* always read in raw mode (ignored) */ 1727cb960a2Sdownsj FVISHOW8, /* display chars with 8th bit set as is (versus M-) */ 1737cb960a2Sdownsj FVITABCOMPLETE, /* enable tab as file name completion char */ 174dcacb757Sdownsj FVIESCCOMPLETE, /* enable ESC as file name completion in command mode */ 1757cb960a2Sdownsj #endif 1767cb960a2Sdownsj FXTRACE, /* -x: execution trace */ 1773b015934Smillert FTALKING_I, /* (internal): initial shell was interactive */ 1787cb960a2Sdownsj FNFLAGS /* (place holder: how many flags are there) */ 1797cb960a2Sdownsj }; 1807cb960a2Sdownsj 1817cb960a2Sdownsj #define Flag(f) (shell_flags[(int) (f)]) 1827cb960a2Sdownsj 183fa9dffc6Smmcc extern char shell_flags[FNFLAGS]; 1847cb960a2Sdownsj 185778289f2Smmcc extern char null[]; /* null value for variable */ 1867cb960a2Sdownsj 187f00c5086Smillert enum temp_type { 188f00c5086Smillert TT_HEREDOC_EXP, /* expanded heredoc */ 189f00c5086Smillert TT_HIST_EDIT /* temp file used for history editing (fc -e) */ 190f00c5086Smillert }; 191f00c5086Smillert typedef enum temp_type Temp_type; 192f00c5086Smillert /* temp/heredoc files. The file is removed when the struct is freed. */ 1937cb960a2Sdownsj struct temp { 1947cb960a2Sdownsj struct temp *next; 1957cb960a2Sdownsj struct shf *shf; 1967cb960a2Sdownsj int pid; /* pid of process parsed here-doc */ 197f00c5086Smillert Temp_type type; 1987cb960a2Sdownsj char *name; 1997cb960a2Sdownsj }; 2007cb960a2Sdownsj 2017cb960a2Sdownsj /* 2027cb960a2Sdownsj * stdio and our IO routines 2037cb960a2Sdownsj */ 2047cb960a2Sdownsj 2057cb960a2Sdownsj #define shl_spare (&shf_iob[0]) /* for c_read()/c_print() */ 2067cb960a2Sdownsj #define shl_stdout (&shf_iob[1]) 2077cb960a2Sdownsj #define shl_out (&shf_iob[2]) 208778289f2Smmcc extern int shl_stdout_ok; 2097cb960a2Sdownsj 2107cb960a2Sdownsj /* 2117cb960a2Sdownsj * trap handlers 2127cb960a2Sdownsj */ 2137cb960a2Sdownsj typedef struct trap { 2147cb960a2Sdownsj int signal; /* signal number */ 2157cb960a2Sdownsj const char *name; /* short name */ 2167cb960a2Sdownsj const char *mess; /* descriptive name */ 2177cb960a2Sdownsj char *trap; /* trap command */ 2188d672f80Smillert volatile sig_atomic_t set; /* trap pending */ 2197cb960a2Sdownsj int flags; /* TF_* */ 2203f3749e5Smillert sig_t cursig; /* current handler (valid if TF_ORIG_* set) */ 2213f3749e5Smillert sig_t shtrap; /* shell signal handler */ 2227cb960a2Sdownsj } Trap; 2237cb960a2Sdownsj 2247cb960a2Sdownsj /* values for Trap.flags */ 2257cb960a2Sdownsj #define TF_SHELL_USES BIT(0) /* shell uses signal, user can't change */ 2267cb960a2Sdownsj #define TF_USER_SET BIT(1) /* user has (tried to) set trap */ 2277cb960a2Sdownsj #define TF_ORIG_IGN BIT(2) /* original action was SIG_IGN */ 2287cb960a2Sdownsj #define TF_ORIG_DFL BIT(3) /* original action was SIG_DFL */ 2297cb960a2Sdownsj #define TF_EXEC_IGN BIT(4) /* restore SIG_IGN just before exec */ 2307cb960a2Sdownsj #define TF_EXEC_DFL BIT(5) /* restore SIG_DFL just before exec */ 2317cb960a2Sdownsj #define TF_DFL_INTR BIT(6) /* when received, default action is LINTR */ 2327cb960a2Sdownsj #define TF_TTY_INTR BIT(7) /* tty generated signal (see j_waitj) */ 2337cb960a2Sdownsj #define TF_CHANGED BIT(8) /* used by runtrap() to detect trap changes */ 2347cb960a2Sdownsj #define TF_FATAL BIT(9) /* causes termination if not trapped */ 2357cb960a2Sdownsj 2367cb960a2Sdownsj /* values for setsig()/setexecsig() flags argument */ 2377cb960a2Sdownsj #define SS_RESTORE_MASK 0x3 /* how to restore a signal before an exec() */ 2387cb960a2Sdownsj #define SS_RESTORE_CURR 0 /* leave current handler in place */ 2397cb960a2Sdownsj #define SS_RESTORE_ORIG 1 /* restore original handler */ 240dcacb757Sdownsj #define SS_RESTORE_DFL 2 /* restore to SIG_DFL */ 241dcacb757Sdownsj #define SS_RESTORE_IGN 3 /* restore to SIG_IGN */ 2427cb960a2Sdownsj #define SS_FORCE BIT(3) /* set signal even if original signal ignored */ 2437cb960a2Sdownsj #define SS_USER BIT(4) /* user is doing the set (ie, trap command) */ 244dcacb757Sdownsj #define SS_SHTRAP BIT(5) /* trap for internal use (CHLD,ALRM,WINCH) */ 2457cb960a2Sdownsj 2467cb960a2Sdownsj #define SIGEXIT_ 0 /* for trap EXIT */ 24769b9f96bSmillert #define SIGERR_ NSIG /* for trap ERR */ 2487cb960a2Sdownsj 249778289f2Smmcc extern volatile sig_atomic_t trap; /* traps pending? */ 250778289f2Smmcc extern volatile sig_atomic_t intrsig; /* pending trap interrupts command */ 251778289f2Smmcc extern volatile sig_atomic_t fatal_trap; /* received a fatal signal */ 2520bd8b190Stedu extern volatile sig_atomic_t got_sigwinch; 25369b9f96bSmillert extern Trap sigtraps[NSIG+1]; 2547cb960a2Sdownsj 2557cb960a2Sdownsj /* 2567cb960a2Sdownsj * TMOUT support 2577cb960a2Sdownsj */ 2587cb960a2Sdownsj /* values for ksh_tmout_state */ 2597cb960a2Sdownsj enum tmout_enum { 2607cb960a2Sdownsj TMOUT_EXECUTING = 0, /* executing commands */ 2617cb960a2Sdownsj TMOUT_READING, /* waiting for input */ 2627cb960a2Sdownsj TMOUT_LEAVING /* have timed out */ 2637cb960a2Sdownsj }; 264778289f2Smmcc extern unsigned int ksh_tmout; 265778289f2Smmcc extern enum tmout_enum ksh_tmout_state; 2667cb960a2Sdownsj 2677cb960a2Sdownsj /* For "You have stopped jobs" message */ 268778289f2Smmcc extern int really_exit; 2697cb960a2Sdownsj 2707cb960a2Sdownsj /* 2717cb960a2Sdownsj * fast character classes 2727cb960a2Sdownsj */ 273dcacb757Sdownsj #define C_ALPHA BIT(0) /* a-z_A-Z */ 274bbf05626Smmcc /* was C_DIGIT */ 275dcacb757Sdownsj #define C_LEX1 BIT(2) /* \0 \t\n|&;<>() */ 276dcacb757Sdownsj #define C_VAR1 BIT(3) /* *@#!$-? */ 277dcacb757Sdownsj #define C_IFSWS BIT(4) /* \t \n (IFS white space) */ 278dcacb757Sdownsj #define C_SUBOP1 BIT(5) /* "=-+?" */ 27951c2de25Santon #define C_SUBOP2 BIT(6) /* "#%" */ 280dcacb757Sdownsj #define C_IFS BIT(7) /* $IFS */ 281dcacb757Sdownsj #define C_QUOTE BIT(8) /* \n\t"#$&'()*;<>?[\`| (needing quoting) */ 2827cb960a2Sdownsj 283dcacb757Sdownsj extern short ctypes []; 2847cb960a2Sdownsj 2857cb960a2Sdownsj #define ctype(c, t) !!(ctypes[(unsigned char)(c)]&(t)) 2867cb960a2Sdownsj #define letter(c) ctype(c, C_ALPHA) 287bbf05626Smmcc #define digit(c) isdigit((unsigned char)(c)) 288bbf05626Smmcc #define letnum(c) (ctype(c, C_ALPHA) || isdigit((unsigned char)(c))) 2897cb960a2Sdownsj 290778289f2Smmcc extern int ifs0; /* for "$*" */ 2917cb960a2Sdownsj 2927cb960a2Sdownsj /* Argument parsing for built-in commands and getopts command */ 2937cb960a2Sdownsj 2947cb960a2Sdownsj /* Values for Getopt.flags */ 2957cb960a2Sdownsj #define GF_ERROR BIT(0) /* call errorf() if there is an error */ 2967cb960a2Sdownsj #define GF_PLUSOPT BIT(1) /* allow +c as an option */ 2977cb960a2Sdownsj #define GF_NONAME BIT(2) /* don't print argv[0] in errors */ 2987cb960a2Sdownsj 2997cb960a2Sdownsj /* Values for Getopt.info */ 3007cb960a2Sdownsj #define GI_MINUS BIT(0) /* an option started with -... */ 3017cb960a2Sdownsj #define GI_PLUS BIT(1) /* an option started with +... */ 3027cb960a2Sdownsj #define GI_MINUSMINUS BIT(2) /* arguments were ended with -- */ 3037cb960a2Sdownsj 3047cb960a2Sdownsj typedef struct { 3057cb960a2Sdownsj int optind; 3063b015934Smillert int uoptind;/* what user sees in $OPTIND */ 3077cb960a2Sdownsj char *optarg; 3087cb960a2Sdownsj int flags; /* see GF_* */ 3097cb960a2Sdownsj int info; /* see GI_* */ 3107cb960a2Sdownsj unsigned int p; /* 0 or index into argv[optind - 1] */ 3117cb960a2Sdownsj char buf[2]; /* for bad option OPTARG value */ 3127cb960a2Sdownsj } Getopt; 3137cb960a2Sdownsj 314778289f2Smmcc extern Getopt builtin_opt; /* for shell builtin commands */ 315778289f2Smmcc extern Getopt user_opt; /* parsing state for getopts builtin command */ 3167cb960a2Sdownsj 3177cb960a2Sdownsj /* This for co-processes */ 318dcacb757Sdownsj 319c3ad38e4Snicm typedef int Coproc_id; /* something that won't (realistically) wrap */ 3207cb960a2Sdownsj struct coproc { 3217cb960a2Sdownsj int read; /* pipe from co-process's stdout */ 3227cb960a2Sdownsj int readw; /* other side of read (saved temporarily) */ 3237cb960a2Sdownsj int write; /* pipe to co-process's stdin */ 324dcacb757Sdownsj Coproc_id id; /* id of current output pipe */ 325dcacb757Sdownsj int njobs; /* number of live jobs using output pipe */ 326dcacb757Sdownsj void *job; /* 0 or job of co-process using input pipe */ 3277cb960a2Sdownsj }; 3281ff40150Smmcc extern struct coproc coproc; 3297cb960a2Sdownsj 330dcacb757Sdownsj /* Used in jobs.c and by coprocess stuff in exec.c */ 3311ff40150Smmcc extern sigset_t sm_default, sm_sigchld; 332dcacb757Sdownsj 3337cb960a2Sdownsj extern const char ksh_version[]; 3347cb960a2Sdownsj 3357cb960a2Sdownsj /* name of called builtin function (used by error functions) */ 3361ff40150Smmcc extern char *builtin_argv0; 3371ff40150Smmcc extern int builtin_flag; /* flags of called builtin (SPEC_BI, etc.) */ 3387cb960a2Sdownsj 3397cb960a2Sdownsj /* current working directory, and size of memory allocated for same */ 3401ff40150Smmcc extern char *current_wd; 3411ff40150Smmcc extern int current_wd_size; 3427cb960a2Sdownsj 343060cee32Sjmc /* Minimum required space to work with on a line - if the prompt leaves less 3447cb960a2Sdownsj * space than this on a line, the prompt is truncated. 3457cb960a2Sdownsj */ 3467cb960a2Sdownsj #define MIN_EDIT_SPACE 7 347060cee32Sjmc /* Minimum allowed value for x_cols: 2 for prompt, 3 for " < " at end of line 3487cb960a2Sdownsj */ 3497cb960a2Sdownsj #define MIN_COLS (2 + MIN_EDIT_SPACE + 3) 3501ff40150Smmcc extern int x_cols; /* tty columns */ 3517cb960a2Sdownsj 3527cb960a2Sdownsj /* These to avoid bracket matching problems */ 3537cb960a2Sdownsj #define OPAREN '(' 3547cb960a2Sdownsj #define CPAREN ')' 3557cb960a2Sdownsj #define OBRACK '[' 3567cb960a2Sdownsj #define CBRACK ']' 3577cb960a2Sdownsj #define OBRACE '{' 3587cb960a2Sdownsj #define CBRACE '}' 3597cb960a2Sdownsj 3607055cce3Sdownsj /* Determine the location of the system (common) profile */ 3617055cce3Sdownsj #define KSH_SYSTEM_PROFILE "/etc/profile" 3627cb960a2Sdownsj 363f00c5086Smillert /* Used by v_evaluate() and setstr() to control action when error occurs */ 364e862637cSmillert #define KSH_UNWIND_ERROR 0x0 /* unwind the stack (longjmp) */ 365e862637cSmillert #define KSH_RETURN_ERROR 0x1 /* return 1/0 for success/failure */ 366e862637cSmillert #define KSH_IGNORE_RDONLY 0x4 /* ignore the read-only flag */ 367f00c5086Smillert 3687cb960a2Sdownsj #include "shf.h" 3697cb960a2Sdownsj #include "table.h" 3707cb960a2Sdownsj #include "tree.h" 3717cb960a2Sdownsj #include "expand.h" 3727cb960a2Sdownsj #include "lex.h" 3739fe385e5Smmcc 3749fe385e5Smmcc /* alloc.c */ 3759fe385e5Smmcc Area * ainit(Area *); 3769fe385e5Smmcc void afreeall(Area *); 3779fe385e5Smmcc void * alloc(size_t, Area *); 378d67c3782Smmcc void * areallocarray(void *, size_t, size_t, Area *); 3799fe385e5Smmcc void * aresize(void *, size_t, Area *); 3809fe385e5Smmcc void afree(void *, Area *); 3819fe385e5Smmcc /* c_ksh.c */ 3829fe385e5Smmcc int c_cd(char **); 3839fe385e5Smmcc int c_pwd(char **); 3849fe385e5Smmcc int c_print(char **); 3859fe385e5Smmcc int c_whence(char **); 3869fe385e5Smmcc int c_command(char **); 387b4fe65e7Sbenno int c_type(char **); 3889fe385e5Smmcc int c_typeset(char **); 3899fe385e5Smmcc int c_alias(char **); 3909fe385e5Smmcc int c_unalias(char **); 3919fe385e5Smmcc int c_let(char **); 3929fe385e5Smmcc int c_jobs(char **); 3939fe385e5Smmcc int c_fgbg(char **); 3949fe385e5Smmcc int c_kill(char **); 3959fe385e5Smmcc void getopts_reset(int); 3969fe385e5Smmcc int c_getopts(char **); 3979fe385e5Smmcc int c_bind(char **); 3989fe385e5Smmcc /* c_sh.c */ 3999fe385e5Smmcc int c_label(char **); 4009fe385e5Smmcc int c_shift(char **); 4019fe385e5Smmcc int c_umask(char **); 4029fe385e5Smmcc int c_dot(char **); 4039fe385e5Smmcc int c_wait(char **); 4049fe385e5Smmcc int c_read(char **); 4059fe385e5Smmcc int c_eval(char **); 4069fe385e5Smmcc int c_trap(char **); 4079fe385e5Smmcc int c_brkcont(char **); 4089fe385e5Smmcc int c_exitreturn(char **); 4099fe385e5Smmcc int c_set(char **); 4109fe385e5Smmcc int c_unset(char **); 4119fe385e5Smmcc int c_ulimit(char **); 4129fe385e5Smmcc int c_times(char **); 4139fe385e5Smmcc int timex(struct op *, int, volatile int *); 4149fe385e5Smmcc void timex_hook(struct op *, char ** volatile *); 4159fe385e5Smmcc int c_exec(char **); 4169fe385e5Smmcc int c_builtin(char **); 4179fe385e5Smmcc /* c_test.c */ 4189fe385e5Smmcc int c_test(char **); 4199fe385e5Smmcc /* edit.c: most prototypes in edit.h */ 4209fe385e5Smmcc void x_init(void); 4219fe385e5Smmcc int x_read(char *, size_t); 4229fe385e5Smmcc void set_editmode(const char *); 4239fe385e5Smmcc /* emacs.c: most prototypes in edit.h */ 4249fe385e5Smmcc int x_bind(const char *, const char *, int, int); 4259fe385e5Smmcc /* eval.c */ 4269fe385e5Smmcc char * substitute(const char *, int); 4279fe385e5Smmcc char ** eval(char **, int); 4289fe385e5Smmcc char * evalstr(char *cp, int); 4299fe385e5Smmcc char * evalonestr(char *cp, int); 4309fe385e5Smmcc char *debunk(char *, const char *, size_t); 4319fe385e5Smmcc void expand(char *, XPtrV *, int); 4329fe385e5Smmcc int glob_str(char *, XPtrV *, int); 4339fe385e5Smmcc /* exec.c */ 4349fe385e5Smmcc int execute(struct op * volatile, volatile int, volatile int *); 4359fe385e5Smmcc int shcomexec(char **); 4369fe385e5Smmcc struct tbl * findfunc(const char *, unsigned int, int); 4379fe385e5Smmcc int define(const char *, struct op *); 4389fe385e5Smmcc void builtin(const char *, int (*)(char **)); 4399fe385e5Smmcc struct tbl * findcom(const char *, int); 4409fe385e5Smmcc void flushcom(int); 4419fe385e5Smmcc char * search(const char *, const char *, int, int *); 4429fe385e5Smmcc int search_access(const char *, int, int *); 4439fe385e5Smmcc int pr_menu(char *const *); 4449fe385e5Smmcc /* expr.c */ 445517d3880Stobias int evaluate(const char *, int64_t *, int, bool); 4469fe385e5Smmcc int v_evaluate(struct tbl *, const char *, volatile int, bool); 4479fe385e5Smmcc /* history.c */ 4489fe385e5Smmcc void init_histvec(void); 4499fe385e5Smmcc void hist_init(Source *); 4509fe385e5Smmcc void hist_finish(void); 4519fe385e5Smmcc void histsave(int, const char *, int); 4529fe385e5Smmcc int c_fc(char **); 453c722fcadSmartijn void c_fc_reset(void); 454a725701fSjca void sethistcontrol(const char *); 4559fe385e5Smmcc void sethistsize(int); 4569fe385e5Smmcc void sethistfile(const char *); 4579fe385e5Smmcc char ** histpos(void); 4589fe385e5Smmcc int histnum(int); 4599fe385e5Smmcc int findhist(int, int, const char *, int); 4609fe385e5Smmcc int findhistrel(const char *); 4619fe385e5Smmcc char **hist_get_newest(int); 4629fe385e5Smmcc 4639fe385e5Smmcc /* io.c */ 4649fe385e5Smmcc void errorf(const char *, ...) 4659fe385e5Smmcc __attribute__((__noreturn__, __format__ (printf, 1, 2))); 466504796f7Smmcc void warningf(bool, const char *, ...) 4679fe385e5Smmcc __attribute__((__format__ (printf, 2, 3))); 4689fe385e5Smmcc void bi_errorf(const char *, ...) 4699fe385e5Smmcc __attribute__((__format__ (printf, 1, 2))); 4706c72b531Sjca void internal_errorf(const char *, ...) 4716c72b531Sjca __attribute__((__noreturn__, __format__ (printf, 1, 2))); 4726c72b531Sjca void internal_warningf(const char *, ...) 4736c72b531Sjca __attribute__((__format__ (printf, 1, 2))); 4749fe385e5Smmcc void error_prefix(int); 4759fe385e5Smmcc void shellf(const char *, ...) 4769fe385e5Smmcc __attribute__((__format__ (printf, 1, 2))); 4779fe385e5Smmcc void shprintf(const char *, ...) 4789fe385e5Smmcc __attribute__((__format__ (printf, 1, 2))); 4799fe385e5Smmcc #ifdef KSH_DEBUG 4809fe385e5Smmcc void kshdebug_init_(void); 4819fe385e5Smmcc void kshdebug_printf_(const char *, ...) 4829fe385e5Smmcc __attribute__((__format__ (printf, 1, 2))); 4839fe385e5Smmcc void kshdebug_dump_(const char *, const void *, int); 4849fe385e5Smmcc #endif /* KSH_DEBUG */ 4859fe385e5Smmcc int can_seek(int); 4869fe385e5Smmcc void initio(void); 4879fe385e5Smmcc int ksh_dup2(int, int, int); 4889fe385e5Smmcc int savefd(int); 4899fe385e5Smmcc void restfd(int, int); 4909fe385e5Smmcc void openpipe(int *); 4919fe385e5Smmcc void closepipe(int *); 4929fe385e5Smmcc int check_fd(char *, int, const char **); 4939fe385e5Smmcc void coproc_init(void); 4949fe385e5Smmcc void coproc_read_close(int); 4959fe385e5Smmcc void coproc_readw_close(int); 4969fe385e5Smmcc void coproc_write_close(int); 4979fe385e5Smmcc int coproc_getfd(int, const char **); 4989fe385e5Smmcc void coproc_cleanup(int); 4999fe385e5Smmcc struct temp *maketemp(Area *, Temp_type, struct temp **); 5009fe385e5Smmcc /* jobs.c */ 5019fe385e5Smmcc void j_init(int); 5029fe385e5Smmcc void j_suspend(void); 5039fe385e5Smmcc void j_exit(void); 5049fe385e5Smmcc void j_change(void); 5059fe385e5Smmcc int exchild(struct op *, int, volatile int *, int); 5069fe385e5Smmcc void startlast(void); 5079fe385e5Smmcc int waitlast(void); 5089fe385e5Smmcc int waitfor(const char *, int *); 5099fe385e5Smmcc int j_kill(const char *, int); 5109fe385e5Smmcc int j_resume(const char *, int); 5119fe385e5Smmcc int j_jobs(const char *, int, int); 5129fe385e5Smmcc int j_njobs(void); 5139fe385e5Smmcc void j_notify(void); 5149fe385e5Smmcc pid_t j_async(void); 5159fe385e5Smmcc int j_stopped_running(void); 5169fe385e5Smmcc /* mail.c */ 5179fe385e5Smmcc void mcheck(void); 518517d3880Stobias void mcset(int64_t); 5199fe385e5Smmcc void mbset(char *); 5209fe385e5Smmcc void mpset(char *); 5219fe385e5Smmcc /* main.c */ 5229fe385e5Smmcc int include(const char *, int, char **, int); 5239fe385e5Smmcc int command(const char *, int); 5249fe385e5Smmcc int shell(Source *volatile, int volatile); 5259fe385e5Smmcc void unwind(int) __attribute__((__noreturn__)); 5269fe385e5Smmcc void newenv(int); 5279fe385e5Smmcc void quitenv(struct shf *); 5289fe385e5Smmcc void cleanup_parents_env(void); 5299fe385e5Smmcc void cleanup_proc_env(void); 5309fe385e5Smmcc /* misc.c */ 5319fe385e5Smmcc void setctypes(const char *, int); 5329fe385e5Smmcc void initctypes(void); 533517d3880Stobias char * u64ton(uint64_t, int); 5349fe385e5Smmcc char * str_save(const char *, Area *); 5359fe385e5Smmcc char * str_nsave(const char *, int, Area *); 5369fe385e5Smmcc int option(const char *); 5379fe385e5Smmcc char * getoptions(void); 5389fe385e5Smmcc void change_flag(enum sh_flag, int, int); 5399fe385e5Smmcc int parse_args(char **, int, int *); 5409fe385e5Smmcc int getn(const char *, int *); 5419fe385e5Smmcc int bi_getn(const char *, int *); 5429fe385e5Smmcc int gmatch(const char *, const char *, int); 5439fe385e5Smmcc int has_globbing(const char *, const char *); 5449fe385e5Smmcc const unsigned char *pat_scan(const unsigned char *, const unsigned char *, 5459fe385e5Smmcc int); 5469fe385e5Smmcc void qsortp(void **, size_t, int (*)(const void *, const void *)); 5479fe385e5Smmcc int xstrcmp(const void *, const void *); 5489fe385e5Smmcc void ksh_getopt_reset(Getopt *, int); 5499fe385e5Smmcc int ksh_getopt(char **, Getopt *, const char *); 5509fe385e5Smmcc void print_value_quoted(const char *); 5519fe385e5Smmcc void print_columns(struct shf *, int, char *(*)(void *, int, char *, int), 5529fe385e5Smmcc void *, int, int prefcol); 5539fe385e5Smmcc int strip_nuls(char *, int); 5549fe385e5Smmcc int blocking_read(int, char *, int); 5559fe385e5Smmcc int reset_nonblock(int); 5569fe385e5Smmcc char *ksh_get_wd(char *, int); 5579fe385e5Smmcc /* path.c */ 5589fe385e5Smmcc int make_path(const char *, const char *, char **, XString *, int *); 5599fe385e5Smmcc void simplify_path(char *); 5609fe385e5Smmcc char *get_phys_path(const char *); 5619fe385e5Smmcc void set_current_wd(char *); 5629fe385e5Smmcc /* syn.c */ 5639fe385e5Smmcc void initkeywords(void); 5649fe385e5Smmcc struct op * compile(Source *); 5659fe385e5Smmcc /* trap.c */ 5669fe385e5Smmcc void inittraps(void); 5679fe385e5Smmcc void alarm_init(void); 5689fe385e5Smmcc Trap * gettrap(const char *, int); 5699fe385e5Smmcc void trapsig(int); 5709fe385e5Smmcc void intrcheck(void); 5719fe385e5Smmcc int fatal_trap_check(void); 5729fe385e5Smmcc int trap_pending(void); 5739fe385e5Smmcc void runtraps(int intr); 5749fe385e5Smmcc void runtrap(Trap *); 5759fe385e5Smmcc void cleartraps(void); 5769fe385e5Smmcc void restoresigs(void); 5779fe385e5Smmcc void settrap(Trap *, char *); 5789fe385e5Smmcc int block_pipe(void); 5799fe385e5Smmcc void restore_pipe(int); 5809fe385e5Smmcc int setsig(Trap *, sig_t, int); 5819fe385e5Smmcc void setexecsig(Trap *, int); 5829fe385e5Smmcc /* var.c */ 5839fe385e5Smmcc void newblock(void); 5849fe385e5Smmcc void popblock(void); 5859fe385e5Smmcc void initvar(void); 5869fe385e5Smmcc struct tbl * global(const char *); 5879fe385e5Smmcc struct tbl * local(const char *, bool); 5889fe385e5Smmcc char * str_val(struct tbl *); 589517d3880Stobias int64_t intval(struct tbl *); 5909fe385e5Smmcc int setstr(struct tbl *, const char *, int); 5919fe385e5Smmcc struct tbl *setint_v(struct tbl *, struct tbl *, bool); 592517d3880Stobias void setint(struct tbl *, int64_t); 593517d3880Stobias int getint(struct tbl *, int64_t *, bool); 5949fe385e5Smmcc struct tbl *typeset(const char *, int, int, int, int); 5959fe385e5Smmcc void unset(struct tbl *, int); 5969fe385e5Smmcc char * skip_varname(const char *, int); 5979fe385e5Smmcc char *skip_wdvarname(const char *, int); 5989fe385e5Smmcc int is_wdvarname(const char *, int); 5999fe385e5Smmcc int is_wdvarassign(const char *); 6009fe385e5Smmcc char ** makenv(void); 6019fe385e5Smmcc void change_random(void); 6029fe385e5Smmcc int array_ref_len(const char *); 6039fe385e5Smmcc char * arrayname(const char *); 6049fe385e5Smmcc void set_array(const char *, int, char **); 6059fe385e5Smmcc /* vi.c: see edit.h */ 606