1 /* $OpenBSD: sh.h,v 1.30 2010/01/04 18:07:11 deraadt Exp $ */ 2 /* $OpenBSD: shf.h,v 1.6 2005/12/11 18:53:51 deraadt Exp $ */ 3 /* $OpenBSD: table.h,v 1.7 2005/12/11 20:31:21 otto Exp $ */ 4 /* $OpenBSD: tree.h,v 1.10 2005/03/28 21:28:22 deraadt Exp $ */ 5 /* $OpenBSD: expand.h,v 1.6 2005/03/30 17:16:37 deraadt Exp $ */ 6 /* $OpenBSD: lex.h,v 1.11 2006/05/29 18:22:24 otto Exp $ */ 7 /* $OpenBSD: proto.h,v 1.33 2010/05/19 17:36:08 jasper Exp $ */ 8 /* $OpenBSD: c_test.h,v 1.4 2004/12/20 11:34:26 otto Exp $ */ 9 /* $OpenBSD: tty.h,v 1.5 2004/12/20 11:34:26 otto Exp $ */ 10 11 /*- 12 * Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 13 * Thorsten Glaser <tg@mirbsd.org> 14 * 15 * Provided that these terms and disclaimer and all copyright notices 16 * are retained or reproduced in an accompanying document, permission 17 * is granted to deal in this work without restriction, including un‐ 18 * limited rights to use, publicly perform, distribute, sell, modify, 19 * merge, give away, or sublicence. 20 * 21 * This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to 22 * the utmost extent permitted by applicable law, neither express nor 23 * implied; without malicious intent or gross negligence. In no event 24 * may a licensor, author or contributor be held liable for indirect, 25 * direct, other damage, loss, or other issues arising in any way out 26 * of dealing in the work, even if advised of the possibility of such 27 * damage or existence of a defect, except proven that it results out 28 * of said person’s immediate fault when using the work as intended. 29 */ 30 31 #ifdef __dietlibc__ 32 /* XXX imake style */ 33 #define _BSD_SOURCE /* live, BSD, live❣ */ 34 #endif 35 36 #if HAVE_SYS_PARAM_H 37 #include <sys/param.h> 38 #endif 39 #include <sys/types.h> 40 #include <sys/time.h> 41 #include <sys/ioctl.h> 42 #if HAVE_SYS_SYSMACROS_H 43 #include <sys/sysmacros.h> 44 #endif 45 #if HAVE_SYS_MKDEV_H 46 #include <sys/mkdev.h> 47 #endif 48 #if HAVE_SYS_MMAN_H 49 #include <sys/mman.h> 50 #endif 51 #include <sys/resource.h> 52 #include <sys/stat.h> 53 #include <sys/wait.h> 54 #include <dirent.h> 55 #include <errno.h> 56 #include <fcntl.h> 57 #if HAVE_LIBGEN_H 58 #include <libgen.h> 59 #endif 60 #if HAVE_LIBUTIL_H 61 #include <libutil.h> 62 #endif 63 #include <limits.h> 64 #if HAVE_PATHS_H 65 #include <paths.h> 66 #endif 67 #include <pwd.h> 68 #include <setjmp.h> 69 #include <signal.h> 70 #include <stdarg.h> 71 #include <stddef.h> 72 #if HAVE_STDINT_H 73 #include <stdint.h> 74 #endif 75 #include <stdio.h> 76 #include <stdlib.h> 77 #include <string.h> 78 #if HAVE_STRINGS_H 79 #include <strings.h> 80 #endif 81 #include <termios.h> 82 #include <time.h> 83 #if HAVE_ULIMIT_H 84 #include <ulimit.h> 85 #endif 86 #include <unistd.h> 87 #if HAVE_VALUES_H 88 #include <values.h> 89 #endif 90 91 #undef __attribute__ 92 #if HAVE_ATTRIBUTE_BOUNDED 93 #define MKSH_A_BOUNDED(x,y,z) __attribute__((__bounded__ (x, y, z))) 94 #else 95 #define MKSH_A_BOUNDED(x,y,z) /* nothing */ 96 #endif 97 #if HAVE_ATTRIBUTE_FORMAT 98 #define MKSH_A_FORMAT(x,y,z) __attribute__((__format__ (x, y, z))) 99 #else 100 #define MKSH_A_FORMAT(x,y,z) /* nothing */ 101 #endif 102 #if HAVE_ATTRIBUTE_NONNULL 103 #define MKSH_A_NONNULL(a) __attribute__(a) 104 #else 105 #define MKSH_A_NONNULL(a) /* nothing */ 106 #endif 107 #if HAVE_ATTRIBUTE_NORETURN 108 #define MKSH_A_NORETURN __attribute__((__noreturn__)) 109 #else 110 #define MKSH_A_NORETURN /* nothing */ 111 #endif 112 #if HAVE_ATTRIBUTE_UNUSED 113 #define MKSH_A_UNUSED __attribute__((__unused__)) 114 #else 115 #define MKSH_A_UNUSED /* nothing */ 116 #endif 117 #if HAVE_ATTRIBUTE_USED 118 #define MKSH_A_USED __attribute__((__used__)) 119 #else 120 #define MKSH_A_USED /* nothing */ 121 #endif 122 123 #if defined(MirBSD) && (MirBSD >= 0x09A1) && \ 124 defined(__ELF__) && defined(__GNUC__) && \ 125 !defined(__llvm__) && !defined(__NWCC__) 126 /* 127 * We got usable __IDSTRING __COPYRIGHT __RCSID __SCCSID macros 128 * which work for all cases; no need to redefine them using the 129 * "portable" macros from below when we might have the "better" 130 * gcc+ELF specific macros or other system dependent ones. 131 */ 132 #else 133 #undef __IDSTRING 134 #undef __IDSTRING_CONCAT 135 #undef __IDSTRING_EXPAND 136 #undef __COPYRIGHT 137 #undef __RCSID 138 #undef __SCCSID 139 #define __IDSTRING_CONCAT(l,p) __LINTED__ ## l ## _ ## p 140 #define __IDSTRING_EXPAND(l,p) __IDSTRING_CONCAT(l,p) 141 #ifdef MKSH_DONT_EMIT_IDSTRING 142 #define __IDSTRING(prefix, string) /* nothing */ 143 #else 144 #define __IDSTRING(prefix, string) \ 145 static const char __IDSTRING_EXPAND(__LINE__,prefix) [] \ 146 MKSH_A_USED = "@(""#)" #prefix ": " string 147 #endif 148 #define __COPYRIGHT(x) __IDSTRING(copyright,x) 149 #define __RCSID(x) __IDSTRING(rcsid,x) 150 #define __SCCSID(x) __IDSTRING(sccsid,x) 151 #endif 152 153 #ifdef EXTERN 154 __RCSID("$MirOS: src/bin/mksh/sh.h,v 1.495 2011/10/07 19:51:44 tg Exp $"); 155 #endif 156 #define MKSH_VERSION "R40 2011/10/07" 157 158 #ifndef MKSH_INCLUDES_ONLY 159 160 /* extra types */ 161 162 #if !HAVE_GETRUSAGE 163 #undef rusage 164 #undef RUSAGE_SELF 165 #undef RUSAGE_CHILDREN 166 #define rusage mksh_rusage 167 #define RUSAGE_SELF 0 168 #define RUSAGE_CHILDREN -1 169 170 struct rusage { 171 struct timeval ru_utime; 172 struct timeval ru_stime; 173 }; 174 #endif 175 176 #if !HAVE_RLIM_T 177 typedef long rlim_t; 178 #endif 179 180 #if !HAVE_SIG_T 181 #undef sig_t 182 typedef void (*sig_t)(int); 183 #endif 184 185 #if !HAVE_CAN_INTTYPES 186 #if !HAVE_CAN_UCBINTS 187 typedef signed int int32_t; 188 typedef unsigned int uint32_t; 189 #else 190 typedef u_int32_t uint32_t; 191 #endif 192 #endif 193 194 #if !HAVE_CAN_INT8TYPE 195 #if !HAVE_CAN_UCBINT8 196 typedef unsigned char uint8_t; 197 #else 198 typedef u_int8_t uint8_t; 199 #endif 200 #endif 201 202 /* extra macros */ 203 204 #ifndef timerclear 205 #define timerclear(tvp) \ 206 do { \ 207 (tvp)->tv_sec = (tvp)->tv_usec = 0; \ 208 } while (/* CONSTCOND */ 0) 209 #endif 210 #ifndef timeradd 211 #define timeradd(tvp, uvp, vvp) \ 212 do { \ 213 (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \ 214 (vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \ 215 if ((vvp)->tv_usec >= 1000000) { \ 216 (vvp)->tv_sec++; \ 217 (vvp)->tv_usec -= 1000000; \ 218 } \ 219 } while (/* CONSTCOND */ 0) 220 #endif 221 #ifndef timersub 222 #define timersub(tvp, uvp, vvp) \ 223 do { \ 224 (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \ 225 (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \ 226 if ((vvp)->tv_usec < 0) { \ 227 (vvp)->tv_sec--; \ 228 (vvp)->tv_usec += 1000000; \ 229 } \ 230 } while (/* CONSTCOND */ 0) 231 #endif 232 233 #define ksh_isdigit(c) (((c) >= '0') && ((c) <= '9')) 234 #define ksh_islower(c) (((c) >= 'a') && ((c) <= 'z')) 235 #define ksh_isupper(c) (((c) >= 'A') && ((c) <= 'Z')) 236 #define ksh_tolower(c) (((c) >= 'A') && ((c) <= 'Z') ? (c) - 'A' + 'a' : (c)) 237 #define ksh_toupper(c) (((c) >= 'a') && ((c) <= 'z') ? (c) - 'a' + 'A' : (c)) 238 #define ksh_isdash(s) (((s) != NULL) && ((s)[0] == '-') && ((s)[1] == '\0')) 239 #define ksh_isspace(c) ((((c) >= 0x09) && ((c) <= 0x0D)) || ((c) == 0x20)) 240 241 #ifdef NO_PATH_MAX 242 #undef PATH_MAX 243 #else 244 #ifndef PATH_MAX 245 #define PATH_MAX 1024 246 #endif 247 #endif 248 #ifndef SIZE_MAX 249 #ifdef SIZE_T_MAX 250 #define SIZE_MAX SIZE_T_MAX 251 #else 252 #define SIZE_MAX ((size_t)-1) 253 #endif 254 #endif 255 #ifndef S_ISLNK 256 #define S_ISLNK(m) ((m & 0170000) == 0120000) 257 #endif 258 #ifndef S_ISSOCK 259 #define S_ISSOCK(m) ((m & 0170000) == 0140000) 260 #endif 261 #if !defined(S_ISCDF) && defined(S_CDF) 262 #define S_ISCDF(m) (S_ISDIR(m) && ((m) & S_CDF)) 263 #endif 264 #ifndef DEFFILEMODE 265 #define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) 266 #endif 267 268 #if !defined(MAP_FAILED) 269 /* XXX imake style */ 270 # if defined(__linux) 271 #define MAP_FAILED ((void *)-1) 272 # elif defined(__bsdi__) || defined(__osf__) || defined(__ultrix) 273 #define MAP_FAILED ((caddr_t)-1) 274 # endif 275 #endif 276 277 #ifndef NSIG 278 #if defined(_NSIG) 279 #define NSIG _NSIG 280 #elif defined(SIGMAX) 281 #define NSIG (SIGMAX+1) 282 #endif 283 #endif 284 285 #undef BAD /* AIX defines that somewhere */ 286 287 /* OS-dependent additions (functions, variables, by OS) */ 288 289 #if !HAVE_FLOCK_DECL 290 extern int flock(int, int); 291 #endif 292 293 #if !HAVE_GETRUSAGE 294 extern int getrusage(int, struct rusage *); 295 #endif 296 297 #if !HAVE_REVOKE_DECL 298 extern int revoke(const char *); 299 #endif 300 301 #ifdef __ultrix 302 /* XXX imake style */ 303 int strcasecmp(const char *, const char *); 304 #endif 305 306 #if !HAVE_STRCASESTR 307 const char *stristr(const char *, const char *); 308 #endif 309 310 #if !HAVE_STRLCPY 311 size_t strlcpy(char *, const char *, size_t); 312 #endif 313 314 #if !HAVE_SYS_SIGLIST_DECL 315 extern const char *const sys_siglist[]; 316 #endif 317 318 #ifdef __INTERIX 319 /* XXX imake style */ 320 #define makedev mkdev 321 extern int __cdecl seteuid(uid_t); 322 extern int __cdecl setegid(gid_t); 323 #endif 324 325 /* remove redundances */ 326 327 #if defined(MirBSD) && (MirBSD >= 0x08A8) 328 #define MKSH_mirbsd_wcwidth 329 #define utf_wcwidth(i) wcwidth((__WCHAR_TYPE__)i) 330 extern int wcwidth(__WCHAR_TYPE__); 331 #endif 332 333 334 /* some useful #defines */ 335 #ifdef EXTERN 336 # define E_INIT(i) = i 337 #else 338 # define E_INIT(i) 339 # define EXTERN extern 340 # define EXTERN_DEFINED 341 #endif 342 343 /* define bit in flag */ 344 #define BIT(i) (1 << (i)) 345 #define NELEM(a) (sizeof(a) / sizeof((a)[0])) 346 347 /* arithmetics types */ 348 typedef int32_t mksh_ari_t; 349 typedef uint32_t mksh_uari_t; 350 351 /* boolean type (no <stdbool.h> deliberately) */ 352 typedef unsigned char mksh_bool; 353 #undef bool 354 /* false MUST equal 0 */ 355 #undef false 356 #undef true 357 /* access macros for boolean type */ 358 #define bool mksh_bool 359 /* values must have identity mapping between mksh_bool and short */ 360 #define false 0 361 #define true 1 362 /* make any-type into bool or short */ 363 #define tobool(cond) ((cond) ? true : false) 364 365 /* these shall be smaller than 100 */ 366 #ifdef MKSH_CONSERVATIVE_FDS 367 #define NUFILE 32 /* Number of user-accessible files */ 368 #define FDBASE 10 /* First file usable by Shell */ 369 #else 370 #define NUFILE 56 /* Number of user-accessible files */ 371 #define FDBASE 24 /* First file usable by Shell */ 372 #endif 373 374 /* 375 * Make MAGIC a char that might be printed to make bugs more obvious, but 376 * not a char that is used often. Also, can't use the high bit as it causes 377 * portability problems (calling strchr(x, 0x80|'x') is error prone). 378 */ 379 #define MAGIC (7) /* prefix for *?[!{,} during expand */ 380 #define ISMAGIC(c) ((unsigned char)(c) == MAGIC) 381 #define NOT '!' /* might use ^ (ie, [!...] vs [^..]) */ 382 383 #define LINE 4096 /* input line size */ 384 385 EXTERN const char *safe_prompt; /* safe prompt if PS1 substitution fails */ 386 EXTERN const char initvsn[] E_INIT("KSH_VERSION=@(#)MIRBSD KSH " MKSH_VERSION); 387 #define KSH_VERSION (initvsn + /* "KSH_VERSION=@(#)" */ 16) 388 389 EXTERN const char digits_uc[] E_INIT("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"); 390 EXTERN const char digits_lc[] E_INIT("0123456789abcdefghijklmnopqrstuvwxyz"); 391 392 /* 393 * Evil hack for const correctness due to API brokenness 394 */ 395 union mksh_cchack { 396 char *rw; 397 const char *ro; 398 }; 399 union mksh_ccphack { 400 char **rw; 401 const char **ro; 402 }; 403 404 /* for const debugging */ 405 #if defined(DEBUG) && defined(__GNUC__) && !defined(__ICC) && \ 406 !defined(__INTEL_COMPILER) && !defined(__SUNPRO_C) 407 char *ucstrchr(char *, int); 408 char *ucstrstr(char *, const char *); 409 #undef strchr 410 #define strchr ucstrchr 411 #define strstr ucstrstr 412 #define cstrchr(s,c) ({ \ 413 union mksh_cchack in, out; \ 414 \ 415 in.ro = (s); \ 416 out.rw = ucstrchr(in.rw, (c)); \ 417 (out.ro); \ 418 }) 419 #define cstrstr(b,l) ({ \ 420 union mksh_cchack in, out; \ 421 \ 422 in.ro = (b); \ 423 out.rw = ucstrstr(in.rw, (l)); \ 424 (out.ro); \ 425 }) 426 #define vstrchr(s,c) (cstrchr((s), (c)) != NULL) 427 #define vstrstr(b,l) (cstrstr((b), (l)) != NULL) 428 #define mkssert(e) ((e) ? (void)0 : exit(255)) 429 #else /* !DEBUG, !gcc */ 430 #define cstrchr(s,c) ((const char *)strchr((s), (c))) 431 #define cstrstr(s,c) ((const char *)strstr((s), (c))) 432 #define vstrchr(s,c) (strchr((s), (c)) != NULL) 433 #define vstrstr(b,l) (strstr((b), (l)) != NULL) 434 #define mkssert(e) ((void)0) 435 #endif 436 437 /* use this ipv strchr(s, 0) but no side effects in s! */ 438 #define strnul(s) ((s) + strlen(s)) 439 440 #define utf_ptradjx(src, dst) do { \ 441 (dst) = (src) + utf_ptradj(src); \ 442 } while (/* CONSTCOND */ 0) 443 444 #ifdef MKSH_SMALL 445 #define strdupx(d, s, ap) do { \ 446 (d) = strdup_((s), (ap)); \ 447 } while (/* CONSTCOND */ 0) 448 #define strndupx(d, s, n, ap) do { \ 449 (d) = strndup_((s), (n), (ap)); \ 450 } while (/* CONSTCOND */ 0) 451 #else 452 /* be careful to evaluate arguments only once! */ 453 #define strdupx(d, s, ap) do { \ 454 const char *strdup_src = (s); \ 455 char *strdup_dst = NULL; \ 456 \ 457 if (strdup_src != NULL) { \ 458 size_t strdup_len = strlen(strdup_src) + 1; \ 459 strdup_dst = alloc(strdup_len, (ap)); \ 460 memcpy(strdup_dst, strdup_src, strdup_len); \ 461 } \ 462 (d) = strdup_dst; \ 463 } while (/* CONSTCOND */ 0) 464 #define strndupx(d, s, n, ap) do { \ 465 const char *strdup_src = (s); \ 466 char *strdup_dst = NULL; \ 467 \ 468 if (strdup_src != NULL) { \ 469 size_t strndup_len = (n); \ 470 strdup_dst = alloc(strndup_len + 1, (ap)); \ 471 memcpy(strdup_dst, strdup_src, strndup_len); \ 472 strdup_dst[strndup_len] = '\0'; \ 473 } \ 474 (d) = strdup_dst; \ 475 } while (/* CONSTCOND */ 0) 476 #endif 477 478 #if HAVE_STRCASESTR 479 #define stristr(b,l) ((const char *)strcasestr((b), (l))) 480 #endif 481 482 #ifdef MKSH_SMALL 483 #ifndef MKSH_CONSERVATIVE_FDS 484 #define MKSH_CONSERVATIVE_FDS /* defined */ 485 #endif 486 #ifndef MKSH_NOPWNAM 487 #define MKSH_NOPWNAM /* defined */ 488 #endif 489 #ifndef MKSH_S_NOVI 490 #define MKSH_S_NOVI 1 491 #endif 492 #endif 493 494 #ifndef MKSH_S_NOVI 495 #define MKSH_S_NOVI 0 496 #endif 497 498 #if defined(MKSH_NOPROSPECTOFWORK) && !defined(MKSH_UNEMPLOYED) 499 #define MKSH_UNEMPLOYED 1 500 #endif 501 502 /* 503 * simple grouping allocator 504 */ 505 506 507 /* 0. OS API: where to get memory from and how to free it (grouped) */ 508 509 /* malloc(3)/realloc(3) -> free(3) for use by the memory allocator */ 510 #define malloc_osi(sz) malloc(sz) 511 #define realloc_osi(p,sz) realloc((p), (sz)) 512 #define free_osimalloc(p) free(p) 513 514 /* malloc(3)/realloc(3) -> free(3) for use by mksh code */ 515 #define malloc_osfunc(sz) malloc(sz) 516 #define realloc_osfunc(p,sz) realloc((p), (sz)) 517 #define free_osfunc(p) free(p) 518 519 #if HAVE_MKNOD 520 /* setmode(3) -> free(3) */ 521 #define free_ossetmode(p) free(p) 522 #endif 523 524 #if !HAVE_MKSTEMP 525 /* tempnam(3) -> free(3) */ 526 #define free_ostempnam(p) free(p) 527 #endif 528 529 #ifdef NO_PATH_MAX 530 /* GNU libc: get_current_dir_name(3) -> free(3) */ 531 #define free_gnu_gcdn(p) free(p) 532 #endif 533 534 535 /* 1. internal structure */ 536 struct lalloc { 537 struct lalloc *next; 538 }; 539 540 /* 2. sizes */ 541 #define ALLOC_ITEM struct lalloc 542 #define ALLOC_SIZE (sizeof(ALLOC_ITEM)) 543 544 /* 3. group structure (only the same for lalloc.c) */ 545 typedef struct lalloc Area; 546 547 548 EXTERN Area aperm; /* permanent object space */ 549 #define APERM &aperm 550 #define ATEMP &e->area 551 552 /* 553 * flags (the order of these enums MUST match the order in misc.c(options[])) 554 */ 555 enum sh_flag { 556 #define SHFLAGS_ENUMS 557 #include "sh_flags.h" 558 FNFLAGS /* (place holder: how many flags are there) */ 559 }; 560 561 #define Flag(f) (shell_flags[(int)(f)]) 562 #define UTFMODE Flag(FUNICODE) 563 564 /* 565 * parsing & execution environment 566 */ 567 extern struct env { 568 ALLOC_ITEM alloc_INT; /* internal, do not touch */ 569 Area area; /* temporary allocation area */ 570 struct env *oenv; /* link to previous environment */ 571 struct block *loc; /* local variables and functions */ 572 short *savefd; /* original redirected fds */ 573 struct temp *temps; /* temp files */ 574 sigjmp_buf jbuf; /* long jump back to env creator */ 575 short type; /* environment type - see below */ 576 short flags; /* EF_* */ 577 } *e; 578 579 /* struct env.type values */ 580 #define E_NONE 0 /* dummy environment */ 581 #define E_PARSE 1 /* parsing command # */ 582 #define E_FUNC 2 /* executing function # */ 583 #define E_INCL 3 /* including a file via . # */ 584 #define E_EXEC 4 /* executing command tree */ 585 #define E_LOOP 5 /* executing for/while # */ 586 #define E_ERRH 6 /* general error handler # */ 587 /* # indicates env has valid jbuf (see unwind()) */ 588 589 /* struct env.flag values */ 590 #define EF_FUNC_PARSE BIT(0) /* function being parsed */ 591 #define EF_BRKCONT_PASS BIT(1) /* set if E_LOOP must pass break/continue on */ 592 #define EF_FAKE_SIGDIE BIT(2) /* hack to get info from unwind to quitenv */ 593 594 /* Do breaks/continues stop at env type e? */ 595 #define STOP_BRKCONT(t) ((t) == E_NONE || (t) == E_PARSE \ 596 || (t) == E_FUNC || (t) == E_INCL) 597 /* Do returns stop at env type e? */ 598 #define STOP_RETURN(t) ((t) == E_FUNC || (t) == E_INCL) 599 600 /* values for siglongjmp(e->jbuf, 0) */ 601 #define LRETURN 1 /* return statement */ 602 #define LEXIT 2 /* exit statement */ 603 #define LERROR 3 /* errorf() called */ 604 #define LLEAVE 4 /* untrappable exit/error */ 605 #define LINTR 5 /* ^C noticed */ 606 #define LBREAK 6 /* break statement */ 607 #define LCONTIN 7 /* continue statement */ 608 #define LSHELL 8 /* return to interactive shell() */ 609 #define LAEXPR 9 /* error in arithmetic expression */ 610 611 /* sort of shell global state */ 612 EXTERN pid_t procpid; /* PID of executing process */ 613 EXTERN int exstat; /* exit status */ 614 EXTERN int subst_exstat; /* exit status of last $(..)/`..` */ 615 EXTERN struct tbl *vp_pipest; /* global PIPESTATUS array */ 616 EXTERN short trap_exstat; /* exit status before running a trap */ 617 EXTERN uint8_t trap_nested; /* running nested traps */ 618 EXTERN uint8_t shell_flags[FNFLAGS]; 619 EXTERN const char *kshname; /* $0 */ 620 EXTERN struct { 621 uid_t kshuid_v; /* real UID of shell */ 622 uid_t ksheuid_v; /* effective UID of shell */ 623 gid_t kshgid_v; /* real GID of shell */ 624 gid_t kshegid_v; /* effective GID of shell */ 625 pid_t kshpgrp_v; /* process group of shell */ 626 pid_t kshppid_v; /* PID of parent of shell */ 627 pid_t kshpid_v; /* $$, shell PID */ 628 } rndsetupstate; 629 630 #define kshpid rndsetupstate.kshpid_v 631 #define kshpgrp rndsetupstate.kshpgrp_v 632 #define kshuid rndsetupstate.kshuid_v 633 #define ksheuid rndsetupstate.ksheuid_v 634 #define kshgid rndsetupstate.kshgid_v 635 #define kshegid rndsetupstate.kshegid_v 636 #define kshppid rndsetupstate.kshppid_v 637 638 639 /* option processing */ 640 #define OF_CMDLINE 0x01 /* command line */ 641 #define OF_SET 0x02 /* set builtin */ 642 #define OF_SPECIAL 0x04 /* a special variable changing */ 643 #define OF_INTERNAL 0x08 /* set internally by shell */ 644 #define OF_FIRSTTIME 0x10 /* as early as possible, once */ 645 #define OF_ANY (OF_CMDLINE | OF_SET | OF_SPECIAL | OF_INTERNAL) 646 647 struct shoption { 648 const char *name; /* long name of option */ 649 char c; /* character flag (if any) */ 650 unsigned char flags; /* OF_* */ 651 }; 652 extern const struct shoption options[]; 653 654 /* null value for variable; comparison pointer for unset */ 655 EXTERN char null[] E_INIT(""); 656 /* helpers for string pooling */ 657 EXTERN const char Tintovfl[] E_INIT("integer overflow %zu %c %zu prevented"); 658 EXTERN const char Toomem[] E_INIT("can't allocate %lu data bytes"); 659 #if defined(__GNUC__) 660 /* trust this to have string pooling; -Wformat bitches otherwise */ 661 #define Tsynerr "syntax error" 662 #else 663 EXTERN const char Tsynerr[] E_INIT("syntax error"); 664 #endif 665 EXTERN const char Tselect[] E_INIT("select"); 666 EXTERN const char Tr_fc_e_dash[] E_INIT("r=fc -e -"); 667 #define Tfc_e_dash (Tr_fc_e_dash + 2) /* "fc -e -" */ 668 #define Zfc_e_dash 7 /* strlen(Tfc_e_dash) */ 669 EXTERN const char Tlocal_typeset[] E_INIT("local=typeset"); 670 #define T_typeset (Tlocal_typeset + 5) /* "=typeset" */ 671 #define Ttypeset (Tlocal_typeset + 6) /* "typeset" */ 672 EXTERN const char Tpalias[] E_INIT("+alias"); 673 #define Talias (Tpalias + 1) /* "alias" */ 674 EXTERN const char Tpunalias[] E_INIT("+unalias"); 675 #define Tunalias (Tpunalias + 1) /* "unalias" */ 676 EXTERN const char Tsgset[] E_INIT("*=set"); 677 #define Tset (Tsgset + 2) /* "set" */ 678 EXTERN const char Tgbuiltin[] E_INIT("=builtin"); 679 #define Tbuiltin (Tgbuiltin + 1) /* "builtin" */ 680 EXTERN const char T_function[] E_INIT(" function"); 681 #define Tfunction (T_function + 1) /* "function" */ 682 683 enum temp_type { 684 TT_HEREDOC_EXP, /* expanded heredoc */ 685 TT_HIST_EDIT /* temp file used for history editing (fc -e) */ 686 }; 687 typedef enum temp_type Temp_type; 688 /* temp/heredoc files. The file is removed when the struct is freed. */ 689 struct temp { 690 struct temp *next; 691 struct shf *shf; 692 char *name; 693 int pid; /* pid of process parsed here-doc */ 694 Temp_type type; 695 }; 696 697 /* 698 * stdio and our IO routines 699 */ 700 701 #define shl_spare (&shf_iob[0]) /* for c_read()/c_print() */ 702 #define shl_stdout (&shf_iob[1]) 703 #define shl_out (&shf_iob[2]) 704 EXTERN bool shl_stdout_ok; 705 706 /* 707 * trap handlers 708 */ 709 typedef struct trap { 710 const char *name; /* short name */ 711 const char *mess; /* descriptive name */ 712 char *trap; /* trap command */ 713 sig_t cursig; /* current handler (valid if TF_ORIG_* set) */ 714 sig_t shtrap; /* shell signal handler */ 715 int signal; /* signal number */ 716 int flags; /* TF_* */ 717 volatile sig_atomic_t set; /* trap pending */ 718 } Trap; 719 720 /* values for Trap.flags */ 721 #define TF_SHELL_USES BIT(0) /* shell uses signal, user can't change */ 722 #define TF_USER_SET BIT(1) /* user has (tried to) set trap */ 723 #define TF_ORIG_IGN BIT(2) /* original action was SIG_IGN */ 724 #define TF_ORIG_DFL BIT(3) /* original action was SIG_DFL */ 725 #define TF_EXEC_IGN BIT(4) /* restore SIG_IGN just before exec */ 726 #define TF_EXEC_DFL BIT(5) /* restore SIG_DFL just before exec */ 727 #define TF_DFL_INTR BIT(6) /* when received, default action is LINTR */ 728 #define TF_TTY_INTR BIT(7) /* tty generated signal (see j_waitj) */ 729 #define TF_CHANGED BIT(8) /* used by runtrap() to detect trap changes */ 730 #define TF_FATAL BIT(9) /* causes termination if not trapped */ 731 732 /* values for setsig()/setexecsig() flags argument */ 733 #define SS_RESTORE_MASK 0x3 /* how to restore a signal before an exec() */ 734 #define SS_RESTORE_CURR 0 /* leave current handler in place */ 735 #define SS_RESTORE_ORIG 1 /* restore original handler */ 736 #define SS_RESTORE_DFL 2 /* restore to SIG_DFL */ 737 #define SS_RESTORE_IGN 3 /* restore to SIG_IGN */ 738 #define SS_FORCE BIT(3) /* set signal even if original signal ignored */ 739 #define SS_USER BIT(4) /* user is doing the set (ie, trap command) */ 740 #define SS_SHTRAP BIT(5) /* trap for internal use (ALRM, CHLD, WINCH) */ 741 742 #define ksh_SIGEXIT 0 /* for trap EXIT */ 743 #define ksh_SIGERR NSIG /* for trap ERR */ 744 745 EXTERN volatile sig_atomic_t trap; /* traps pending? */ 746 EXTERN volatile sig_atomic_t intrsig; /* pending trap interrupts command */ 747 EXTERN volatile sig_atomic_t fatal_trap; /* received a fatal signal */ 748 extern Trap sigtraps[NSIG+1]; 749 750 /* got_winch = 1 when we need to re-adjust the window size */ 751 #ifdef SIGWINCH 752 EXTERN volatile sig_atomic_t got_winch E_INIT(1); 753 #else 754 #define got_winch true 755 #endif 756 757 /* 758 * TMOUT support 759 */ 760 /* values for ksh_tmout_state */ 761 enum tmout_enum { 762 TMOUT_EXECUTING = 0, /* executing commands */ 763 TMOUT_READING, /* waiting for input */ 764 TMOUT_LEAVING /* have timed out */ 765 }; 766 EXTERN unsigned int ksh_tmout; 767 EXTERN enum tmout_enum ksh_tmout_state E_INIT(TMOUT_EXECUTING); 768 769 /* For "You have stopped jobs" message */ 770 EXTERN int really_exit; 771 772 /* 773 * fast character classes 774 */ 775 #define C_ALPHA BIT(0) /* a-z_A-Z */ 776 #define C_DIGIT BIT(1) /* 0-9 */ 777 #define C_LEX1 BIT(2) /* \t \n\0|&;<>() */ 778 #define C_VAR1 BIT(3) /* *@#!$-? */ 779 #define C_IFSWS BIT(4) /* \t \n (IFS white space) */ 780 #define C_SUBOP1 BIT(5) /* "=-+?" */ 781 #define C_QUOTE BIT(6) /* \t\n "#$&'()*;<=>?[\]`| (needing quoting) */ 782 #define C_IFS BIT(7) /* $IFS */ 783 #define C_SUBOP2 BIT(8) /* "#%" (magic, see below) */ 784 785 extern unsigned char chtypes[]; 786 787 #define ctype(c, t) tobool( ((t) == C_SUBOP2) ? \ 788 (((c) == '#' || (c) == '%') ? 1 : 0) : \ 789 (chtypes[(unsigned char)(c)] & (t)) ) 790 #define ksh_isalphx(c) ctype((c), C_ALPHA) 791 #define ksh_isalnux(c) ctype((c), C_ALPHA | C_DIGIT) 792 793 EXTERN int ifs0 E_INIT(' '); /* for "$*" */ 794 795 /* Argument parsing for built-in commands and getopts command */ 796 797 /* Values for Getopt.flags */ 798 #define GF_ERROR BIT(0) /* call errorf() if there is an error */ 799 #define GF_PLUSOPT BIT(1) /* allow +c as an option */ 800 #define GF_NONAME BIT(2) /* don't print argv[0] in errors */ 801 802 /* Values for Getopt.info */ 803 #define GI_MINUS BIT(0) /* an option started with -... */ 804 #define GI_PLUS BIT(1) /* an option started with +... */ 805 #define GI_MINUSMINUS BIT(2) /* arguments were ended with -- */ 806 807 /* in case some OS defines these */ 808 #undef optarg 809 #undef optind 810 811 typedef struct { 812 const char *optarg; 813 int optind; 814 int uoptind; /* what user sees in $OPTIND */ 815 int flags; /* see GF_* */ 816 int info; /* see GI_* */ 817 unsigned int p; /* 0 or index into argv[optind - 1] */ 818 char buf[2]; /* for bad option OPTARG value */ 819 } Getopt; 820 821 EXTERN Getopt builtin_opt; /* for shell builtin commands */ 822 EXTERN Getopt user_opt; /* parsing state for getopts builtin command */ 823 824 /* This for co-processes */ 825 826 /* something that won't (realisticly) wrap */ 827 typedef int32_t Coproc_id; 828 829 struct coproc { 830 void *job; /* 0 or job of co-process using input pipe */ 831 int read; /* pipe from co-process's stdout */ 832 int readw; /* other side of read (saved temporarily) */ 833 int write; /* pipe to co-process's stdin */ 834 int njobs; /* number of live jobs using output pipe */ 835 Coproc_id id; /* id of current output pipe */ 836 }; 837 EXTERN struct coproc coproc; 838 839 #ifndef MKSH_NOPROSPECTOFWORK 840 /* used in jobs.c and by coprocess stuff in exec.c and select() calls */ 841 EXTERN sigset_t sm_default, sm_sigchld; 842 #endif 843 844 /* name of called builtin function (used by error functions) */ 845 EXTERN const char *builtin_argv0; 846 /* flags of called builtin (SPEC_BI, etc.) */ 847 EXTERN uint32_t builtin_flag; 848 849 /* current working directory */ 850 EXTERN char *current_wd; 851 852 /* 853 * Minimum required space to work with on a line - if the prompt leaves 854 * less space than this on a line, the prompt is truncated. 855 */ 856 #define MIN_EDIT_SPACE 7 857 /* 858 * Minimum allowed value for x_cols: 2 for prompt, 3 for " < " at end of line 859 */ 860 #define MIN_COLS (2 + MIN_EDIT_SPACE + 3) 861 #define MIN_LINS 3 862 EXTERN mksh_ari_t x_cols E_INIT(80); /* tty columns */ 863 EXTERN mksh_ari_t x_lins E_INIT(-1); /* tty lines */ 864 865 /* These to avoid bracket matching problems */ 866 #define OPAREN '(' 867 #define CPAREN ')' 868 #define OBRACK '[' 869 #define CBRACK ']' 870 #define OBRACE '{' 871 #define CBRACE '}' 872 873 874 /* Determine the location of the system (common) profile */ 875 876 /* This is deliberately not configurable via CPPFLAGS */ 877 #if defined(ANDROID) 878 #define MKSH_ETC_LOCATION "/system/etc" 879 #else 880 #define MKSH_ETC_LOCATION "/etc" 881 #endif 882 883 #define MKSH_SYSTEM_PROFILE MKSH_ETC_LOCATION "/profile" 884 #define MKSH_SUID_PROFILE MKSH_ETC_LOCATION "/suid_profile" 885 886 887 /* Used by v_evaluate() and setstr() to control action when error occurs */ 888 #define KSH_UNWIND_ERROR 0 /* unwind the stack (longjmp) */ 889 #define KSH_RETURN_ERROR 1 /* return 1/0 for success/failure */ 890 891 /* 892 * Shell file I/O routines 893 */ 894 895 #define SHF_BSIZE 512 896 897 #define shf_fileno(shf) ((shf)->fd) 898 #define shf_setfileno(shf,nfd) ((shf)->fd = (nfd)) 899 #define shf_getc_(shf) ((shf)->rnleft > 0 ? \ 900 (shf)->rnleft--, *(shf)->rp++ : \ 901 shf_getchar(shf)) 902 #define shf_putc_(c, shf) ((shf)->wnleft == 0 ? \ 903 shf_putchar((c), (shf)) : \ 904 ((shf)->wnleft--, *(shf)->wp++ = (c))) 905 #define shf_eof(shf) ((shf)->flags & SHF_EOF) 906 #define shf_error(shf) ((shf)->flags & SHF_ERROR) 907 #define shf_errno(shf) ((shf)->errnosv) 908 #define shf_clearerr(shf) ((shf)->flags &= ~(SHF_EOF | SHF_ERROR)) 909 910 /* Flags passed to shf_*open() */ 911 #define SHF_RD 0x0001 912 #define SHF_WR 0x0002 913 #define SHF_RDWR (SHF_RD|SHF_WR) 914 #define SHF_ACCMODE 0x0003 /* mask */ 915 #define SHF_GETFL 0x0004 /* use fcntl() to figure RD/WR flags */ 916 #define SHF_UNBUF 0x0008 /* unbuffered I/O */ 917 #define SHF_CLEXEC 0x0010 /* set close on exec flag */ 918 #define SHF_MAPHI 0x0020 /* make fd > FDBASE (and close orig) 919 * (shf_open() only) */ 920 #define SHF_DYNAMIC 0x0040 /* string: increase buffer as needed */ 921 #define SHF_INTERRUPT 0x0080 /* EINTR in read/write causes error */ 922 /* Flags used internally */ 923 #define SHF_STRING 0x0100 /* a string, not a file */ 924 #define SHF_ALLOCS 0x0200 /* shf and shf->buf were alloc()ed */ 925 #define SHF_ALLOCB 0x0400 /* shf->buf was alloc()ed */ 926 #define SHF_ERROR 0x0800 /* read()/write() error */ 927 #define SHF_EOF 0x1000 /* read eof (sticky) */ 928 #define SHF_READING 0x2000 /* currently reading: rnleft,rp valid */ 929 #define SHF_WRITING 0x4000 /* currently writing: wnleft,wp valid */ 930 931 932 struct shf { 933 Area *areap; /* area shf/buf were allocated in */ 934 unsigned char *rp; /* read: current position in buffer */ 935 unsigned char *wp; /* write: current position in buffer */ 936 unsigned char *buf; /* buffer */ 937 ssize_t bsize; /* actual size of buf */ 938 ssize_t rbsize; /* size of buffer (1 if SHF_UNBUF) */ 939 ssize_t rnleft; /* read: how much data left in buffer */ 940 ssize_t wbsize; /* size of buffer (0 if SHF_UNBUF) */ 941 ssize_t wnleft; /* write: how much space left in buffer */ 942 int flags; /* see SHF_* */ 943 int fd; /* file descriptor */ 944 int errnosv; /* saved value of errno after error */ 945 }; 946 947 extern struct shf shf_iob[]; 948 949 struct table { 950 Area *areap; /* area to allocate entries */ 951 struct tbl **tbls; /* hashed table items */ 952 size_t nfree; /* free table entries */ 953 uint8_t tshift; /* table size (2^tshift) */ 954 }; 955 956 /* table item */ 957 struct tbl { 958 /* Area to allocate from */ 959 Area *areap; 960 /* value */ 961 union { 962 char *s; /* string */ 963 mksh_ari_t i; /* integer */ 964 mksh_uari_t u; /* unsigned integer */ 965 int (*f)(const char **); /* built-in command */ 966 struct op *t; /* "function" tree */ 967 } val; 968 union { 969 struct tbl *array; /* array values */ 970 const char *fpath; /* temporary path to undef function */ 971 } u; 972 union { 973 int field; /* field with for -L/-R/-Z */ 974 int errnov; /* CEXEC/CTALIAS */ 975 } u2; 976 union { 977 uint32_t hval; /* hash(name) */ 978 uint32_t index; /* index for an array */ 979 } ua; 980 /* 981 * command type (see below), base (if INTEGER), 982 * offset from val.s of value (if EXPORT) 983 */ 984 int type; 985 /* flags (see below) */ 986 uint32_t flag; 987 988 /* actually longer: name (variable length) */ 989 char name[4]; 990 }; 991 992 /* common flag bits */ 993 #define ALLOC BIT(0) /* val.s has been allocated */ 994 #define DEFINED BIT(1) /* is defined in block */ 995 #define ISSET BIT(2) /* has value, vp->val.[si] */ 996 #define EXPORT BIT(3) /* exported variable/function */ 997 #define TRACE BIT(4) /* var: user flagged, func: execution tracing */ 998 /* (start non-common flags at 8) */ 999 /* flag bits used for variables */ 1000 #define SPECIAL BIT(8) /* PATH, IFS, SECONDS, etc */ 1001 #define INTEGER BIT(9) /* val.i contains integer value */ 1002 #define RDONLY BIT(10) /* read-only variable */ 1003 #define LOCAL BIT(11) /* for local typeset() */ 1004 #define ARRAY BIT(13) /* array */ 1005 #define LJUST BIT(14) /* left justify */ 1006 #define RJUST BIT(15) /* right justify */ 1007 #define ZEROFIL BIT(16) /* 0 filled if RJUSTIFY, strip 0s if LJUSTIFY */ 1008 #define LCASEV BIT(17) /* convert to lower case */ 1009 #define UCASEV_AL BIT(18) /* convert to upper case / autoload function */ 1010 #define INT_U BIT(19) /* unsigned integer */ 1011 #define INT_L BIT(20) /* long integer (no-op but used as magic) */ 1012 #define IMPORT BIT(21) /* flag to typeset(): no arrays, must have = */ 1013 #define LOCAL_COPY BIT(22) /* with LOCAL - copy attrs from existing var */ 1014 #define EXPRINEVAL BIT(23) /* contents currently being evaluated */ 1015 #define EXPRLVALUE BIT(24) /* useable as lvalue (temp flag) */ 1016 #define AINDEX BIT(25) /* array index >0 = ua.index filled in */ 1017 #define ASSOC BIT(26) /* ARRAY ? associative : reference */ 1018 /* flag bits used for taliases/builtins/aliases/keywords/functions */ 1019 #define KEEPASN BIT(8) /* keep command assignments (eg, var=x cmd) */ 1020 #define FINUSE BIT(9) /* function being executed */ 1021 #define FDELETE BIT(10) /* function deleted while it was executing */ 1022 #define FKSH BIT(11) /* function defined with function x (vs x()) */ 1023 #define SPEC_BI BIT(12) /* a POSIX special builtin */ 1024 #define REG_BI BIT(13) /* a POSIX regular builtin */ 1025 /* 1026 * Attributes that can be set by the user (used to decide if an unset 1027 * param should be repoted by set/typeset). Does not include ARRAY or 1028 * LOCAL. 1029 */ 1030 #define USERATTRIB (EXPORT|INTEGER|RDONLY|LJUST|RJUST|ZEROFIL|\ 1031 LCASEV|UCASEV_AL|INT_U|INT_L) 1032 1033 #define arrayindex(vp) ((unsigned long)((vp)->flag & AINDEX ? \ 1034 (vp)->ua.index : 0)) 1035 1036 EXTERN enum { 1037 SRF_NOP, 1038 SRF_ENABLE, 1039 SRF_DISABLE 1040 } set_refflag E_INIT(SRF_NOP); 1041 1042 /* command types */ 1043 #define CNONE 0 /* undefined */ 1044 #define CSHELL 1 /* built-in */ 1045 #define CFUNC 2 /* function */ 1046 #define CEXEC 4 /* executable command */ 1047 #define CALIAS 5 /* alias */ 1048 #define CKEYWD 6 /* keyword */ 1049 #define CTALIAS 7 /* tracked alias */ 1050 1051 /* Flags for findcom()/comexec() */ 1052 #define FC_SPECBI BIT(0) /* special builtin */ 1053 #define FC_FUNC BIT(1) /* function builtin */ 1054 #define FC_REGBI BIT(2) /* regular builtin */ 1055 #define FC_UNREGBI BIT(3) /* un-regular builtin (!special,!regular) */ 1056 #define FC_BI (FC_SPECBI|FC_REGBI|FC_UNREGBI) 1057 #define FC_PATH BIT(4) /* do path search */ 1058 #define FC_DEFPATH BIT(5) /* use default path in path search */ 1059 1060 1061 #define AF_ARGV_ALLOC 0x1 /* argv[] array allocated */ 1062 #define AF_ARGS_ALLOCED 0x2 /* argument strings allocated */ 1063 #define AI_ARGV(a, i) ((i) == 0 ? (a).argv[0] : (a).argv[(i) - (a).skip]) 1064 #define AI_ARGC(a) ((a).ai_argc - (a).skip) 1065 1066 /* Argument info. Used for $#, $* for shell, functions, includes, etc. */ 1067 struct arg_info { 1068 const char **argv; 1069 int flags; /* AF_* */ 1070 int ai_argc; 1071 int skip; /* first arg is argv[0], second is argv[1 + skip] */ 1072 }; 1073 1074 /* 1075 * activation record for function blocks 1076 */ 1077 struct block { 1078 Area area; /* area to allocate things */ 1079 const char **argv; 1080 char *error; /* error handler */ 1081 char *exit; /* exit handler */ 1082 struct block *next; /* enclosing block */ 1083 struct table vars; /* local variables */ 1084 struct table funs; /* local functions */ 1085 Getopt getopts_state; 1086 int argc; 1087 int flags; /* see BF_* */ 1088 }; 1089 1090 /* Values for struct block.flags */ 1091 #define BF_DOGETOPTS BIT(0) /* save/restore getopts state */ 1092 1093 /* 1094 * Used by ktwalk() and ktnext() routines. 1095 */ 1096 struct tstate { 1097 struct tbl **next; 1098 ssize_t left; 1099 }; 1100 1101 EXTERN struct table taliases; /* tracked aliases */ 1102 EXTERN struct table builtins; /* built-in commands */ 1103 EXTERN struct table aliases; /* aliases */ 1104 EXTERN struct table keywords; /* keywords */ 1105 #ifndef MKSH_NOPWNAM 1106 EXTERN struct table homedirs; /* homedir() cache */ 1107 #endif 1108 1109 struct builtin { 1110 const char *name; 1111 int (*func)(const char **); 1112 }; 1113 1114 extern const struct builtin mkshbuiltins[]; 1115 1116 /* values for set_prompt() */ 1117 #define PS1 0 /* command */ 1118 #define PS2 1 /* command continuation */ 1119 1120 EXTERN char *path; /* copy of either PATH or def_path */ 1121 EXTERN const char *def_path; /* path to use if PATH not set */ 1122 EXTERN char *tmpdir; /* TMPDIR value */ 1123 EXTERN const char *prompt; 1124 EXTERN int cur_prompt; /* PS1 or PS2 */ 1125 EXTERN int current_lineno; /* LINENO value */ 1126 1127 #define NOBLOCK ((struct op *)NULL) 1128 #define NOWORD ((char *)NULL) 1129 #define NOWORDS ((char **)NULL) 1130 1131 /* 1132 * Description of a command or an operation on commands. 1133 */ 1134 struct op { 1135 const char **args; /* arguments to a command */ 1136 char **vars; /* variable assignments */ 1137 struct ioword **ioact; /* IO actions (eg, < > >>) */ 1138 struct op *left, *right; /* descendents */ 1139 char *str; /* word for case; identifier for for, 1140 * select, and functions; 1141 * path to execute for TEXEC; 1142 * time hook for TCOM. 1143 */ 1144 int lineno; /* TCOM/TFUNC: LINENO for this */ 1145 short type; /* operation type, see below */ 1146 /* WARNING: newtp(), tcopy() use evalflags = 0 to clear union */ 1147 union { 1148 /* TCOM: arg expansion eval() flags */ 1149 short evalflags; 1150 /* TFUNC: function x (vs x()) */ 1151 short ksh_func; 1152 /* TPAT: termination character */ 1153 char charflag; 1154 } u; 1155 }; 1156 1157 /* Tree.type values */ 1158 #define TEOF 0 1159 #define TCOM 1 /* command */ 1160 #define TPAREN 2 /* (c-list) */ 1161 #define TPIPE 3 /* a | b */ 1162 #define TLIST 4 /* a ; b */ 1163 #define TOR 5 /* || */ 1164 #define TAND 6 /* && */ 1165 #define TBANG 7 /* ! */ 1166 #define TDBRACKET 8 /* [[ .. ]] */ 1167 #define TFOR 9 1168 #define TSELECT 10 1169 #define TCASE 11 1170 #define TIF 12 1171 #define TWHILE 13 1172 #define TUNTIL 14 1173 #define TELIF 15 1174 #define TPAT 16 /* pattern in case */ 1175 #define TBRACE 17 /* {c-list} */ 1176 #define TASYNC 18 /* c & */ 1177 #define TFUNCT 19 /* function name { command; } */ 1178 #define TTIME 20 /* time pipeline */ 1179 #define TEXEC 21 /* fork/exec eval'd TCOM */ 1180 #define TCOPROC 22 /* coprocess |& */ 1181 1182 /* 1183 * prefix codes for words in command tree 1184 */ 1185 #define EOS 0 /* end of string */ 1186 #define CHAR 1 /* unquoted character */ 1187 #define QCHAR 2 /* quoted character */ 1188 #define COMSUB 3 /* $() substitution (0 terminated) */ 1189 #define EXPRSUB 4 /* $(()) substitution (0 terminated) */ 1190 #define OQUOTE 5 /* opening " or ' */ 1191 #define CQUOTE 6 /* closing " or ' */ 1192 #define OSUBST 7 /* opening ${ subst (followed by { or X) */ 1193 #define CSUBST 8 /* closing } of above (followed by } or X) */ 1194 #define OPAT 9 /* open pattern: *(, @(, etc. */ 1195 #define SPAT 10 /* separate pattern: | */ 1196 #define CPAT 11 /* close pattern: ) */ 1197 #define ADELIM 12 /* arbitrary delimiter: ${foo:2:3} ${foo/bar/baz} */ 1198 1199 /* 1200 * IO redirection 1201 */ 1202 struct ioword { 1203 int unit; /* unit affected */ 1204 int flag; /* action (below) */ 1205 char *name; /* file name (unused if heredoc) */ 1206 char *delim; /* delimiter for <<,<<- */ 1207 char *heredoc; /* content of heredoc */ 1208 }; 1209 1210 /* ioword.flag - type of redirection */ 1211 #define IOTYPE 0xF /* type: bits 0:3 */ 1212 #define IOREAD 0x1 /* < */ 1213 #define IOWRITE 0x2 /* > */ 1214 #define IORDWR 0x3 /* <>: todo */ 1215 #define IOHERE 0x4 /* << (here file) */ 1216 #define IOCAT 0x5 /* >> */ 1217 #define IODUP 0x6 /* <&/>& */ 1218 #define IOEVAL BIT(4) /* expand in << */ 1219 #define IOSKIP BIT(5) /* <<-, skip ^\t* */ 1220 #define IOCLOB BIT(6) /* >|, override -o noclobber */ 1221 #define IORDUP BIT(7) /* x<&y (as opposed to x>&y) */ 1222 #define IONAMEXP BIT(8) /* name has been expanded */ 1223 #define IOBASH BIT(9) /* &> etc. */ 1224 #define IOHERESTR BIT(10) /* <<< (here string) */ 1225 #define IONDELIM BIT(11) /* null delimiter (<<) */ 1226 1227 /* execute/exchild flags */ 1228 #define XEXEC BIT(0) /* execute without forking */ 1229 #define XFORK BIT(1) /* fork before executing */ 1230 #define XBGND BIT(2) /* command & */ 1231 #define XPIPEI BIT(3) /* input is pipe */ 1232 #define XPIPEO BIT(4) /* output is pipe */ 1233 #define XPIPE (XPIPEI|XPIPEO) /* member of pipe */ 1234 #define XXCOM BIT(5) /* `...` command */ 1235 #define XPCLOSE BIT(6) /* exchild: close close_fd in parent */ 1236 #define XCCLOSE BIT(7) /* exchild: close close_fd in child */ 1237 #define XERROK BIT(8) /* non-zero exit ok (for set -e) */ 1238 #define XCOPROC BIT(9) /* starting a co-process */ 1239 #define XTIME BIT(10) /* timing TCOM command */ 1240 #define XPIPEST BIT(11) /* want PIPESTATUS */ 1241 1242 /* 1243 * flags to control expansion of words (assumed by t->evalflags to fit 1244 * in a short) 1245 */ 1246 #define DOBLANK BIT(0) /* perform blank interpretation */ 1247 #define DOGLOB BIT(1) /* expand [?* */ 1248 #define DOPAT BIT(2) /* quote *?[ */ 1249 #define DOTILDE BIT(3) /* normal ~ expansion (first char) */ 1250 #define DONTRUNCOMMAND BIT(4) /* do not run $(command) things */ 1251 #define DOASNTILDE BIT(5) /* assignment ~ expansion (after =, :) */ 1252 #define DOBRACE BIT(6) /* used by expand(): do brace expansion */ 1253 #define DOMAGIC BIT(7) /* used by expand(): string contains MAGIC */ 1254 #define DOTEMP BIT(8) /* dito: in word part of ${..[%#=?]..} */ 1255 #define DOVACHECK BIT(9) /* var assign check (for typeset, set, etc) */ 1256 #define DOMARKDIRS BIT(10) /* force markdirs behaviour */ 1257 1258 /* 1259 * The arguments of [[ .. ]] expressions are kept in t->args[] and flags 1260 * indicating how the arguments have been munged are kept in t->vars[]. 1261 * The contents of t->vars[] are stuffed strings (so they can be treated 1262 * like all other t->vars[]) in which the second character is the one that 1263 * is examined. The DB_* defines are the values for these second characters. 1264 */ 1265 #define DB_NORM 1 /* normal argument */ 1266 #define DB_OR 2 /* || -> -o conversion */ 1267 #define DB_AND 3 /* && -> -a conversion */ 1268 #define DB_BE 4 /* an inserted -BE */ 1269 #define DB_PAT 5 /* a pattern argument */ 1270 1271 #define X_EXTRA 20 /* this many extra bytes in X string */ 1272 1273 typedef struct XString { 1274 char *end, *beg; /* end, begin of string */ 1275 size_t len; /* length */ 1276 Area *areap; /* area to allocate/free from */ 1277 } XString; 1278 1279 typedef char *XStringP; 1280 1281 /* initialise expandable string */ 1282 #define XinitN(xs, length, area) do { \ 1283 (xs).len = (length); \ 1284 (xs).areap = (area); \ 1285 (xs).beg = alloc((xs).len + X_EXTRA, (xs).areap); \ 1286 (xs).end = (xs).beg + (xs).len; \ 1287 } while (/* CONSTCOND */ 0) 1288 #define Xinit(xs, xp, length, area) do { \ 1289 XinitN((xs), (length), (area)); \ 1290 (xp) = (xs).beg; \ 1291 } while (/* CONSTCOND */ 0) 1292 1293 /* stuff char into string */ 1294 #define Xput(xs, xp, c) (*xp++ = (c)) 1295 1296 /* check if there are at least n bytes left */ 1297 #define XcheckN(xs, xp, n) do { \ 1298 ssize_t more = ((xp) + (n)) - (xs).end; \ 1299 if (more > 0) \ 1300 (xp) = Xcheck_grow_(&(xs), (xp), more); \ 1301 } while (/* CONSTCOND */ 0) 1302 1303 /* check for overflow, expand string */ 1304 #define Xcheck(xs, xp) XcheckN((xs), (xp), 1) 1305 1306 /* free string */ 1307 #define Xfree(xs, xp) afree((xs).beg, (xs).areap) 1308 1309 /* close, return string */ 1310 #define Xclose(xs, xp) aresize((xs).beg, (xp) - (xs).beg, (xs).areap) 1311 1312 /* begin of string */ 1313 #define Xstring(xs, xp) ((xs).beg) 1314 1315 #define Xnleft(xs, xp) ((xs).end - (xp)) /* may be less than 0 */ 1316 #define Xlength(xs, xp) ((xp) - (xs).beg) 1317 #define Xsize(xs, xp) ((xs).end - (xs).beg) 1318 #define Xsavepos(xs, xp) ((xp) - (xs).beg) 1319 #define Xrestpos(xs, xp, n) ((xs).beg + (n)) 1320 1321 char *Xcheck_grow_(XString *, const char *, size_t); 1322 1323 /* 1324 * expandable vector of generic pointers 1325 */ 1326 1327 typedef struct XPtrV { 1328 void **cur; /* next avail pointer */ 1329 void **beg, **end; /* begin, end of vector */ 1330 } XPtrV; 1331 1332 #define XPinit(x, n) do { \ 1333 void **XPinit_vp; \ 1334 XPinit_vp = alloc2((n), sizeof(void *), ATEMP); \ 1335 (x).cur = (x).beg = XPinit_vp; \ 1336 (x).end = XPinit_vp + (n); \ 1337 } while (/* CONSTCOND */ 0) 1338 1339 #define XPput(x, p) do { \ 1340 if ((x).cur >= (x).end) { \ 1341 size_t n = XPsize(x); \ 1342 (x).beg = aresize2((x).beg, \ 1343 n, 2 * sizeof(void *), ATEMP); \ 1344 (x).cur = (x).beg + n; \ 1345 (x).end = (x).cur + n; \ 1346 } \ 1347 *(x).cur++ = (p); \ 1348 } while (/* CONSTCOND */ 0) 1349 1350 #define XPptrv(x) ((x).beg) 1351 #define XPsize(x) ((x).cur - (x).beg) 1352 #define XPclose(x) aresize2((x).beg, XPsize(x), sizeof(void *), ATEMP) 1353 #define XPfree(x) afree((x).beg, ATEMP) 1354 1355 #define IDENT 64 1356 1357 typedef struct source Source; 1358 struct source { 1359 const char *str; /* input pointer */ 1360 const char *start; /* start of current buffer */ 1361 union { 1362 const char **strv; /* string [] */ 1363 struct shf *shf; /* shell file */ 1364 struct tbl *tblp; /* alias (SF_HASALIAS) */ 1365 char *freeme; /* also for SREREAD */ 1366 } u; 1367 const char *file; /* input file name */ 1368 int type; /* input type */ 1369 int line; /* line number */ 1370 int errline; /* line the error occurred on (0 if not set) */ 1371 int flags; /* SF_* */ 1372 Area *areap; 1373 Source *next; /* stacked source */ 1374 XString xs; /* input buffer */ 1375 char ugbuf[2]; /* buffer for ungetsc() (SREREAD) and 1376 * alias (SALIAS) */ 1377 }; 1378 1379 /* Source.type values */ 1380 #define SEOF 0 /* input EOF */ 1381 #define SFILE 1 /* file input */ 1382 #define SSTDIN 2 /* read stdin */ 1383 #define SSTRING 3 /* string */ 1384 #define SWSTR 4 /* string without \n */ 1385 #define SWORDS 5 /* string[] */ 1386 #define SWORDSEP 6 /* string[] separator */ 1387 #define SALIAS 7 /* alias expansion */ 1388 #define SREREAD 8 /* read ahead to be re-scanned */ 1389 1390 /* Source.flags values */ 1391 #define SF_ECHO BIT(0) /* echo input to shlout */ 1392 #define SF_ALIAS BIT(1) /* faking space at end of alias */ 1393 #define SF_ALIASEND BIT(2) /* faking space at end of alias */ 1394 #define SF_TTY BIT(3) /* type == SSTDIN & it is a tty */ 1395 #define SF_HASALIAS BIT(4) /* u.tblp valid (SALIAS, SEOF) */ 1396 1397 typedef union { 1398 int i; 1399 char *cp; 1400 char **wp; 1401 struct op *o; 1402 struct ioword *iop; 1403 } YYSTYPE; 1404 1405 /* If something is added here, add it to tokentab[] in syn.c as well */ 1406 #define LWORD 256 1407 #define LOGAND 257 /* && */ 1408 #define LOGOR 258 /* || */ 1409 #define BREAK 259 /* ;; */ 1410 #define IF 260 1411 #define THEN 261 1412 #define ELSE 262 1413 #define ELIF 263 1414 #define FI 264 1415 #define CASE 265 1416 #define ESAC 266 1417 #define FOR 267 1418 #define SELECT 268 1419 #define WHILE 269 1420 #define UNTIL 270 1421 #define DO 271 1422 #define DONE 272 1423 #define IN 273 1424 #define FUNCTION 274 1425 #define TIME 275 1426 #define REDIR 276 1427 #define MDPAREN 277 /* (( )) */ 1428 #define BANG 278 /* ! */ 1429 #define DBRACKET 279 /* [[ .. ]] */ 1430 #define COPROC 280 /* |& */ 1431 #define BRKEV 281 /* ;| */ 1432 #define BRKFT 282 /* ;& */ 1433 #define YYERRCODE 300 1434 1435 /* flags to yylex */ 1436 #define CONTIN BIT(0) /* skip new lines to complete command */ 1437 #define ONEWORD BIT(1) /* single word for substitute() */ 1438 #define ALIAS BIT(2) /* recognise alias */ 1439 #define KEYWORD BIT(3) /* recognise keywords */ 1440 #define LETEXPR BIT(4) /* get expression inside (( )) */ 1441 #define VARASN BIT(5) /* check for var=word */ 1442 #define ARRAYVAR BIT(6) /* parse x[1 & 2] as one word */ 1443 #define ESACONLY BIT(7) /* only accept esac keyword */ 1444 #define CMDWORD BIT(8) /* parsing simple command (alias related) */ 1445 #define HEREDELIM BIT(9) /* parsing <<,<<- delimiter */ 1446 #define LQCHAR BIT(10) /* source string contains QCHAR */ 1447 #define HEREDOC BIT(11) /* parsing a here document */ 1448 1449 #define HERES 10 /* max number of << in line */ 1450 1451 #undef CTRL 1452 #define CTRL(x) ((x) == '?' ? 0x7F : (x) & 0x1F) /* ASCII */ 1453 #define UNCTRL(x) ((x) ^ 0x40) /* ASCII */ 1454 1455 EXTERN Source *source; /* yyparse/yylex source */ 1456 EXTERN YYSTYPE yylval; /* result from yylex */ 1457 EXTERN struct ioword *heres[HERES], **herep; 1458 EXTERN char ident[IDENT+1]; 1459 1460 #define HISTORYSIZE 500 /* size of saved history */ 1461 1462 EXTERN char **history; /* saved commands */ 1463 EXTERN char **histptr; /* last history item */ 1464 EXTERN int histsize; /* history size */ 1465 1466 /* user and system time of last j_waitjed job */ 1467 EXTERN struct timeval j_usrtime, j_systime; 1468 1469 #define notoktomul(fac1, fac2) (((fac1) != 0) && ((fac2) != 0) && \ 1470 ((SIZE_MAX / (fac1)) < (fac2))) 1471 #define notoktoadd(val, cnst) ((val) > (SIZE_MAX - (cnst))) 1472 #define checkoktoadd(val, cnst) do { \ 1473 if (notoktoadd((val), (cnst))) \ 1474 internal_errorf(Tintovfl, (size_t)(val), \ 1475 '+', (size_t)(cnst)); \ 1476 } while (/* CONSTCOND */ 0) 1477 1478 1479 /* NZAT/NZAAT hashes based on Bob Jenkins' one-at-a-time hash */ 1480 1481 /* From: src/kern/include/nzat.h,v 1.2 2011/07/18 00:35:40 tg Exp $ */ 1482 1483 #define NZATInit(h) do { \ 1484 (h) = 0; \ 1485 } while (/* CONSTCOND */ 0) 1486 1487 #define NZATUpdateByte(h,b) do { \ 1488 (h) += (uint8_t)(b); \ 1489 ++(h); \ 1490 (h) += (h) << 10; \ 1491 (h) ^= (h) >> 6; \ 1492 } while (/* CONSTCOND */ 0) 1493 1494 #define NZATUpdateMem(h,p,z) do { \ 1495 register const uint8_t *NZATUpdateMem_p; \ 1496 register size_t NZATUpdateMem_z = (z); \ 1497 \ 1498 NZATUpdateMem_p = (const void *)(p); \ 1499 while (NZATUpdateMem_z--) \ 1500 NZATUpdateByte((h), *NZATUpdateMem_p++); \ 1501 } while (/* CONSTCOND */ 0) 1502 1503 #define NZATUpdateString(h,s) do { \ 1504 register const char *NZATUpdateString_s; \ 1505 register uint8_t NZATUpdateString_c; \ 1506 \ 1507 NZATUpdateString_s = (const void *)(s); \ 1508 while ((NZATUpdateString_c = *NZATUpdateString_s++)) \ 1509 NZATUpdateByte((h), NZATUpdateString_c); \ 1510 } while (/* CONSTCOND */ 0) 1511 1512 /* not zero after termination */ 1513 #define NZATFinish(h) do { \ 1514 if ((h) == 0) \ 1515 ++(h); \ 1516 else \ 1517 NZAATFinish(h); \ 1518 } while (/* CONSTCOND */ 0) 1519 1520 /* NULs zählen an allen Teilen */ 1521 #define NZAATFinish(h) do { \ 1522 (h) += (h) << 10; \ 1523 (h) ^= (h) >> 6; \ 1524 (h) += (h) << 3; \ 1525 (h) ^= (h) >> 11; \ 1526 (h) += (h) << 15; \ 1527 } while (/* CONSTCOND */ 0) 1528 1529 1530 /* lalloc.c */ 1531 void ainit(Area *); 1532 void afreeall(Area *); 1533 /* these cannot fail and can take NULL (not for ap) */ 1534 #define alloc(n, ap) aresize(NULL, (n), (ap)) 1535 #define alloc2(m, n, ap) aresize2(NULL, (m), (n), (ap)) 1536 void *aresize(void *, size_t, Area *); 1537 void *aresize2(void *, size_t, size_t, Area *); 1538 void afree(void *, Area *); /* can take NULL */ 1539 /* edit.c */ 1540 #ifndef MKSH_SMALL 1541 int x_bind(const char *, const char *, bool, bool); 1542 #else 1543 int x_bind(const char *, const char *, bool); 1544 #endif 1545 void x_init(void); 1546 void x_mkraw(int, struct termios *, bool); 1547 int x_read(char *, size_t); 1548 /* eval.c */ 1549 char *substitute(const char *, int); 1550 char **eval(const char **, int); 1551 char *evalstr(const char *cp, int); 1552 char *evalonestr(const char *cp, int); 1553 char *debunk(char *, const char *, size_t); 1554 void expand(const char *, XPtrV *, int); 1555 int glob_str(char *, XPtrV *, int); 1556 /* exec.c */ 1557 int execute(struct op * volatile, volatile int, volatile int * volatile); 1558 int shcomexec(const char **); 1559 struct tbl *findfunc(const char *, uint32_t, bool); 1560 int define(const char *, struct op *); 1561 const char *builtin(const char *, int (*)(const char **)); 1562 struct tbl *findcom(const char *, int); 1563 void flushcom(bool); 1564 const char *search_path(const char *, const char *, int, int *); 1565 int pr_menu(const char * const *); 1566 int pr_list(char * const *); 1567 /* expr.c */ 1568 int evaluate(const char *, mksh_ari_t *, int, bool); 1569 int v_evaluate(struct tbl *, const char *, volatile int, bool); 1570 /* UTF-8 stuff */ 1571 size_t utf_mbtowc(unsigned int *, const char *); 1572 size_t utf_wctomb(char *, unsigned int); 1573 int utf_widthadj(const char *, const char **); 1574 size_t utf_mbswidth(const char *); 1575 const char *utf_skipcols(const char *, int); 1576 size_t utf_ptradj(const char *); 1577 #ifndef MKSH_mirbsd_wcwidth 1578 int utf_wcwidth(unsigned int); 1579 #endif 1580 int ksh_access(const char *, int); 1581 /* funcs.c */ 1582 int c_hash(const char **); 1583 int c_pwd(const char **); 1584 int c_print(const char **); 1585 #ifdef MKSH_PRINTF_BUILTIN 1586 int c_printf(const char **); 1587 #endif 1588 int c_whence(const char **); 1589 int c_command(const char **); 1590 int c_typeset(const char **); 1591 int c_alias(const char **); 1592 int c_unalias(const char **); 1593 int c_let(const char **); 1594 int c_jobs(const char **); 1595 #ifndef MKSH_UNEMPLOYED 1596 int c_fgbg(const char **); 1597 #endif 1598 int c_kill(const char **); 1599 void getopts_reset(int); 1600 int c_getopts(const char **); 1601 int c_bind(const char **); 1602 int c_shift(const char **); 1603 int c_umask(const char **); 1604 int c_dot(const char **); 1605 int c_wait(const char **); 1606 int c_read(const char **); 1607 int c_eval(const char **); 1608 int c_trap(const char **); 1609 int c_brkcont(const char **); 1610 int c_exitreturn(const char **); 1611 int c_set(const char **); 1612 int c_unset(const char **); 1613 int c_ulimit(const char **); 1614 int c_times(const char **); 1615 int timex(struct op *, int, volatile int *); 1616 void timex_hook(struct op *, char ** volatile *); 1617 int c_exec(const char **); 1618 /* dummy function (just need pointer value), special case in comexec() */ 1619 #define c_builtin shcomexec 1620 int c_test(const char **); 1621 #if HAVE_MKNOD 1622 int c_mknod(const char **); 1623 #endif 1624 int c_realpath(const char **); 1625 int c_rename(const char **); 1626 int c_cat(const char **); 1627 int c_sleep(const char **); 1628 /* histrap.c */ 1629 void init_histvec(void); 1630 void hist_init(Source *); 1631 #if HAVE_PERSISTENT_HISTORY 1632 void hist_finish(void); 1633 #endif 1634 void histsave(int *, const char *, bool, bool); 1635 #if !defined(MKSH_SMALL) && HAVE_PERSISTENT_HISTORY 1636 bool histsync(void); 1637 #endif 1638 int c_fc(const char **); 1639 void sethistsize(int); 1640 #if HAVE_PERSISTENT_HISTORY 1641 void sethistfile(const char *); 1642 #endif 1643 char **histpos(void); 1644 int histnum(int); 1645 int findhist(int, int, const char *, int); 1646 char **hist_get_newest(bool); 1647 void inittraps(void); 1648 void alarm_init(void); 1649 Trap *gettrap(const char *, int); 1650 void trapsig(int); 1651 void intrcheck(void); 1652 int fatal_trap_check(void); 1653 int trap_pending(void); 1654 void runtraps(int intr); 1655 void runtrap(Trap *, bool); 1656 void cleartraps(void); 1657 void restoresigs(void); 1658 void settrap(Trap *, const char *); 1659 int block_pipe(void); 1660 void restore_pipe(int); 1661 int setsig(Trap *, sig_t, int); 1662 void setexecsig(Trap *, int); 1663 /* jobs.c */ 1664 void j_init(void); 1665 void j_exit(void); 1666 #ifndef MKSH_UNEMPLOYED 1667 void j_change(void); 1668 #endif 1669 int exchild(struct op *, int, volatile int *, int); 1670 void startlast(void); 1671 int waitlast(void); 1672 int waitfor(const char *, int *); 1673 int j_kill(const char *, int); 1674 #ifndef MKSH_UNEMPLOYED 1675 int j_resume(const char *, int); 1676 #endif 1677 int j_jobs(const char *, int, int); 1678 void j_notify(void); 1679 pid_t j_async(void); 1680 int j_stopped_running(void); 1681 /* lex.c */ 1682 int yylex(int); 1683 void yyerror(const char *, ...) 1684 MKSH_A_NORETURN 1685 MKSH_A_FORMAT(__printf__, 1, 2); 1686 Source *pushs(int, Area *); 1687 void set_prompt(int, Source *); 1688 void pprompt(const char *, int); 1689 int promptlen(const char *); 1690 /* main.c */ 1691 int include(const char *, int, const char **, int); 1692 int command(const char *, int); 1693 int shell(Source *volatile, int volatile); 1694 void unwind(int) MKSH_A_NORETURN; 1695 void newenv(int); 1696 void quitenv(struct shf *); 1697 void cleanup_parents_env(void); 1698 void cleanup_proc_env(void); 1699 void errorf(const char *, ...) 1700 MKSH_A_NORETURN 1701 MKSH_A_FORMAT(__printf__, 1, 2); 1702 void errorfx(int, const char *, ...) 1703 MKSH_A_NORETURN 1704 MKSH_A_FORMAT(__printf__, 2, 3); 1705 void warningf(bool, const char *, ...) 1706 MKSH_A_FORMAT(__printf__, 2, 3); 1707 void bi_errorf(const char *, ...) 1708 MKSH_A_FORMAT(__printf__, 1, 2); 1709 #define errorfz() errorf("\1") 1710 #define errorfxz(rc) errorfx((rc), "\1") 1711 #define bi_errorfz() bi_errorf("\1") 1712 void internal_errorf(const char *, ...) 1713 MKSH_A_NORETURN 1714 MKSH_A_FORMAT(__printf__, 1, 2); 1715 void internal_warningf(const char *, ...) 1716 MKSH_A_FORMAT(__printf__, 1, 2); 1717 void error_prefix(bool); 1718 void shellf(const char *, ...) 1719 MKSH_A_FORMAT(__printf__, 1, 2); 1720 void shprintf(const char *, ...) 1721 MKSH_A_FORMAT(__printf__, 1, 2); 1722 int can_seek(int); 1723 void initio(void); 1724 int ksh_dup2(int, int, bool); 1725 short savefd(int); 1726 void restfd(int, int); 1727 void openpipe(int *); 1728 void closepipe(int *); 1729 int check_fd(const char *, int, const char **); 1730 void coproc_init(void); 1731 void coproc_read_close(int); 1732 void coproc_readw_close(int); 1733 void coproc_write_close(int); 1734 int coproc_getfd(int, const char **); 1735 void coproc_cleanup(int); 1736 struct temp *maketemp(Area *, Temp_type, struct temp **); 1737 void ktinit(Area *, struct table *, uint8_t); 1738 struct tbl *ktscan(struct table *, const char *, uint32_t, struct tbl ***); 1739 /* table, name (key) to search for, hash(n) */ 1740 #define ktsearch(tp, s, h) ktscan((tp), (s), (h), NULL) 1741 struct tbl *ktenter(struct table *, const char *, uint32_t); 1742 #define ktdelete(p) do { p->flag = 0; } while (/* CONSTCOND */ 0) 1743 void ktwalk(struct tstate *, struct table *); 1744 struct tbl *ktnext(struct tstate *); 1745 struct tbl **ktsort(struct table *); 1746 /* misc.c */ 1747 void setctypes(const char *, int); 1748 void initctypes(void); 1749 size_t option(const char *); 1750 char *getoptions(void); 1751 void change_flag(enum sh_flag, int, unsigned int); 1752 int parse_args(const char **, int, bool *); 1753 int getn(const char *, int *); 1754 int bi_getn(const char *, int *); 1755 int gmatchx(const char *, const char *, bool); 1756 int has_globbing(const char *, const char *); 1757 int xstrcmp(const void *, const void *); 1758 void ksh_getopt_reset(Getopt *, int); 1759 int ksh_getopt(const char **, Getopt *, const char *); 1760 void print_value_quoted(const char *); 1761 char *quote_value(const char *); 1762 void print_columns(struct shf *, int, 1763 char *(*)(char *, size_t, int, const void *), 1764 const void *, size_t, size_t, bool); 1765 void strip_nuls(char *, int); 1766 ssize_t blocking_read(int, char *, size_t) 1767 MKSH_A_BOUNDED(__buffer__, 2, 3); 1768 int reset_nonblock(int); 1769 char *ksh_get_wd(void); 1770 char *do_realpath(const char *); 1771 void simplify_path(char *); 1772 void set_current_wd(const char *); 1773 int c_cd(const char **); 1774 #ifdef MKSH_SMALL 1775 char *strdup_(const char *, Area *); 1776 char *strndup_(const char *, size_t, Area *); 1777 #endif 1778 int unbksl(bool, int (*)(void), void (*)(int)); 1779 /* shf.c */ 1780 struct shf *shf_open(const char *, int, int, int); 1781 struct shf *shf_fdopen(int, int, struct shf *); 1782 struct shf *shf_reopen(int, int, struct shf *); 1783 struct shf *shf_sopen(char *, ssize_t, int, struct shf *); 1784 int shf_close(struct shf *); 1785 int shf_fdclose(struct shf *); 1786 char *shf_sclose(struct shf *); 1787 int shf_flush(struct shf *); 1788 ssize_t shf_read(char *, ssize_t, struct shf *); 1789 char *shf_getse(char *, ssize_t, struct shf *); 1790 int shf_getchar(struct shf *s); 1791 int shf_ungetc(int, struct shf *); 1792 #ifdef MKSH_SMALL 1793 int shf_getc(struct shf *); 1794 int shf_putc(int, struct shf *); 1795 #else 1796 #define shf_getc shf_getc_ 1797 #define shf_putc shf_putc_ 1798 #endif 1799 int shf_putchar(int, struct shf *); 1800 ssize_t shf_puts(const char *, struct shf *); 1801 ssize_t shf_write(const char *, ssize_t, struct shf *); 1802 ssize_t shf_fprintf(struct shf *, const char *, ...) 1803 MKSH_A_FORMAT(__printf__, 2, 3); 1804 ssize_t shf_snprintf(char *, ssize_t, const char *, ...) 1805 MKSH_A_FORMAT(__printf__, 3, 4) 1806 MKSH_A_BOUNDED(__string__, 1, 2); 1807 char *shf_smprintf(const char *, ...) 1808 MKSH_A_FORMAT(__printf__, 1, 2); 1809 ssize_t shf_vfprintf(struct shf *, const char *, va_list) 1810 MKSH_A_FORMAT(__printf__, 2, 0); 1811 /* syn.c */ 1812 void initkeywords(void); 1813 struct op *compile(Source *, bool); 1814 bool parse_usec(const char *, struct timeval *); 1815 char *yyrecursive(void); 1816 /* tree.c */ 1817 void fptreef(struct shf *, int, const char *, ...); 1818 char *snptreef(char *, ssize_t, const char *, ...); 1819 struct op *tcopy(struct op *, Area *); 1820 char *wdcopy(const char *, Area *); 1821 const char *wdscan(const char *, int); 1822 #define WDS_TPUTS BIT(0) /* tputS (dumpwdvar) mode */ 1823 #define WDS_KEEPQ BIT(1) /* keep quote characters */ 1824 #define WDS_MAGIC BIT(2) /* make MAGIC */ 1825 char *wdstrip(const char *, int); 1826 void tfree(struct op *, Area *); 1827 void dumpchar(struct shf *, int); 1828 void dumptree(struct shf *, struct op *); 1829 void dumpwdvar(struct shf *, const char *); 1830 void vistree(char *, size_t, struct op *) 1831 MKSH_A_BOUNDED(__string__, 1, 2); 1832 void fpFUNCTf(struct shf *, int, bool, const char *, struct op *); 1833 /* var.c */ 1834 void newblock(void); 1835 void popblock(void); 1836 void initvar(void); 1837 struct tbl *global(const char *); 1838 struct tbl *local(const char *, bool); 1839 char *str_val(struct tbl *); 1840 int setstr(struct tbl *, const char *, int); 1841 struct tbl *setint_v(struct tbl *, struct tbl *, bool); 1842 void setint(struct tbl *, mksh_ari_t); 1843 void setint_n(struct tbl *, mksh_ari_t); 1844 struct tbl *typeset(const char *, uint32_t, uint32_t, int, int) 1845 MKSH_A_NONNULL((__nonnull__ (1))); 1846 void unset(struct tbl *, int); 1847 const char *skip_varname(const char *, int); 1848 const char *skip_wdvarname(const char *, bool); 1849 int is_wdvarname(const char *, bool); 1850 int is_wdvarassign(const char *); 1851 struct tbl *arraysearch(struct tbl *, uint32_t); 1852 char **makenv(void); 1853 void change_winsz(void); 1854 size_t array_ref_len(const char *); 1855 char *arrayname(const char *); 1856 mksh_uari_t set_array(const char *, bool, const char **); 1857 uint32_t hash(const void *); 1858 void rndset(long); 1859 1860 enum Test_op { 1861 /* non-operator */ 1862 TO_NONOP = 0, 1863 /* unary operators */ 1864 TO_STNZE, TO_STZER, TO_OPTION, 1865 TO_FILAXST, 1866 TO_FILEXST, 1867 TO_FILREG, TO_FILBDEV, TO_FILCDEV, TO_FILSYM, TO_FILFIFO, TO_FILSOCK, 1868 TO_FILCDF, TO_FILID, TO_FILGID, TO_FILSETG, TO_FILSTCK, TO_FILUID, 1869 TO_FILRD, TO_FILGZ, TO_FILTT, TO_FILSETU, TO_FILWR, TO_FILEX, 1870 /* binary operators */ 1871 TO_STEQL, TO_STNEQ, TO_STLT, TO_STGT, TO_INTEQ, TO_INTNE, TO_INTGT, 1872 TO_INTGE, TO_INTLT, TO_INTLE, TO_FILEQ, TO_FILNT, TO_FILOT, 1873 /* not an operator */ 1874 TO_NONNULL /* !TO_NONOP */ 1875 }; 1876 typedef enum Test_op Test_op; 1877 1878 /* Used by Test_env.isa() (order important - used to index *_tokens[] arrays) */ 1879 enum Test_meta { 1880 TM_OR, /* -o or || */ 1881 TM_AND, /* -a or && */ 1882 TM_NOT, /* ! */ 1883 TM_OPAREN, /* ( */ 1884 TM_CPAREN, /* ) */ 1885 TM_UNOP, /* unary operator */ 1886 TM_BINOP, /* binary operator */ 1887 TM_END /* end of input */ 1888 }; 1889 typedef enum Test_meta Test_meta; 1890 1891 #define TEF_ERROR BIT(0) /* set if we've hit an error */ 1892 #define TEF_DBRACKET BIT(1) /* set if [[ .. ]] test */ 1893 1894 typedef struct test_env { 1895 union { 1896 const char **wp; /* used by ptest_* */ 1897 XPtrV *av; /* used by dbtestp_* */ 1898 } pos; 1899 const char **wp_end; /* used by ptest_* */ 1900 Test_op (*isa)(struct test_env *, Test_meta); 1901 const char *(*getopnd) (struct test_env *, Test_op, bool); 1902 int (*eval)(struct test_env *, Test_op, const char *, const char *, bool); 1903 void (*error)(struct test_env *, int, const char *); 1904 int flags; /* TEF_* */ 1905 } Test_env; 1906 1907 extern const char *const dbtest_tokens[]; 1908 1909 Test_op test_isop(Test_meta, const char *); 1910 int test_eval(Test_env *, Test_op, const char *, const char *, bool); 1911 int test_parse(Test_env *); 1912 1913 EXTERN int tty_fd E_INIT(-1); /* dup'd tty file descriptor */ 1914 EXTERN bool tty_devtty; /* true if tty_fd is from /dev/tty */ 1915 EXTERN struct termios tty_state; /* saved tty state */ 1916 1917 extern void tty_init(bool, bool); 1918 extern void tty_close(void); 1919 1920 /* be sure not to interfere with anyone else's idea about EXTERN */ 1921 #ifdef EXTERN_DEFINED 1922 # undef EXTERN_DEFINED 1923 # undef EXTERN 1924 #endif 1925 #undef E_INIT 1926 1927 #endif /* !MKSH_INCLUDES_ONLY */ 1928