1 /* $NetBSD: sh.h,v 1.35 2017/06/30 04:44:46 kamil Exp $ */ 2 3 /* 4 * Public Domain Bourne/Korn shell 5 */ 6 7 /* $Id: sh.h,v 1.35 2017/06/30 04:44:46 kamil Exp $ */ 8 9 #include "config.h" /* system and option configuration info */ 10 11 #define ARGS(args) args /* prototype declaration */ 12 13 /* Start of common headers */ 14 15 #include <stdio.h> 16 #include <sys/types.h> 17 #include <setjmp.h> 18 #include <stddef.h> 19 #include <stdlib.h> 20 #include <unistd.h> 21 #include <string.h> 22 #include <stdarg.h> 23 #include <errno.h> 24 #include <fcntl.h> 25 #include <stdint.h> 26 27 #ifndef O_ACCMODE 28 # define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR) 29 #endif /* !O_ACCMODE */ 30 31 #ifndef F_OK /* access() arguments */ 32 # define F_OK 0 33 # define X_OK 1 34 # define W_OK 2 35 # define R_OK 4 36 #endif /* !F_OK */ 37 38 #ifndef SEEK_SET 39 # ifdef L_SET 40 # define SEEK_SET L_SET 41 # define SEEK_CUR L_INCR 42 # define SEEK_END L_XTND 43 # else /* L_SET */ 44 # define SEEK_SET 0 45 # define SEEK_CUR 1 46 # define SEEK_END 2 47 # endif /* L_SET */ 48 #endif /* !SEEK_SET */ 49 50 #include <limits.h> 51 52 #include <signal.h> 53 #ifdef NSIG 54 # define SIGNALS NSIG 55 #else 56 # ifdef _MINIX 57 # define SIGNALS (_NSIG+1) /* _NSIG is # of signals used, excluding 0. */ 58 # else 59 # ifdef _SIGMAX /* QNX */ 60 # define SIGNALS _SIGMAX 61 # else /* _SIGMAX */ 62 # define SIGNALS 32 63 # endif /* _SIGMAX */ 64 # endif /* _MINIX */ 65 #endif /* NSIG */ 66 #ifndef SIGCHLD 67 # define SIGCHLD SIGCLD 68 #endif 69 /* struct sigaction.sa_flags is set to KSH_SA_FLAGS. Used to ensure 70 * system calls are interrupted 71 */ 72 #ifdef SA_INTERRUPT 73 # define KSH_SA_FLAGS SA_INTERRUPT 74 #else /* SA_INTERRUPT */ 75 # define KSH_SA_FLAGS 0 76 #endif /* SA_INTERRUPT */ 77 78 typedef RETSIGTYPE (*handler_t) ARGS((int)); /* signal handler */ 79 80 #ifdef HAVE_PATHS_H 81 # include <paths.h> 82 #endif /* HAVE_PATHS_H */ 83 #ifdef _PATH_DEFPATH 84 # define DEFAULT__PATH _PATH_DEFPATH 85 #else /* _PATH_DEFPATH */ 86 # define DEFAULT__PATH DEFAULT_PATH 87 #endif /* _PATH_DEFPATH */ 88 89 #ifndef HAVE_KILLPG 90 # define killpg(p, s) kill(-(p), (s)) 91 #endif /* !HAVE_KILLPG */ 92 93 /* this is a hang-over from older versions of the os2 port */ 94 #define ksh_dupbase(fd, base) fcntl(fd, F_DUPFD, base) 95 96 #ifdef HAVE_SIGSETJMP 97 # define ksh_sigsetjmp(env,sm) sigsetjmp((env), (sm)) 98 # define ksh_siglongjmp(env,v) siglongjmp((env), (v)) 99 # define ksh_jmp_buf sigjmp_buf 100 #else /* HAVE_SIGSETJMP */ 101 # ifdef HAVE__SETJMP 102 # define ksh_sigsetjmp(env,sm) _setjmp(env) 103 # define ksh_siglongjmp(env,v) _longjmp((env), (v)) 104 # else /* HAVE__SETJMP */ 105 # define ksh_sigsetjmp(env,sm) setjmp(env) 106 # define ksh_siglongjmp(env,v) longjmp((env), (v)) 107 # endif /* HAVE__SETJMP */ 108 # define ksh_jmp_buf jmp_buf 109 #endif /* HAVE_SIGSETJMP */ 110 111 /* end of common headers */ 112 113 /* Stop gcc and lint from complaining about possibly uninitialized variables */ 114 #if defined(__GNUC__) || defined(lint) 115 # define UNINITIALIZED(var) var = 0 116 #else 117 # define UNINITIALIZED(var) var 118 #endif /* GNUC || lint */ 119 120 /* some useful #defines */ 121 #ifdef EXTERN 122 # define I__(i) = i 123 #else 124 # define I__(i) 125 # define EXTERN extern 126 # define EXTERN_DEFINED 127 #endif 128 129 #ifndef EXECSHELL 130 /* shell to exec scripts (see also $SHELL initialization in main.c) */ 131 # define EXECSHELL "/bin/sh" 132 # define EXECSHELL_STR "EXECSHELL" 133 #endif 134 135 /* ISABSPATH() means path is fully and completely specified, 136 * ISROOTEDPATH() means a .. as the first component is a no-op, 137 * ISRELPATH() means $PWD can be tacked on to get an absolute path. 138 * 139 * OS Path ISABSPATH ISROOTEDPATH ISRELPATH 140 * unix /foo yes yes no 141 * unix foo no no yes 142 * unix ../foo no no yes 143 */ 144 # define PATHSEP ':' 145 # define DIRSEP '/' 146 # define DIRSEPSTR "/" 147 # define ISDIRSEP(c) ((c) == '/') 148 # define ISABSPATH(s) ISDIRSEP((s)[0]) 149 # define ISRELPATH(s) (!ISABSPATH(s)) 150 # define ISROOTEDPATH(s) ISABSPATH(s) 151 # define FILECHCONV(c) c 152 # define FILECMP(s1, s2) strcmp(s1, s2) 153 # define FILENCMP(s1, s2, n) strncmp(s1, s2, n) 154 # define ksh_strchr_dirsep(p) strchr(p, DIRSEP) 155 # define ksh_strrchr_dirsep(p) strrchr(p, DIRSEP) 156 157 #define NELEM(a) (sizeof(a) / sizeof((a)[0])) 158 #define sizeofN(type, n) (sizeof(type) * (n)) 159 #define BIT(i) (1<<(i)) /* define bit in flag */ 160 161 /* Table flag type - needs > 16 and < 32 bits */ 162 typedef int_least32_t Tflag; 163 164 #define NUFILE 32 /* Number of user-accessible files */ 165 #define FDBASE 10 /* First file usable by Shell */ 166 167 /* you're not going to run setuid shell scripts, are you? */ 168 #define eaccess(path, mode) access(path, mode) 169 170 /* Make MAGIC a char that might be printed to make bugs more obvious, but 171 * not a char that is used often. Also, can't use the high bit as it causes 172 * portability problems (calling strchr(x, 0x80|'x') is error prone). 173 */ 174 #define MAGIC (7) /* prefix for *?[!{,} during expand */ 175 #define ISMAGIC(c) ((unsigned char)(c) == MAGIC) 176 #define NOT '!' /* might use ^ (ie, [!...] vs [^..]) */ 177 178 #define LINE 1024 /* input line size */ 179 #define PATH 1024 /* pathname size (todo: PATH_MAX/pathconf()) */ 180 #define ARRAYMAX 1023 /* max array index */ 181 182 EXTERN const char *kshname; /* $0 */ 183 EXTERN pid_t kshpid; /* $$, shell pid */ 184 EXTERN pid_t procpid; /* pid of executing process */ 185 EXTERN uid_t ksheuid; /* effective uid of shell */ 186 EXTERN int exstat; /* exit status */ 187 EXTERN int subst_exstat; /* exit status of last $(..)/`..` */ 188 EXTERN const char *safe_prompt; /* safe prompt if PS1 substitution fails */ 189 190 /* 191 * Area-based allocation built on malloc/free 192 */ 193 typedef struct Area { 194 struct link *freelist; /* free list */ 195 } Area; 196 197 EXTERN Area aperm; /* permanent object space */ 198 #define APERM &aperm 199 #define ATEMP &e->area 200 201 #ifdef KSH_DEBUG 202 # define kshdebug_init() kshdebug_init_() 203 # define kshdebug_printf(a) kshdebug_printf_ a 204 # define kshdebug_dump(a) kshdebug_dump_ a 205 #else /* KSH_DEBUG */ 206 # define kshdebug_init() 207 # define kshdebug_printf(a) 208 # define kshdebug_dump(a) 209 #endif /* KSH_DEBUG */ 210 211 /* 212 * parsing & execution environment 213 */ 214 EXTERN struct env { 215 short type; /* environment type - see below */ 216 short flags; /* EF_* */ 217 Area area; /* temporary allocation area */ 218 struct block *loc; /* local variables and functions */ 219 short *savefd; /* original redirected fd's */ 220 struct env *oenv; /* link to previous environment */ 221 ksh_jmp_buf jbuf; /* long jump back to env creator */ 222 struct temp *temps; /* temp files */ 223 } *e; 224 225 /* struct env.type values */ 226 #define E_NONE 0 /* dummy environment */ 227 #define E_PARSE 1 /* parsing command # */ 228 #define E_FUNC 2 /* executing function # */ 229 #define E_INCL 3 /* including a file via . # */ 230 #define E_EXEC 4 /* executing command tree */ 231 #define E_LOOP 5 /* executing for/while # */ 232 #define E_ERRH 6 /* general error handler # */ 233 /* # indicates env has valid jbuf (see unwind()) */ 234 235 /* struct env.flag values */ 236 #define EF_FUNC_PARSE BIT(0) /* function being parsed */ 237 #define EF_BRKCONT_PASS BIT(1) /* set if E_LOOP must pass break/continue on */ 238 #define EF_FAKE_SIGDIE BIT(2) /* hack to get info from unwind to quitenv */ 239 240 /* Do breaks/continues stop at env type e? */ 241 #define STOP_BRKCONT(t) ((t) == E_NONE || (t) == E_PARSE \ 242 || (t) == E_FUNC || (t) == E_INCL) 243 /* Do returns stop at env type e? */ 244 #define STOP_RETURN(t) ((t) == E_FUNC || (t) == E_INCL) 245 246 /* values for ksh_siglongjmp(e->jbuf, 0) */ 247 #define LRETURN 1 /* return statement */ 248 #define LEXIT 2 /* exit statement */ 249 #define LERROR 3 /* errorf() called */ 250 #define LLEAVE 4 /* untrappable exit/error */ 251 #define LINTR 5 /* ^C noticed */ 252 #define LBREAK 6 /* break statement */ 253 #define LCONTIN 7 /* continue statement */ 254 #define LSHELL 8 /* return to interactive shell() */ 255 #define LAEXPR 9 /* error in arithmetic expression */ 256 257 /* option processing */ 258 #define OF_CMDLINE 0x01 /* command line */ 259 #define OF_SET 0x02 /* set builtin */ 260 #define OF_SPECIAL 0x04 /* a special variable changing */ 261 #define OF_INTERNAL 0x08 /* set internally by shell */ 262 #define OF_ANY (OF_CMDLINE | OF_SET | OF_SPECIAL | OF_INTERNAL) 263 264 struct option { 265 const char *name; /* long name of option */ 266 char c; /* character flag (if any) */ 267 short flags; /* OF_* */ 268 }; 269 extern const struct option goptions[]; 270 271 /* 272 * flags (the order of these enums MUST match the order in misc.c(options[])) 273 */ 274 enum sh_flag { 275 FEXPORT = 0, /* -a: export all */ 276 #ifdef BRACE_EXPAND 277 FBRACEEXPAND, /* enable {} globbing */ 278 #endif 279 FBGNICE, /* bgnice */ 280 FCOMMAND, /* -c: (invocation) execute specified command */ 281 #ifdef EMACS 282 FEMACS, /* emacs command editing */ 283 FEMACSUSEMETA, /* use 8th bit as meta */ 284 #endif 285 FERREXIT, /* -e: quit on error */ 286 #ifdef EMACS 287 FGMACS, /* gmacs command editing */ 288 #endif 289 FIGNOREEOF, /* eof does not exit */ 290 FTALKING, /* -i: interactive */ 291 FKEYWORD, /* -k: name=value anywhere */ 292 FLOGIN, /* -l: a login shell */ 293 FMARKDIRS, /* mark dirs with / in file name completion */ 294 FMONITOR, /* -m: job control monitoring */ 295 FNOCLOBBER, /* -C: don't overwrite existing files */ 296 FNOEXEC, /* -n: don't execute any commands */ 297 FNOGLOB, /* -f: don't do file globbing */ 298 FNOHUP, /* -H: don't kill running jobs when login shell exits */ 299 FNOLOG, /* don't save functions in history (ignored) */ 300 #ifdef JOBS 301 FNOTIFY, /* -b: asynchronous job completion notification */ 302 #endif 303 FNOUNSET, /* -u: using an unset var is an error */ 304 FPHYSICAL, /* -o physical: don't do logical cd's/pwd's */ 305 FPOSIX, /* -o posix: be posixly correct */ 306 FPRIVILEGED, /* -p: use suid_profile */ 307 FRESTRICTED, /* -r: restricted shell */ 308 FSTDIN, /* -s: (invocation) parse stdin */ 309 FTRACKALL, /* -h: create tracked aliases for all commands */ 310 FVERBOSE, /* -v: echo input */ 311 #ifdef VI 312 FVI, /* vi command editing */ 313 FVIRAW, /* always read in raw mode (ignored) */ 314 FVISHOW8, /* display chars with 8th bit set as is (versus M-) */ 315 FVITABCOMPLETE, /* enable tab as file name completion char */ 316 FVIESCCOMPLETE, /* enable ESC as file name completion in command mode */ 317 #endif 318 FXTRACE, /* -x: execution trace */ 319 FTALKING_I, /* (internal): initial shell was interactive */ 320 FNFLAGS /* (place holder: how many flags are there) */ 321 }; 322 323 #define Flag(f) (shell_flags[(int) (f)]) 324 325 EXTERN char shell_flags [FNFLAGS]; 326 327 EXTERN char null [] I__(""); /* null value for variable */ 328 EXTERN char space [] I__(" "); 329 EXTERN char newline [] I__("\n"); 330 EXTERN char slash [] I__("/"); 331 332 enum temp_type { 333 TT_HEREDOC_EXP, /* expanded heredoc */ 334 TT_HIST_EDIT /* temp file used for history editing (fc -e) */ 335 }; 336 typedef enum temp_type Temp_type; 337 /* temp/heredoc files. The file is removed when the struct is freed. */ 338 struct temp { 339 struct temp *next; 340 struct shf *shf; 341 int pid; /* pid of process parsed here-doc */ 342 Temp_type type; 343 char *name; 344 }; 345 346 /* 347 * stdio and our IO routines 348 */ 349 350 #define shl_spare (&shf_iob[0]) /* for c_read()/c_print() */ 351 #define shl_stdout (&shf_iob[1]) 352 #define shl_out (&shf_iob[2]) 353 EXTERN int shl_stdout_ok; 354 355 /* 356 * trap handlers 357 */ 358 typedef struct trap { 359 int signal; /* signal number */ 360 const char *name; /* short name */ 361 const char *mess; /* descriptive name */ 362 char *trap; /* trap command */ 363 int volatile set; /* trap pending */ 364 int flags; /* TF_* */ 365 handler_t cursig; /* current handler (valid if TF_ORIG_* set) */ 366 handler_t shtrap; /* shell signal handler */ 367 } Trap; 368 369 /* values for Trap.flags */ 370 #define TF_SHELL_USES BIT(0) /* shell uses signal, user can't change */ 371 #define TF_USER_SET BIT(1) /* user has (tried to) set trap */ 372 #define TF_ORIG_IGN BIT(2) /* original action was SIG_IGN */ 373 #define TF_ORIG_DFL BIT(3) /* original action was SIG_DFL */ 374 #define TF_EXEC_IGN BIT(4) /* restore SIG_IGN just before exec */ 375 #define TF_EXEC_DFL BIT(5) /* restore SIG_DFL just before exec */ 376 #define TF_DFL_INTR BIT(6) /* when received, default action is LINTR */ 377 #define TF_TTY_INTR BIT(7) /* tty generated signal (see j_waitj) */ 378 #define TF_CHANGED BIT(8) /* used by runtrap() to detect trap changes */ 379 #define TF_FATAL BIT(9) /* causes termination if not trapped */ 380 381 /* values for setsig()/setexecsig() flags argument */ 382 #define SS_RESTORE_MASK 0x3 /* how to restore a signal before an exec() */ 383 #define SS_RESTORE_CURR 0 /* leave current handler in place */ 384 #define SS_RESTORE_ORIG 1 /* restore original handler */ 385 #define SS_RESTORE_DFL 2 /* restore to SIG_DFL */ 386 #define SS_RESTORE_IGN 3 /* restore to SIG_IGN */ 387 #define SS_FORCE BIT(3) /* set signal even if original signal ignored */ 388 #define SS_USER BIT(4) /* user is doing the set (ie, trap command) */ 389 #define SS_SHTRAP BIT(5) /* trap for internal use (CHLD,ALRM,WINCH) */ 390 391 #define SIGEXIT_ 0 /* for trap EXIT */ 392 #define SIGERR_ SIGNALS /* for trap ERR */ 393 394 EXTERN int volatile trap; /* traps pending? */ 395 EXTERN int volatile intrsig; /* pending trap interrupts executing command */ 396 EXTERN int volatile fatal_trap;/* received a fatal signal */ 397 extern Trap sigtraps[SIGNALS+1]; 398 399 #ifdef KSH 400 /* 401 * TMOUT support 402 */ 403 /* values for ksh_tmout_state */ 404 enum tmout_enum { 405 TMOUT_EXECUTING = 0, /* executing commands */ 406 TMOUT_READING, /* waiting for input */ 407 TMOUT_LEAVING /* have timed out */ 408 }; 409 EXTERN unsigned int ksh_tmout; 410 EXTERN enum tmout_enum ksh_tmout_state I__(TMOUT_EXECUTING); 411 #endif /* KSH */ 412 413 /* For "You have stopped jobs" message */ 414 EXTERN int really_exit; 415 416 /* 417 * fast character classes 418 */ 419 #define C_ALPHA BIT(0) /* a-z_A-Z */ 420 #define C_DIGIT BIT(1) /* 0-9 */ 421 #define C_LEX1 BIT(2) /* \0 \t\n|&;<>() */ 422 #define C_VAR1 BIT(3) /* *@#!$-? */ 423 #define C_IFSWS BIT(4) /* \t \n (IFS white space) */ 424 #define C_SUBOP1 BIT(5) /* "=-+?" */ 425 #define C_SUBOP2 BIT(6) /* "#%" */ 426 #define C_IFS BIT(7) /* $IFS */ 427 #define C_QUOTE BIT(8) /* \n\t"#$&'()*;<>?[\`| (needing quoting) */ 428 429 extern short ctypes []; 430 431 #define ctype(c, t) !!(ctypes[(unsigned char)(c)]&(t)) 432 #define letter(c) ctype(c, C_ALPHA) 433 #define digit(c) ctype(c, C_DIGIT) 434 #define letnum(c) ctype(c, C_ALPHA|C_DIGIT) 435 436 EXTERN int ifs0 I__(' '); /* for "$*" */ 437 438 /* Argument parsing for built-in commands and getopts command */ 439 440 /* Values for Getopt.flags */ 441 #define GF_ERROR BIT(0) /* call errorf() if there is an error */ 442 #define GF_PLUSOPT BIT(1) /* allow +c as an option */ 443 #define GF_NONAME BIT(2) /* don't print argv[0] in errors */ 444 445 /* Values for Getopt.info */ 446 #define GI_MINUS BIT(0) /* an option started with -... */ 447 #define GI_PLUS BIT(1) /* an option started with +... */ 448 #define GI_MINUSMINUS BIT(2) /* arguments were ended with -- */ 449 450 typedef struct { 451 int optind; 452 int uoptind;/* what user sees in $OPTIND */ 453 char *optarg; 454 int flags; /* see GF_* */ 455 int info; /* see GI_* */ 456 unsigned int p; /* 0 or index into argv[optind - 1] */ 457 char buf[2]; /* for bad option OPTARG value */ 458 } Getopt; 459 460 EXTERN Getopt builtin_opt; /* for shell builtin commands */ 461 EXTERN Getopt user_opt; /* parsing state for getopts builtin command */ 462 463 #ifdef KSH 464 /* This for co-processes */ 465 466 typedef int_least32_t Coproc_id; /* something that won't (realisticly) wrap */ 467 struct coproc { 468 int read; /* pipe from co-process's stdout */ 469 int readw; /* other side of read (saved temporarily) */ 470 int write; /* pipe to co-process's stdin */ 471 Coproc_id id; /* id of current output pipe */ 472 int njobs; /* number of live jobs using output pipe */ 473 void *job; /* 0 or job of co-process using input pipe */ 474 }; 475 EXTERN struct coproc coproc; 476 #endif /* KSH */ 477 478 /* Used in jobs.c and by coprocess stuff in exec.c */ 479 EXTERN sigset_t sm_default, sm_sigchld; 480 481 extern char ksh_version[]; 482 483 /* name of called builtin function (used by error functions) */ 484 EXTERN char *builtin_argv0; 485 EXTERN Tflag builtin_flag; /* flags of called builtin (SPEC_BI, etc.) */ 486 487 /* current working directory, and size of memory allocated for same */ 488 EXTERN char *current_wd; 489 EXTERN int current_wd_size; 490 491 #ifdef EDIT 492 /* Minimum required space to work with on a line - if the prompt leaves less 493 * space than this on a line, the prompt is truncated. 494 */ 495 # define MIN_EDIT_SPACE 7 496 /* Minimum allowed value for x_cols: 2 for prompt, 3 for " < " at end of line 497 */ 498 # define MIN_COLS (2 + MIN_EDIT_SPACE + 3) 499 EXTERN int x_cols I__(80); /* tty columns */ 500 #else 501 # define x_cols 80 /* for pr_menu(exec.c) */ 502 #endif 503 504 /* These to avoid bracket matching problems */ 505 #define OPAREN '(' 506 #define CPAREN ')' 507 #define OBRACK '[' 508 #define CBRACK ']' 509 #define OBRACE '{' 510 #define CBRACE '}' 511 512 /* Determine the location of the system (common) profile */ 513 #ifndef KSH_SYSTEM_PROFILE 514 # define KSH_SYSTEM_PROFILE "/etc/profile" 515 #endif /* KSH_SYSTEM_PROFILE */ 516 517 /* Used by v_evaluate() and setstr() to control action when error occurs */ 518 #define KSH_UNWIND_ERROR 0 /* unwind the stack (longjmp) */ 519 #define KSH_RETURN_ERROR 1 /* return 1/0 for success/failure */ 520 521 #include "shf.h" 522 #include "table.h" 523 #include "tree.h" 524 #include "expand.h" 525 #include "lex.h" 526 #include "proto.h" 527 528 /* be sure not to interfere with anyone else's idea about EXTERN */ 529 #ifdef EXTERN_DEFINED 530 # undef EXTERN_DEFINED 531 # undef EXTERN 532 #endif 533 #undef I__ 534