sh.h revision 1.74
1/* $OpenBSD: sh.h,v 1.74 2018/11/20 07:02:23 martijn Exp $ */ 2 3/* 4 * Public Domain Bourne/Korn shell 5 */ 6 7/* $From: sh.h,v 1.2 1994/05/19 18:32:40 michael Exp michael $ */ 8 9#include "config.h" /* system and option configuration info */ 10 11/* Start of common headers */ 12 13#include <limits.h> 14#include <setjmp.h> 15#include <stdarg.h> 16#include <stddef.h> 17#include <signal.h> 18#include <stdbool.h> 19 20/* end of common headers */ 21 22#define NELEM(a) (sizeof(a) / sizeof((a)[0])) 23#define BIT(i) (1<<(i)) /* define bit in flag */ 24 25#define NUFILE 32 /* Number of user-accessible files */ 26#define FDBASE 10 /* First file usable by Shell */ 27 28#define BITS(t) (CHAR_BIT * sizeof(t)) 29 30/* Make MAGIC a char that might be printed to make bugs more obvious, but 31 * not a char that is used often. Also, can't use the high bit as it causes 32 * portability problems (calling strchr(x, 0x80|'x') is error prone). 33 */ 34#define MAGIC (7) /* prefix for *?[!{,} during expand */ 35#define ISMAGIC(c) ((unsigned char)(c) == MAGIC) 36 37#define LINE 4096 /* input line size */ 38 39extern const char *kshname; /* $0 */ 40extern pid_t kshpid; /* $$, shell pid */ 41extern pid_t procpid; /* pid of executing process */ 42extern uid_t ksheuid; /* effective uid of shell */ 43extern int exstat; /* exit status */ 44extern int subst_exstat; /* exit status of last $(..)/`..` */ 45extern const char *safe_prompt; /* safe prompt if PS1 substitution fails */ 46extern char username[]; /* username for \u prompt expansion */ 47 48/* 49 * Area-based allocation built on malloc/free 50 */ 51typedef struct Area { 52 struct link *freelist; /* free list */ 53} Area; 54 55extern Area aperm; /* permanent object space */ 56#define APERM &aperm 57#define ATEMP &genv->area 58 59#ifdef KSH_DEBUG 60# define kshdebug_init() kshdebug_init_() 61# define kshdebug_printf(a) kshdebug_printf_ a 62# define kshdebug_dump(a) kshdebug_dump_ a 63#else /* KSH_DEBUG */ 64# define kshdebug_init() 65# define kshdebug_printf(a) 66# define kshdebug_dump(a) 67#endif /* KSH_DEBUG */ 68 69/* 70 * parsing & execution environment 71 */ 72struct env { 73 short type; /* environment type - see below */ 74 short flags; /* EF_* */ 75 Area area; /* temporary allocation area */ 76 struct block *loc; /* local variables and functions */ 77 short *savefd; /* original redirected fd's */ 78 struct env *oenv; /* link to previous environment */ 79 sigjmp_buf jbuf; /* long jump back to env creator */ 80 struct temp *temps; /* temp files */ 81}; 82extern struct env *genv; 83 84/* struct env.type values */ 85#define E_NONE 0 /* dummy environment */ 86#define E_PARSE 1 /* parsing command # */ 87#define E_FUNC 2 /* executing function # */ 88#define E_INCL 3 /* including a file via . # */ 89#define E_EXEC 4 /* executing command tree */ 90#define E_LOOP 5 /* executing for/while # */ 91#define E_ERRH 6 /* general error handler # */ 92/* # indicates env has valid jbuf (see unwind()) */ 93 94/* struct env.flag values */ 95#define EF_FUNC_PARSE BIT(0) /* function being parsed */ 96#define EF_BRKCONT_PASS BIT(1) /* set if E_LOOP must pass break/continue on */ 97#define EF_FAKE_SIGDIE BIT(2) /* hack to get info from unwind to quitenv */ 98 99/* Do breaks/continues stop at env type e? */ 100#define STOP_BRKCONT(t) ((t) == E_NONE || (t) == E_PARSE \ 101 || (t) == E_FUNC || (t) == E_INCL) 102/* Do returns stop at env type e? */ 103#define STOP_RETURN(t) ((t) == E_FUNC || (t) == E_INCL) 104 105/* values for siglongjmp(e->jbuf, 0) */ 106#define LRETURN 1 /* return statement */ 107#define LEXIT 2 /* exit statement */ 108#define LERROR 3 /* errorf() called */ 109#define LLEAVE 4 /* untrappable exit/error */ 110#define LINTR 5 /* ^C noticed */ 111#define LBREAK 6 /* break statement */ 112#define LCONTIN 7 /* continue statement */ 113#define LSHELL 8 /* return to interactive shell() */ 114#define LAEXPR 9 /* error in arithmetic expression */ 115 116/* option processing */ 117#define OF_CMDLINE 0x01 /* command line */ 118#define OF_SET 0x02 /* set builtin */ 119#define OF_SPECIAL 0x04 /* a special variable changing */ 120#define OF_INTERNAL 0x08 /* set internally by shell */ 121#define OF_ANY (OF_CMDLINE | OF_SET | OF_SPECIAL | OF_INTERNAL) 122 123struct option { 124 const char *name; /* long name of option */ 125 char c; /* character flag (if any) */ 126 short flags; /* OF_* */ 127}; 128extern const struct option sh_options[]; 129 130/* 131 * flags (the order of these enums MUST match the order in misc.c(options[])) 132 */ 133enum sh_flag { 134 FEXPORT = 0, /* -a: export all */ 135 FBRACEEXPAND, /* enable {} globbing */ 136 FBGNICE, /* bgnice */ 137 FCOMMAND, /* -c: (invocation) execute specified command */ 138 FCSHHISTORY, /* csh-style history enabled */ 139#ifdef EMACS 140 FEMACS, /* emacs command editing */ 141#endif 142 FERREXIT, /* -e: quit on error */ 143#ifdef EMACS 144 FGMACS, /* gmacs command editing */ 145#endif 146 FIGNOREEOF, /* eof does not exit */ 147 FTALKING, /* -i: interactive */ 148 FKEYWORD, /* -k: name=value anywhere */ 149 FLOGIN, /* -l: a login shell */ 150 FMARKDIRS, /* mark dirs with / in file name completion */ 151 FMONITOR, /* -m: job control monitoring */ 152 FNOCLOBBER, /* -C: don't overwrite existing files */ 153 FNOEXEC, /* -n: don't execute any commands */ 154 FNOGLOB, /* -f: don't do file globbing */ 155 FNOHUP, /* -H: don't kill running jobs when login shell exits */ 156 FNOLOG, /* don't save functions in history (ignored) */ 157 FNOTIFY, /* -b: asynchronous job completion notification */ 158 FNOUNSET, /* -u: using an unset var is an error */ 159 FPHYSICAL, /* -o physical: don't do logical cd's/pwd's */ 160 FPOSIX, /* -o posix: be posixly correct */ 161 FPRIVILEGED, /* -p: use suid_profile */ 162 FRESTRICTED, /* -r: restricted shell */ 163 FSH, /* -o sh: favor sh behaviour */ 164 FSTDIN, /* -s: (invocation) parse stdin */ 165 FTRACKALL, /* -h: create tracked aliases for all commands */ 166 FVERBOSE, /* -v: echo input */ 167#ifdef VI 168 FVI, /* vi command editing */ 169 FVIRAW, /* always read in raw mode (ignored) */ 170 FVISHOW8, /* display chars with 8th bit set as is (versus M-) */ 171 FVITABCOMPLETE, /* enable tab as file name completion char */ 172 FVIESCCOMPLETE, /* enable ESC as file name completion in command mode */ 173#endif 174 FXTRACE, /* -x: execution trace */ 175 FTALKING_I, /* (internal): initial shell was interactive */ 176 FNFLAGS /* (place holder: how many flags are there) */ 177}; 178 179#define Flag(f) (shell_flags[(int) (f)]) 180 181extern char shell_flags[FNFLAGS]; 182 183extern char null[]; /* null value for variable */ 184 185enum temp_type { 186 TT_HEREDOC_EXP, /* expanded heredoc */ 187 TT_HIST_EDIT /* temp file used for history editing (fc -e) */ 188}; 189typedef enum temp_type Temp_type; 190/* temp/heredoc files. The file is removed when the struct is freed. */ 191struct temp { 192 struct temp *next; 193 struct shf *shf; 194 int pid; /* pid of process parsed here-doc */ 195 Temp_type type; 196 char *name; 197}; 198 199/* 200 * stdio and our IO routines 201 */ 202 203#define shl_spare (&shf_iob[0]) /* for c_read()/c_print() */ 204#define shl_stdout (&shf_iob[1]) 205#define shl_out (&shf_iob[2]) 206extern int shl_stdout_ok; 207 208/* 209 * trap handlers 210 */ 211typedef struct trap { 212 int signal; /* signal number */ 213 const char *name; /* short name */ 214 const char *mess; /* descriptive name */ 215 char *trap; /* trap command */ 216 volatile sig_atomic_t set; /* trap pending */ 217 int flags; /* TF_* */ 218 sig_t cursig; /* current handler (valid if TF_ORIG_* set) */ 219 sig_t shtrap; /* shell signal handler */ 220} Trap; 221 222/* values for Trap.flags */ 223#define TF_SHELL_USES BIT(0) /* shell uses signal, user can't change */ 224#define TF_USER_SET BIT(1) /* user has (tried to) set trap */ 225#define TF_ORIG_IGN BIT(2) /* original action was SIG_IGN */ 226#define TF_ORIG_DFL BIT(3) /* original action was SIG_DFL */ 227#define TF_EXEC_IGN BIT(4) /* restore SIG_IGN just before exec */ 228#define TF_EXEC_DFL BIT(5) /* restore SIG_DFL just before exec */ 229#define TF_DFL_INTR BIT(6) /* when received, default action is LINTR */ 230#define TF_TTY_INTR BIT(7) /* tty generated signal (see j_waitj) */ 231#define TF_CHANGED BIT(8) /* used by runtrap() to detect trap changes */ 232#define TF_FATAL BIT(9) /* causes termination if not trapped */ 233 234/* values for setsig()/setexecsig() flags argument */ 235#define SS_RESTORE_MASK 0x3 /* how to restore a signal before an exec() */ 236#define SS_RESTORE_CURR 0 /* leave current handler in place */ 237#define SS_RESTORE_ORIG 1 /* restore original handler */ 238#define SS_RESTORE_DFL 2 /* restore to SIG_DFL */ 239#define SS_RESTORE_IGN 3 /* restore to SIG_IGN */ 240#define SS_FORCE BIT(3) /* set signal even if original signal ignored */ 241#define SS_USER BIT(4) /* user is doing the set (ie, trap command) */ 242#define SS_SHTRAP BIT(5) /* trap for internal use (CHLD,ALRM,WINCH) */ 243 244#define SIGEXIT_ 0 /* for trap EXIT */ 245#define SIGERR_ NSIG /* for trap ERR */ 246 247extern volatile sig_atomic_t trap; /* traps pending? */ 248extern volatile sig_atomic_t intrsig; /* pending trap interrupts command */ 249extern volatile sig_atomic_t fatal_trap; /* received a fatal signal */ 250extern volatile sig_atomic_t got_sigwinch; 251extern Trap sigtraps[NSIG+1]; 252 253/* 254 * TMOUT support 255 */ 256/* values for ksh_tmout_state */ 257enum tmout_enum { 258 TMOUT_EXECUTING = 0, /* executing commands */ 259 TMOUT_READING, /* waiting for input */ 260 TMOUT_LEAVING /* have timed out */ 261}; 262extern unsigned int ksh_tmout; 263extern enum tmout_enum ksh_tmout_state; 264 265/* For "You have stopped jobs" message */ 266extern int really_exit; 267 268/* 269 * fast character classes 270 */ 271#define C_ALPHA BIT(0) /* a-z_A-Z */ 272/* was C_DIGIT */ 273#define C_LEX1 BIT(2) /* \0 \t\n|&;<>() */ 274#define C_VAR1 BIT(3) /* *@#!$-? */ 275#define C_IFSWS BIT(4) /* \t \n (IFS white space) */ 276#define C_SUBOP1 BIT(5) /* "=-+?" */ 277#define C_SUBOP2 BIT(6) /* "#%" */ 278#define C_IFS BIT(7) /* $IFS */ 279#define C_QUOTE BIT(8) /* \n\t"#$&'()*;<>?[\`| (needing quoting) */ 280 281extern short ctypes []; 282 283#define ctype(c, t) !!(ctypes[(unsigned char)(c)]&(t)) 284#define letter(c) ctype(c, C_ALPHA) 285#define digit(c) isdigit((unsigned char)(c)) 286#define letnum(c) (ctype(c, C_ALPHA) || isdigit((unsigned char)(c))) 287 288extern int ifs0; /* for "$*" */ 289 290/* Argument parsing for built-in commands and getopts command */ 291 292/* Values for Getopt.flags */ 293#define GF_ERROR BIT(0) /* call errorf() if there is an error */ 294#define GF_PLUSOPT BIT(1) /* allow +c as an option */ 295#define GF_NONAME BIT(2) /* don't print argv[0] in errors */ 296 297/* Values for Getopt.info */ 298#define GI_MINUS BIT(0) /* an option started with -... */ 299#define GI_PLUS BIT(1) /* an option started with +... */ 300#define GI_MINUSMINUS BIT(2) /* arguments were ended with -- */ 301 302typedef struct { 303 int optind; 304 int uoptind;/* what user sees in $OPTIND */ 305 char *optarg; 306 int flags; /* see GF_* */ 307 int info; /* see GI_* */ 308 unsigned int p; /* 0 or index into argv[optind - 1] */ 309 char buf[2]; /* for bad option OPTARG value */ 310} Getopt; 311 312extern Getopt builtin_opt; /* for shell builtin commands */ 313extern Getopt user_opt; /* parsing state for getopts builtin command */ 314 315/* This for co-processes */ 316 317typedef int Coproc_id; /* something that won't (realistically) wrap */ 318struct coproc { 319 int read; /* pipe from co-process's stdout */ 320 int readw; /* other side of read (saved temporarily) */ 321 int write; /* pipe to co-process's stdin */ 322 Coproc_id id; /* id of current output pipe */ 323 int njobs; /* number of live jobs using output pipe */ 324 void *job; /* 0 or job of co-process using input pipe */ 325}; 326extern struct coproc coproc; 327 328/* Used in jobs.c and by coprocess stuff in exec.c */ 329extern sigset_t sm_default, sm_sigchld; 330 331extern const char ksh_version[]; 332 333/* name of called builtin function (used by error functions) */ 334extern char *builtin_argv0; 335extern int builtin_flag; /* flags of called builtin (SPEC_BI, etc.) */ 336 337/* current working directory, and size of memory allocated for same */ 338extern char *current_wd; 339extern int current_wd_size; 340 341/* Minimum required space to work with on a line - if the prompt leaves less 342 * space than this on a line, the prompt is truncated. 343 */ 344#define MIN_EDIT_SPACE 7 345/* Minimum allowed value for x_cols: 2 for prompt, 3 for " < " at end of line 346 */ 347#define MIN_COLS (2 + MIN_EDIT_SPACE + 3) 348extern int x_cols; /* tty columns */ 349 350/* These to avoid bracket matching problems */ 351#define OPAREN '(' 352#define CPAREN ')' 353#define OBRACK '[' 354#define CBRACK ']' 355#define OBRACE '{' 356#define CBRACE '}' 357 358/* Determine the location of the system (common) profile */ 359#define KSH_SYSTEM_PROFILE "/etc/profile" 360 361/* Used by v_evaluate() and setstr() to control action when error occurs */ 362#define KSH_UNWIND_ERROR 0x0 /* unwind the stack (longjmp) */ 363#define KSH_RETURN_ERROR 0x1 /* return 1/0 for success/failure */ 364#define KSH_IGNORE_RDONLY 0x4 /* ignore the read-only flag */ 365 366#include "shf.h" 367#include "table.h" 368#include "tree.h" 369#include "expand.h" 370#include "lex.h" 371 372/* alloc.c */ 373Area * ainit(Area *); 374void afreeall(Area *); 375void * alloc(size_t, Area *); 376void * areallocarray(void *, size_t, size_t, Area *); 377void * aresize(void *, size_t, Area *); 378void afree(void *, Area *); 379/* c_ksh.c */ 380int c_cd(char **); 381int c_pwd(char **); 382int c_print(char **); 383int c_whence(char **); 384int c_command(char **); 385int c_type(char **); 386int c_typeset(char **); 387int c_alias(char **); 388int c_unalias(char **); 389int c_let(char **); 390int c_jobs(char **); 391int c_fgbg(char **); 392int c_kill(char **); 393void getopts_reset(int); 394int c_getopts(char **); 395int c_bind(char **); 396/* c_sh.c */ 397int c_label(char **); 398int c_shift(char **); 399int c_umask(char **); 400int c_dot(char **); 401int c_wait(char **); 402int c_read(char **); 403int c_eval(char **); 404int c_trap(char **); 405int c_brkcont(char **); 406int c_exitreturn(char **); 407int c_set(char **); 408int c_unset(char **); 409int c_ulimit(char **); 410int c_times(char **); 411int timex(struct op *, int, volatile int *); 412void timex_hook(struct op *, char ** volatile *); 413int c_exec(char **); 414int c_builtin(char **); 415/* c_test.c */ 416int c_test(char **); 417/* edit.c: most prototypes in edit.h */ 418void x_init(void); 419int x_read(char *, size_t); 420void set_editmode(const char *); 421/* emacs.c: most prototypes in edit.h */ 422int x_bind(const char *, const char *, int, int); 423/* eval.c */ 424char * substitute(const char *, int); 425char ** eval(char **, int); 426char * evalstr(char *cp, int); 427char * evalonestr(char *cp, int); 428char *debunk(char *, const char *, size_t); 429void expand(char *, XPtrV *, int); 430int glob_str(char *, XPtrV *, int); 431/* exec.c */ 432int execute(struct op * volatile, volatile int, volatile int *); 433int shcomexec(char **); 434struct tbl * findfunc(const char *, unsigned int, int); 435int define(const char *, struct op *); 436void builtin(const char *, int (*)(char **)); 437struct tbl * findcom(const char *, int); 438void flushcom(int); 439char * search(const char *, const char *, int, int *); 440int search_access(const char *, int, int *); 441int pr_menu(char *const *); 442int pr_list(char *const *); 443/* expr.c */ 444int evaluate(const char *, int64_t *, int, bool); 445int v_evaluate(struct tbl *, const char *, volatile int, bool); 446/* history.c */ 447void init_histvec(void); 448void hist_init(Source *); 449void hist_finish(void); 450void histsave(int, const char *, int); 451int c_fc(char **); 452void c_fc_reset(void); 453void sethistcontrol(const char *); 454void sethistsize(int); 455void sethistfile(const char *); 456char ** histpos(void); 457int histnum(int); 458int findhist(int, int, const char *, int); 459int findhistrel(const char *); 460char **hist_get_newest(int); 461 462/* io.c */ 463void errorf(const char *, ...) 464 __attribute__((__noreturn__, __format__ (printf, 1, 2))); 465void warningf(bool, const char *, ...) 466 __attribute__((__format__ (printf, 2, 3))); 467void bi_errorf(const char *, ...) 468 __attribute__((__format__ (printf, 1, 2))); 469void internal_errorf(const char *, ...) 470 __attribute__((__noreturn__, __format__ (printf, 1, 2))); 471void internal_warningf(const char *, ...) 472 __attribute__((__format__ (printf, 1, 2))); 473void error_prefix(int); 474void shellf(const char *, ...) 475 __attribute__((__format__ (printf, 1, 2))); 476void shprintf(const char *, ...) 477 __attribute__((__format__ (printf, 1, 2))); 478#ifdef KSH_DEBUG 479void kshdebug_init_(void); 480void kshdebug_printf_(const char *, ...) 481 __attribute__((__format__ (printf, 1, 2))); 482void kshdebug_dump_(const char *, const void *, int); 483#endif /* KSH_DEBUG */ 484int can_seek(int); 485void initio(void); 486int ksh_dup2(int, int, int); 487int savefd(int); 488void restfd(int, int); 489void openpipe(int *); 490void closepipe(int *); 491int check_fd(char *, int, const char **); 492void coproc_init(void); 493void coproc_read_close(int); 494void coproc_readw_close(int); 495void coproc_write_close(int); 496int coproc_getfd(int, const char **); 497void coproc_cleanup(int); 498struct temp *maketemp(Area *, Temp_type, struct temp **); 499/* jobs.c */ 500void j_init(int); 501void j_suspend(void); 502void j_exit(void); 503void j_change(void); 504int exchild(struct op *, int, volatile int *, int); 505void startlast(void); 506int waitlast(void); 507int waitfor(const char *, int *); 508int j_kill(const char *, int); 509int j_resume(const char *, int); 510int j_jobs(const char *, int, int); 511int j_njobs(void); 512void j_notify(void); 513pid_t j_async(void); 514int j_stopped_running(void); 515/* mail.c */ 516void mcheck(void); 517void mcset(int64_t); 518void mbset(char *); 519void mpset(char *); 520/* main.c */ 521int include(const char *, int, char **, int); 522int command(const char *, int); 523int shell(Source *volatile, int volatile); 524void unwind(int) __attribute__((__noreturn__)); 525void newenv(int); 526void quitenv(struct shf *); 527void cleanup_parents_env(void); 528void cleanup_proc_env(void); 529/* misc.c */ 530void setctypes(const char *, int); 531void initctypes(void); 532char * u64ton(uint64_t, int); 533char * str_save(const char *, Area *); 534char * str_nsave(const char *, int, Area *); 535int option(const char *); 536char * getoptions(void); 537void change_flag(enum sh_flag, int, int); 538int parse_args(char **, int, int *); 539int getn(const char *, int *); 540int bi_getn(const char *, int *); 541int gmatch(const char *, const char *, int); 542int has_globbing(const char *, const char *); 543const unsigned char *pat_scan(const unsigned char *, const unsigned char *, 544 int); 545void qsortp(void **, size_t, int (*)(const void *, const void *)); 546int xstrcmp(const void *, const void *); 547void ksh_getopt_reset(Getopt *, int); 548int ksh_getopt(char **, Getopt *, const char *); 549void print_value_quoted(const char *); 550void print_columns(struct shf *, int, char *(*)(void *, int, char *, int), 551 void *, int, int prefcol); 552int strip_nuls(char *, int); 553int blocking_read(int, char *, int); 554int reset_nonblock(int); 555char *ksh_get_wd(char *, int); 556/* path.c */ 557int make_path(const char *, const char *, char **, XString *, int *); 558void simplify_path(char *); 559char *get_phys_path(const char *); 560void set_current_wd(char *); 561/* syn.c */ 562void initkeywords(void); 563struct op * compile(Source *); 564/* trap.c */ 565void inittraps(void); 566void alarm_init(void); 567Trap * gettrap(const char *, int); 568void trapsig(int); 569void intrcheck(void); 570int fatal_trap_check(void); 571int trap_pending(void); 572void runtraps(int intr); 573void runtrap(Trap *); 574void cleartraps(void); 575void restoresigs(void); 576void settrap(Trap *, char *); 577int block_pipe(void); 578void restore_pipe(int); 579int setsig(Trap *, sig_t, int); 580void setexecsig(Trap *, int); 581/* var.c */ 582void newblock(void); 583void popblock(void); 584void initvar(void); 585struct tbl * global(const char *); 586struct tbl * local(const char *, bool); 587char * str_val(struct tbl *); 588int64_t intval(struct tbl *); 589int setstr(struct tbl *, const char *, int); 590struct tbl *setint_v(struct tbl *, struct tbl *, bool); 591void setint(struct tbl *, int64_t); 592int getint(struct tbl *, int64_t *, bool); 593struct tbl *typeset(const char *, int, int, int, int); 594void unset(struct tbl *, int); 595char * skip_varname(const char *, int); 596char *skip_wdvarname(const char *, int); 597int is_wdvarname(const char *, int); 598int is_wdvarassign(const char *); 599char ** makenv(void); 600void change_random(void); 601int array_ref_len(const char *); 602char * arrayname(const char *); 603void set_array(const char *, int, char **); 604/* vi.c: see edit.h */ 605