1 /* $OpenBSD: exec.c,v 1.52 2015/09/10 22:48:58 nicm Exp $ */ 2 3 /*- 4 * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 5 * 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 6 * 2019 7 * mirabilos <m (at) mirbsd.org> 8 * 9 * Provided that these terms and disclaimer and all copyright notices 10 * are retained or reproduced in an accompanying document, permission 11 * is granted to deal in this work without restriction, including un- 12 * limited rights to use, publicly perform, distribute, sell, modify, 13 * merge, give away, or sublicence. 14 * 15 * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to 16 * the utmost extent permitted by applicable law, neither express nor 17 * implied; without malicious intent or gross negligence. In no event 18 * may a licensor, author or contributor be held liable for indirect, 19 * direct, other damage, loss, or other issues arising in any way out 20 * of dealing in the work, even if advised of the possibility of such 21 * damage or existence of a defect, except proven that it results out 22 * of said person's immediate fault when using the work as intended. 23 */ 24 25 #include "sh.h" 26 27 __RCSID("$MirOS: src/bin/mksh/exec.c,v 1.206 2019/03/01 16:17:53 tg Exp $"); 28 29 #ifndef MKSH_DEFAULT_EXECSHELL 30 #define MKSH_DEFAULT_EXECSHELL MKSH_UNIXROOT "/bin/sh" 31 #endif 32 33 static int comexec(struct op *, struct tbl * volatile, const char **, 34 int volatile, volatile int *); 35 static void scriptexec(struct op *, const char **) MKSH_A_NORETURN; 36 static int call_builtin(struct tbl *, const char **, const char *, bool); 37 static int iosetup(struct ioword *, struct tbl *); 38 static const char *do_selectargs(const char **, bool); 39 static Test_op dbteste_isa(Test_env *, Test_meta); 40 static const char *dbteste_getopnd(Test_env *, Test_op, bool); 41 static void dbteste_error(Test_env *, int, const char *); 42 /* XXX: horrible kludge to fit within the framework */ 43 static void plain_fmt_entry(char *, size_t, unsigned int, const void *); 44 static void select_fmt_entry(char *, size_t, unsigned int, const void *); 45 46 /* 47 * execute command tree 48 */ 49 int 50 execute(struct op * volatile t, 51 /* if XEXEC don't fork */ 52 volatile int flags, 53 volatile int * volatile xerrok) 54 { 55 int i; 56 volatile int rv = 0, dummy = 0; 57 int pv[2]; 58 const char ** volatile ap = NULL; 59 char ** volatile up; 60 const char *s, *ccp; 61 struct ioword **iowp; 62 struct tbl *tp = NULL; 63 64 if (t == NULL) 65 return (0); 66 67 /* Caller doesn't care if XERROK should propagate. */ 68 if (xerrok == NULL) 69 xerrok = &dummy; 70 71 if ((flags&XFORK) && !(flags&XEXEC) && t->type != TPIPE) 72 /* run in sub-process */ 73 return (exchild(t, flags & ~XTIME, xerrok, -1)); 74 75 newenv(E_EXEC); 76 if (trap) 77 runtraps(0); 78 79 /* we want to run an executable, do some variance checks */ 80 if (t->type == TCOM) { 81 /* 82 * Clear subst_exstat before argument expansion. Used by 83 * null commands (see comexec() and c_eval()) and by c_set(). 84 */ 85 subst_exstat = 0; 86 87 /* for $LINENO */ 88 current_lineno = t->lineno; 89 90 /* check if this is 'var=<<EOF' */ 91 if ( 92 /* we have zero arguments, i.e. no program to run */ 93 t->args[0] == NULL && 94 /* we have exactly one variable assignment */ 95 t->vars[0] != NULL && t->vars[1] == NULL && 96 /* we have exactly one I/O redirection */ 97 t->ioact != NULL && t->ioact[0] != NULL && 98 t->ioact[1] == NULL && 99 /* of type "here document" (or "here string") */ 100 (t->ioact[0]->ioflag & IOTYPE) == IOHERE && 101 /* the variable assignment begins with a valid varname */ 102 (ccp = skip_wdvarname(t->vars[0], true)) != t->vars[0] && 103 /* and has no right-hand side (i.e. "varname=") */ 104 ccp[0] == CHAR && ((ccp[1] == '=' && ccp[2] == EOS) || 105 /* or "varname+=" */ (ccp[1] == '+' && ccp[2] == CHAR && 106 ccp[3] == '=' && ccp[4] == EOS))) { 107 char *cp, *dp; 108 109 if ((rv = herein(t->ioact[0], &cp) /*? 1 : 0*/)) 110 cp = NULL; 111 dp = shf_smprintf(Tf_ss, evalstr(t->vars[0], 112 DOASNTILDE | DOSCALAR), rv ? null : cp); 113 typeset(dp, Flag(FEXPORT) ? EXPORT : 0, 0, 0, 0); 114 /* free the expanded value */ 115 afree(cp, APERM); 116 afree(dp, ATEMP); 117 goto Break; 118 } 119 120 /* 121 * POSIX says expand command words first, then redirections, 122 * and assignments last.. 123 */ 124 up = eval(t->args, t->u.evalflags | DOBLANK | DOGLOB | DOTILDE); 125 if (flags & XTIME) 126 /* Allow option parsing (bizarre, but POSIX) */ 127 timex_hook(t, &up); 128 ap = (const char **)up; 129 if (ap[0]) 130 tp = findcom(ap[0], FC_BI|FC_FUNC); 131 } 132 flags &= ~XTIME; 133 134 if (t->ioact != NULL || t->type == TPIPE || t->type == TCOPROC) { 135 e->savefd = alloc2(NUFILE, sizeof(short), ATEMP); 136 /* initialise to not redirected */ 137 memset(e->savefd, 0, NUFILE * sizeof(short)); 138 } 139 140 /* mark for replacement later (unless TPIPE) */ 141 vp_pipest->flag |= INT_L; 142 143 /* do redirection, to be restored in quitenv() */ 144 if (t->ioact != NULL) 145 for (iowp = t->ioact; *iowp != NULL; iowp++) { 146 if (iosetup(*iowp, tp) < 0) { 147 exstat = rv = 1; 148 /* 149 * Redirection failures for special commands 150 * cause (non-interactive) shell to exit. 151 */ 152 if (tp && tp->type == CSHELL && 153 (tp->flag & SPEC_BI)) 154 errorfz(); 155 /* Deal with FERREXIT, quitenv(), etc. */ 156 goto Break; 157 } 158 } 159 160 switch (t->type) { 161 case TCOM: 162 rv = comexec(t, tp, (const char **)ap, flags, xerrok); 163 break; 164 165 case TPAREN: 166 rv = execute(t->left, flags | XFORK, xerrok); 167 break; 168 169 case TPIPE: 170 flags |= XFORK; 171 flags &= ~XEXEC; 172 e->savefd[0] = savefd(0); 173 e->savefd[1] = savefd(1); 174 while (t->type == TPIPE) { 175 openpipe(pv); 176 /* stdout of curr */ 177 ksh_dup2(pv[1], 1, false); 178 /** 179 * Let exchild() close pv[0] in child 180 * (if this isn't done, commands like 181 * (: ; cat /etc/termcap) | sleep 1 182 * will hang forever). 183 */ 184 exchild(t->left, flags | XPIPEO | XCCLOSE, 185 NULL, pv[0]); 186 /* stdin of next */ 187 ksh_dup2(pv[0], 0, false); 188 closepipe(pv); 189 flags |= XPIPEI; 190 t = t->right; 191 } 192 /* stdout of last */ 193 restfd(1, e->savefd[1]); 194 /* no need to re-restore this */ 195 e->savefd[1] = 0; 196 /* Let exchild() close 0 in parent, after fork, before wait */ 197 i = exchild(t, flags | XPCLOSE | XPIPEST, xerrok, 0); 198 if (!(flags&XBGND) && !(flags&XXCOM)) 199 rv = i; 200 break; 201 202 case TLIST: 203 while (t->type == TLIST) { 204 execute(t->left, flags & XERROK, NULL); 205 t = t->right; 206 } 207 rv = execute(t, flags & XERROK, xerrok); 208 break; 209 210 case TCOPROC: { 211 #ifndef MKSH_NOPROSPECTOFWORK 212 sigset_t omask; 213 214 /* 215 * Block sigchild as we are using things changed in the 216 * signal handler 217 */ 218 sigprocmask(SIG_BLOCK, &sm_sigchld, &omask); 219 e->type = E_ERRH; 220 if ((i = kshsetjmp(e->jbuf))) { 221 sigprocmask(SIG_SETMASK, &omask, NULL); 222 quitenv(NULL); 223 unwind(i); 224 /* NOTREACHED */ 225 } 226 #endif 227 /* Already have a (live) co-process? */ 228 if (coproc.job && coproc.write >= 0) 229 errorf("coprocess already exists"); 230 231 /* Can we re-use the existing co-process pipe? */ 232 coproc_cleanup(true); 233 234 /* do this before opening pipes, in case these fail */ 235 e->savefd[0] = savefd(0); 236 e->savefd[1] = savefd(1); 237 238 openpipe(pv); 239 if (pv[0] != 0) { 240 ksh_dup2(pv[0], 0, false); 241 close(pv[0]); 242 } 243 coproc.write = pv[1]; 244 coproc.job = NULL; 245 246 if (coproc.readw >= 0) 247 ksh_dup2(coproc.readw, 1, false); 248 else { 249 openpipe(pv); 250 coproc.read = pv[0]; 251 ksh_dup2(pv[1], 1, false); 252 /* closed before first read */ 253 coproc.readw = pv[1]; 254 coproc.njobs = 0; 255 /* create new coprocess id */ 256 ++coproc.id; 257 } 258 #ifndef MKSH_NOPROSPECTOFWORK 259 sigprocmask(SIG_SETMASK, &omask, NULL); 260 /* no more need for error handler */ 261 e->type = E_EXEC; 262 #endif 263 264 /* 265 * exchild() closes coproc.* in child after fork, 266 * will also increment coproc.njobs when the 267 * job is actually created. 268 */ 269 flags &= ~XEXEC; 270 exchild(t->left, flags | XBGND | XFORK | XCOPROC | XCCLOSE, 271 NULL, coproc.readw); 272 break; 273 } 274 275 case TASYNC: 276 /* 277 * XXX non-optimal, I think - "(foo &)", forks for (), 278 * forks again for async... parent should optimise 279 * this to "foo &"... 280 */ 281 rv = execute(t->left, (flags&~XEXEC)|XBGND|XFORK, xerrok); 282 break; 283 284 case TOR: 285 case TAND: 286 rv = execute(t->left, XERROK, NULL); 287 if ((rv == 0) == (t->type == TAND)) 288 rv = execute(t->right, flags & XERROK, xerrok); 289 else { 290 flags |= XERROK; 291 if (xerrok) 292 *xerrok = 1; 293 } 294 break; 295 296 case TBANG: 297 rv = !execute(t->right, XERROK, xerrok); 298 flags |= XERROK; 299 if (xerrok) 300 *xerrok = 1; 301 break; 302 303 case TDBRACKET: { 304 Test_env te; 305 306 te.flags = TEF_DBRACKET; 307 te.pos.wp = t->args; 308 te.isa = dbteste_isa; 309 te.getopnd = dbteste_getopnd; 310 te.eval = test_eval; 311 te.error = dbteste_error; 312 313 rv = test_parse(&te); 314 break; 315 } 316 317 case TFOR: 318 case TSELECT: { 319 volatile bool is_first = true; 320 321 ap = (t->vars == NULL) ? e->loc->argv + 1 : 322 (const char **)eval((const char **)t->vars, 323 DOBLANK | DOGLOB | DOTILDE); 324 e->type = E_LOOP; 325 while ((i = kshsetjmp(e->jbuf))) { 326 if ((e->flags&EF_BRKCONT_PASS) || 327 (i != LBREAK && i != LCONTIN)) { 328 quitenv(NULL); 329 unwind(i); 330 } else if (i == LBREAK) { 331 rv = 0; 332 goto Break; 333 } 334 } 335 /* in case of a continue */ 336 rv = 0; 337 if (t->type == TFOR) { 338 while (*ap != NULL) { 339 setstr(global(t->str), *ap++, KSH_UNWIND_ERROR); 340 rv = execute(t->left, flags & XERROK, xerrok); 341 } 342 } else { 343 do_TSELECT: 344 if ((ccp = do_selectargs(ap, is_first))) { 345 is_first = false; 346 setstr(global(t->str), ccp, KSH_UNWIND_ERROR); 347 execute(t->left, flags & XERROK, xerrok); 348 goto do_TSELECT; 349 } 350 rv = 1; 351 } 352 break; 353 } 354 355 case TWHILE: 356 case TUNTIL: 357 e->type = E_LOOP; 358 while ((i = kshsetjmp(e->jbuf))) { 359 if ((e->flags&EF_BRKCONT_PASS) || 360 (i != LBREAK && i != LCONTIN)) { 361 quitenv(NULL); 362 unwind(i); 363 } else if (i == LBREAK) { 364 rv = 0; 365 goto Break; 366 } 367 } 368 /* in case of a continue */ 369 rv = 0; 370 while ((execute(t->left, XERROK, NULL) == 0) == 371 (t->type == TWHILE)) 372 rv = execute(t->right, flags & XERROK, xerrok); 373 break; 374 375 case TIF: 376 case TELIF: 377 if (t->right == NULL) 378 /* should be error */ 379 break; 380 rv = execute(execute(t->left, XERROK, NULL) == 0 ? 381 t->right->left : t->right->right, flags & XERROK, xerrok); 382 break; 383 384 case TCASE: 385 i = 0; 386 ccp = evalstr(t->str, DOTILDE | DOSCALAR); 387 for (t = t->left; t != NULL && t->type == TPAT; t = t->right) { 388 for (ap = (const char **)t->vars; *ap; ap++) { 389 if (i || ((s = evalstr(*ap, DOTILDE|DOPAT)) && 390 gmatchx(ccp, s, false))) { 391 record_match(ccp); 392 rv = execute(t->left, flags & XERROK, 393 xerrok); 394 i = 0; 395 switch (t->u.charflag) { 396 case '&': 397 i = 1; 398 /* FALLTHROUGH */ 399 case '|': 400 goto TCASE_next; 401 } 402 goto TCASE_out; 403 } 404 } 405 i = 0; 406 TCASE_next: 407 /* empty */; 408 } 409 TCASE_out: 410 break; 411 412 case TBRACE: 413 rv = execute(t->left, flags & XERROK, xerrok); 414 break; 415 416 case TFUNCT: 417 rv = define(t->str, t); 418 break; 419 420 case TTIME: 421 /* 422 * Clear XEXEC so nested execute() call doesn't exit 423 * (allows "ls -l | time grep foo"). 424 */ 425 rv = timex(t, flags & ~XEXEC, xerrok); 426 break; 427 428 case TEXEC: 429 /* an eval'd TCOM */ 430 up = makenv(); 431 restoresigs(); 432 cleanup_proc_env(); 433 /* I/O redirection cleanup to be done in child process */ 434 if (!Flag(FPOSIX) && !Flag(FSH) && t->left->ioact != NULL) 435 for (iowp = t->left->ioact; *iowp != NULL; iowp++) 436 if ((*iowp)->ioflag & IODUPSELF) 437 fcntl((*iowp)->unit, F_SETFD, 0); 438 /* try to execute */ 439 { 440 union mksh_ccphack cargs; 441 442 cargs.ro = t->args; 443 execve(t->str, cargs.rw, up); 444 rv = errno; 445 } 446 if (rv == ENOEXEC) 447 scriptexec(t, (const char **)up); 448 else 449 errorf(Tf_sD_s, t->str, cstrerror(rv)); 450 } 451 Break: 452 exstat = rv & 0xFF; 453 if (vp_pipest->flag & INT_L) { 454 unset(vp_pipest, 1); 455 vp_pipest->flag = DEFINED | ISSET | INTEGER | RDONLY | 456 ARRAY | INT_U | INT_L; 457 vp_pipest->val.i = rv; 458 } 459 460 /* restores IO */ 461 quitenv(NULL); 462 if ((flags&XEXEC)) 463 /* exit child */ 464 unwind(LEXIT); 465 if (rv != 0 && !(flags & XERROK) && 466 (xerrok == NULL || !*xerrok)) { 467 if (Flag(FERREXIT) & 0x80) { 468 /* inside eval */ 469 Flag(FERREXIT) = 0; 470 } else { 471 trapsig(ksh_SIGERR); 472 if (Flag(FERREXIT)) 473 unwind(LERROR); 474 } 475 } 476 return (rv); 477 } 478 479 /* 480 * execute simple command 481 */ 482 483 static int 484 comexec(struct op *t, struct tbl * volatile tp, const char **ap, 485 volatile int flags, volatile int *xerrok) 486 { 487 int i; 488 volatile int rv = 0; 489 const char *cp; 490 const char **lastp; 491 /* Must be static (XXX but why?) */ 492 static struct op texec; 493 int type_flags; 494 bool resetspec; 495 int fcflags = FC_BI|FC_FUNC|FC_PATH; 496 struct block *l_expand, *l_assign; 497 int optc; 498 const char *exec_argv0 = NULL; 499 bool exec_clrenv = false; 500 501 /* snag the last argument for $_ */ 502 if (Flag(FTALKING) && *(lastp = ap)) { 503 /* 504 * XXX not the same as AT&T ksh, which only seems to set $_ 505 * after a newline (but not in functions/dot scripts, but in 506 * interactive and script) - perhaps save last arg here and 507 * set it in shell()?. 508 */ 509 while (*++lastp) 510 ; 511 /* setstr() can't fail here */ 512 setstr(typeset("_", LOCAL, 0, INTEGER, 0), *--lastp, 513 KSH_RETURN_ERROR); 514 } 515 516 /** 517 * Deal with the shell builtins builtin, exec and command since 518 * they can be followed by other commands. This must be done before 519 * we know if we should create a local block which must be done 520 * before we can do a path search (in case the assignments change 521 * PATH). 522 * Odd cases: 523 * FOO=bar exec >/dev/null FOO is kept but not exported 524 * FOO=bar exec foobar FOO is exported 525 * FOO=bar command exec >/dev/null FOO is neither kept nor exported 526 * FOO=bar command FOO is neither kept nor exported 527 * PATH=... foobar use new PATH in foobar search 528 */ 529 resetspec = false; 530 while (tp && tp->type == CSHELL) { 531 /* undo effects of command */ 532 fcflags = FC_BI|FC_FUNC|FC_PATH; 533 if (tp->val.f == c_builtin) { 534 if ((cp = *++ap) == NULL || 535 (!strcmp(cp, "--") && (cp = *++ap) == NULL)) { 536 tp = NULL; 537 break; 538 } 539 if ((tp = findcom(cp, FC_BI)) == NULL) 540 errorf(Tf_sD_sD_s, Tbuiltin, cp, Tnot_found); 541 if (tp->type == CSHELL && (tp->flag & LOW_BI)) 542 break; 543 continue; 544 } else if (tp->val.f == c_exec) { 545 if (ap[1] == NULL) 546 break; 547 ksh_getopt_reset(&builtin_opt, GF_ERROR); 548 while ((optc = ksh_getopt(ap, &builtin_opt, "a:c")) != -1) 549 switch (optc) { 550 case 'a': 551 exec_argv0 = builtin_opt.optarg; 552 break; 553 case 'c': 554 exec_clrenv = true; 555 /* ensure we can actually do this */ 556 resetspec = true; 557 break; 558 default: 559 rv = 2; 560 goto Leave; 561 } 562 ap += builtin_opt.optind; 563 flags |= XEXEC; 564 /* POSuX demands ksh88-like behaviour here */ 565 if (Flag(FPOSIX)) 566 fcflags = FC_PATH; 567 } else if (tp->val.f == c_command) { 568 bool saw_p = false; 569 570 /* 571 * Ugly dealing with options in two places (here 572 * and in c_command(), but such is life) 573 */ 574 ksh_getopt_reset(&builtin_opt, 0); 575 while ((optc = ksh_getopt(ap, &builtin_opt, ":p")) == 'p') 576 saw_p = true; 577 if (optc != -1) 578 /* command -vV or something */ 579 break; 580 /* don't look for functions */ 581 fcflags = FC_BI|FC_PATH; 582 if (saw_p) { 583 if (Flag(FRESTRICTED)) { 584 warningf(true, Tf_sD_s, 585 "command -p", "restricted"); 586 rv = 1; 587 goto Leave; 588 } 589 fcflags |= FC_DEFPATH; 590 } 591 ap += builtin_opt.optind; 592 /* 593 * POSIX says special builtins lose their status 594 * if accessed using command. 595 */ 596 resetspec = true; 597 if (!ap[0]) { 598 /* ensure command with no args exits with 0 */ 599 subst_exstat = 0; 600 break; 601 } 602 } else if (tp->flag & LOW_BI) { 603 /* if we have any flags, do not use the builtin */ 604 if ((ap[1] && ap[1][0] == '-' && ap[1][1] != '\0' && 605 /* argument, begins with -, is not - or -- */ 606 (ap[1][1] != '-' || ap[1][2] != '\0')) || 607 /* always prefer the external utility */ 608 (tp->flag & LOWER_BI)) { 609 struct tbl *ext_cmd; 610 611 ext_cmd = findcom(tp->name, FC_PATH | FC_FUNC); 612 if (ext_cmd && (ext_cmd->type != CTALIAS || 613 (ext_cmd->flag & ISSET))) 614 tp = ext_cmd; 615 } 616 break; 617 } else if (tp->val.f == c_trap) { 618 t->u.evalflags &= ~DOTCOMEXEC; 619 break; 620 } else 621 break; 622 tp = findcom(ap[0], fcflags & (FC_BI|FC_FUNC)); 623 } 624 if (t->u.evalflags & DOTCOMEXEC) 625 flags |= XEXEC; 626 l_expand = e->loc; 627 if (!resetspec && (!ap[0] || (tp && (tp->flag & KEEPASN)))) 628 type_flags = 0; 629 else { 630 /* create new variable/function block */ 631 newblock(); 632 /* ksh functions don't keep assignments, POSIX functions do. */ 633 if (!resetspec && tp && tp->type == CFUNC && 634 !(tp->flag & FKSH)) 635 type_flags = EXPORT; 636 else 637 type_flags = LOCAL|LOCAL_COPY|EXPORT; 638 } 639 l_assign = e->loc; 640 if (exec_clrenv) 641 l_assign->flags |= BF_STOPENV; 642 if (Flag(FEXPORT)) 643 type_flags |= EXPORT; 644 if (Flag(FXTRACE)) 645 change_xtrace(2, false); 646 for (i = 0; t->vars[i]; i++) { 647 /* do NOT lookup in the new var/fn block just created */ 648 e->loc = l_expand; 649 cp = evalstr(t->vars[i], DOASNTILDE | DOSCALAR); 650 e->loc = l_assign; 651 if (Flag(FXTRACE)) { 652 const char *ccp; 653 654 ccp = skip_varname(cp, true); 655 if (*ccp == '+') 656 ++ccp; 657 if (*ccp == '=') 658 ++ccp; 659 shf_write(cp, ccp - cp, shl_xtrace); 660 print_value_quoted(shl_xtrace, ccp); 661 shf_putc(' ', shl_xtrace); 662 } 663 /* but assign in there as usual */ 664 typeset(cp, type_flags, 0, 0, 0); 665 } 666 667 if (Flag(FXTRACE)) { 668 change_xtrace(2, false); 669 if (ap[rv = 0]) { 670 xtrace_ap_loop: 671 print_value_quoted(shl_xtrace, ap[rv]); 672 if (ap[++rv]) { 673 shf_putc(' ', shl_xtrace); 674 goto xtrace_ap_loop; 675 } 676 } 677 change_xtrace(1, false); 678 } 679 680 if ((cp = *ap) == NULL) { 681 rv = subst_exstat; 682 goto Leave; 683 } else if (!tp) { 684 if (Flag(FRESTRICTED) && mksh_vdirsep(cp)) { 685 warningf(true, Tf_sD_s, cp, "restricted"); 686 rv = 1; 687 goto Leave; 688 } 689 tp = findcom(cp, fcflags); 690 } 691 692 switch (tp->type) { 693 694 /* shell built-in */ 695 case CSHELL: 696 do_call_builtin: 697 rv = call_builtin(tp, (const char **)ap, null, resetspec); 698 if (resetspec && tp->val.f == c_shift) { 699 l_expand->argc = l_assign->argc; 700 l_expand->argv = l_assign->argv; 701 } 702 break; 703 704 /* function call */ 705 case CFUNC: { 706 volatile uint32_t old_inuse; 707 const char * volatile old_kshname; 708 volatile uint8_t old_flags[FNFLAGS]; 709 710 if (!(tp->flag & ISSET)) { 711 struct tbl *ftp; 712 713 if (!tp->u.fpath) { 714 fpath_error: 715 rv = (tp->u2.errnov == ENOENT) ? 127 : 126; 716 warningf(true, Tf_sD_s_sD_s, cp, 717 Tcant_find, Tfile_fd, 718 cstrerror(tp->u2.errnov)); 719 break; 720 } 721 errno = 0; 722 if (include(tp->u.fpath, 0, NULL, false) < 0 || 723 !(ftp = findfunc(cp, hash(cp), false)) || 724 !(ftp->flag & ISSET)) { 725 rv = errno; 726 if ((ftp = findcom(cp, FC_BI)) && 727 (ftp->type == CSHELL) && 728 (ftp->flag & LOW_BI)) { 729 tp = ftp; 730 goto do_call_builtin; 731 } 732 if (rv) { 733 tp->u2.errnov = rv; 734 cp = tp->u.fpath; 735 goto fpath_error; 736 } 737 warningf(true, Tf_sD_s_s, cp, 738 "function not defined by", tp->u.fpath); 739 rv = 127; 740 break; 741 } 742 tp = ftp; 743 } 744 745 /* 746 * ksh functions set $0 to function name, POSIX 747 * functions leave $0 unchanged. 748 */ 749 old_kshname = kshname; 750 if (tp->flag & FKSH) 751 kshname = ap[0]; 752 else 753 ap[0] = kshname; 754 e->loc->argv = ap; 755 for (i = 0; *ap++ != NULL; i++) 756 ; 757 e->loc->argc = i - 1; 758 /* 759 * ksh-style functions handle getopts sanely, 760 * Bourne/POSIX functions are insane... 761 */ 762 if (tp->flag & FKSH) { 763 e->loc->flags |= BF_DOGETOPTS; 764 e->loc->getopts_state = user_opt; 765 getopts_reset(1); 766 } 767 768 for (type_flags = 0; type_flags < FNFLAGS; ++type_flags) 769 old_flags[type_flags] = shell_flags[type_flags]; 770 change_xtrace((Flag(FXTRACEREC) ? Flag(FXTRACE) : 0) | 771 ((tp->flag & TRACE) ? 1 : 0), false); 772 old_inuse = tp->flag & FINUSE; 773 tp->flag |= FINUSE; 774 775 e->type = E_FUNC; 776 if (!(i = kshsetjmp(e->jbuf))) { 777 execute(tp->val.t, flags & XERROK, NULL); 778 i = LRETURN; 779 } 780 781 kshname = old_kshname; 782 change_xtrace(old_flags[(int)FXTRACE], false); 783 #ifndef MKSH_LEGACY_MODE 784 if (tp->flag & FKSH) { 785 /* Korn style functions restore Flags on return */ 786 old_flags[(int)FXTRACE] = Flag(FXTRACE); 787 for (type_flags = 0; type_flags < FNFLAGS; ++type_flags) 788 shell_flags[type_flags] = old_flags[type_flags]; 789 } 790 #endif 791 tp->flag = (tp->flag & ~FINUSE) | old_inuse; 792 793 /* 794 * Were we deleted while executing? If so, free the 795 * execution tree. 796 */ 797 if ((tp->flag & (FDELETE|FINUSE)) == FDELETE) { 798 if (tp->flag & ALLOC) { 799 tp->flag &= ~ALLOC; 800 tfree(tp->val.t, tp->areap); 801 } 802 tp->flag = 0; 803 } 804 switch (i) { 805 case LRETURN: 806 case LERROR: 807 rv = exstat & 0xFF; 808 break; 809 case LINTR: 810 case LEXIT: 811 case LLEAVE: 812 case LSHELL: 813 quitenv(NULL); 814 unwind(i); 815 /* NOTREACHED */ 816 default: 817 quitenv(NULL); 818 internal_errorf(Tunexpected_type, Tunwind, Tfunction, i); 819 } 820 break; 821 } 822 823 /* executable command */ 824 case CEXEC: 825 /* tracked alias */ 826 case CTALIAS: 827 if (!(tp->flag&ISSET)) { 828 if (tp->u2.errnov == ENOENT) { 829 rv = 127; 830 warningf(true, Tf_sD_s_s, cp, 831 "inaccessible or", Tnot_found); 832 } else { 833 rv = 126; 834 warningf(true, Tf_sD_sD_s, cp, "can't execute", 835 cstrerror(tp->u2.errnov)); 836 } 837 break; 838 } 839 840 /* set $_ to program's full path */ 841 /* setstr() can't fail here */ 842 setstr(typeset("_", LOCAL | EXPORT, 0, INTEGER, 0), 843 tp->val.s, KSH_RETURN_ERROR); 844 845 /* to fork, we set up a TEXEC node and call execute */ 846 texec.type = TEXEC; 847 /* for vistree/dumptree */ 848 texec.left = t; 849 texec.str = tp->val.s; 850 texec.args = ap; 851 852 /* in this case we do not fork, of course */ 853 if (flags & XEXEC) { 854 if (exec_argv0) 855 texec.args[0] = exec_argv0; 856 j_exit(); 857 if (!(flags & XBGND) 858 #ifndef MKSH_UNEMPLOYED 859 || Flag(FMONITOR) 860 #endif 861 ) { 862 setexecsig(&sigtraps[SIGINT], SS_RESTORE_ORIG); 863 setexecsig(&sigtraps[SIGQUIT], SS_RESTORE_ORIG); 864 } 865 } 866 867 rv = exchild(&texec, flags, xerrok, -1); 868 break; 869 } 870 Leave: 871 if (flags & XEXEC) { 872 exstat = rv & 0xFF; 873 unwind(LEXIT); 874 } 875 return (rv); 876 } 877 878 static void 879 scriptexec(struct op *tp, const char **ap) 880 { 881 const char *sh; 882 #ifndef MKSH_SMALL 883 int fd; 884 unsigned char buf[68]; 885 #endif 886 union mksh_ccphack args, cap; 887 888 sh = str_val(global(TEXECSHELL)); 889 if (sh && *sh) 890 sh = search_path(sh, path, X_OK, NULL); 891 if (!sh || !*sh) 892 sh = MKSH_DEFAULT_EXECSHELL; 893 894 *tp->args-- = tp->str; 895 896 #ifndef MKSH_SMALL 897 if ((fd = binopen2(tp->str, O_RDONLY | O_MAYEXEC)) >= 0) { 898 unsigned char *cp; 899 #ifndef MKSH_EBCDIC 900 unsigned short m; 901 #endif 902 ssize_t n; 903 904 #if defined(__OS2__) && defined(MKSH_WITH_TEXTMODE) 905 setmode(fd, O_TEXT); 906 #endif 907 /* read first couple of octets from file */ 908 n = read(fd, buf, sizeof(buf) - 1); 909 close(fd); 910 /* read error or short read? */ 911 if (n < 5) 912 goto nomagic; 913 /* terminate buffer */ 914 buf[n] = '\0'; 915 916 /* skip UTF-8 Byte Order Mark, if present */ 917 cp = buf + (n = ((buf[0] == 0xEF) && (buf[1] == 0xBB) && 918 (buf[2] == 0xBF)) ? 3 : 0); 919 920 /* scan for newline or NUL (end of buffer) */ 921 while (!ctype(*cp, C_NL | C_NUL)) 922 ++cp; 923 /* if the shebang line is longer than MAXINTERP, bail out */ 924 if (!*cp) 925 goto noshebang; 926 /* replace newline by NUL */ 927 *cp = '\0'; 928 929 /* restore start of shebang position (buf+0 or buf+3) */ 930 cp = buf + n; 931 /* bail out if no shebang magic found */ 932 if (cp[0] == '#' && cp[1] == '!') 933 cp += 2; 934 #ifdef __OS2__ 935 else if (!strncmp(cp, Textproc, 7) && 936 ctype(cp[7], C_BLANK)) 937 cp += 8; 938 #endif 939 else 940 goto noshebang; 941 /* skip whitespace before shell name */ 942 while (ctype(*cp, C_BLANK)) 943 ++cp; 944 /* just whitespace on the line? */ 945 if (*cp == '\0') 946 goto noshebang; 947 /* no, we actually found an interpreter name */ 948 sh = (char *)cp; 949 /* look for end of shell/interpreter name */ 950 while (!ctype(*cp, C_BLANK | C_NUL)) 951 ++cp; 952 /* any arguments? */ 953 if (*cp) { 954 *cp++ = '\0'; 955 /* skip spaces before arguments */ 956 while (ctype(*cp, C_BLANK)) 957 ++cp; 958 /* pass it all in ONE argument (historic reasons) */ 959 if (*cp) 960 *tp->args-- = (char *)cp; 961 } 962 #ifdef __OS2__ 963 /* 964 * On OS/2, the directory structure differs from normal 965 * Unix, which can make many scripts whose shebang 966 * hardcodes the path to an interpreter fail (and there 967 * might be no /usr/bin/env); for user convenience, if 968 * the specified interpreter is not usable, do a PATH 969 * search to find it. 970 */ 971 if (mksh_vdirsep(sh) && !search_path(sh, path, X_OK, NULL)) { 972 cp = search_path(_getname(sh), path, X_OK, NULL); 973 if (cp) 974 sh = cp; 975 } 976 #endif 977 goto nomagic; 978 noshebang: 979 #ifndef MKSH_EBCDIC 980 m = buf[0] << 8 | buf[1]; 981 if (m == 0x7F45 && buf[2] == 'L' && buf[3] == 'F') 982 errorf("%s: not executable: %d-bit ELF file", tp->str, 983 32 * buf[4]); 984 if ((m == /* OMAGIC */ 0407) || 985 (m == /* NMAGIC */ 0410) || 986 (m == /* ZMAGIC */ 0413) || 987 (m == /* QMAGIC */ 0314) || 988 (m == /* ECOFF_I386 */ 0x4C01) || 989 (m == /* ECOFF_M68K */ 0x0150 || m == 0x5001) || 990 (m == /* ECOFF_SH */ 0x0500 || m == 0x0005) || 991 (m == /* bzip */ 0x425A) || (m == /* "MZ" */ 0x4D5A) || 992 (m == /* "NE" */ 0x4E45) || (m == /* "LX" */ 0x4C58) || 993 (m == /* ksh93 */ 0x0B13) || (m == /* LZIP */ 0x4C5A) || 994 (m == /* xz */ 0xFD37 && buf[2] == 'z' && buf[3] == 'X' && 995 buf[4] == 'Z') || (m == /* 7zip */ 0x377A) || 996 (m == /* gzip */ 0x1F8B) || (m == /* .Z */ 0x1F9D)) 997 errorf("%s: not executable: magic %04X", tp->str, m); 998 #endif 999 #ifdef __OS2__ 1000 cp = _getext(tp->str); 1001 if (cp && (!stricmp(cp, ".cmd") || !stricmp(cp, ".bat"))) { 1002 /* execute .cmd and .bat with OS2_SHELL, usually CMD.EXE */ 1003 sh = str_val(global("OS2_SHELL")); 1004 *tp->args-- = "/c"; 1005 /* convert slahes to backslashes */ 1006 for (cp = tp->str; *cp; cp++) { 1007 if (*cp == '/') 1008 *cp = '\\'; 1009 } 1010 } 1011 #endif 1012 nomagic: 1013 ; 1014 } 1015 #endif 1016 args.ro = tp->args; 1017 *args.ro = sh; 1018 1019 cap.ro = ap; 1020 execve(args.rw[0], args.rw, cap.rw); 1021 1022 /* report both the program that was run and the bogus interpreter */ 1023 errorf(Tf_sD_sD_s, tp->str, sh, cstrerror(errno)); 1024 } 1025 1026 /* actual 'builtin' built-in utility call is handled in comexec() */ 1027 int 1028 c_builtin(const char **wp) 1029 { 1030 return (call_builtin(get_builtin(*wp), wp, Tbuiltin, false)); 1031 } 1032 1033 struct tbl * 1034 get_builtin(const char *s) 1035 { 1036 return (s && *s ? ktsearch(&builtins, s, hash(s)) : NULL); 1037 } 1038 1039 /* 1040 * Search function tables for a function. If create set, a table entry 1041 * is created if none is found. 1042 */ 1043 struct tbl * 1044 findfunc(const char *name, uint32_t h, bool create) 1045 { 1046 struct block *l; 1047 struct tbl *tp = NULL; 1048 1049 for (l = e->loc; l; l = l->next) { 1050 tp = ktsearch(&l->funs, name, h); 1051 if (tp) 1052 break; 1053 if (!l->next && create) { 1054 tp = ktenter(&l->funs, name, h); 1055 tp->flag = DEFINED; 1056 tp->type = CFUNC; 1057 tp->val.t = NULL; 1058 break; 1059 } 1060 } 1061 return (tp); 1062 } 1063 1064 /* 1065 * define function. Returns 1 if function is being undefined (t == 0) and 1066 * function did not exist, returns 0 otherwise. 1067 */ 1068 int 1069 define(const char *name, struct op *t) 1070 { 1071 uint32_t nhash; 1072 struct tbl *tp; 1073 bool was_set = false; 1074 1075 nhash = hash(name); 1076 1077 while (/* CONSTCOND */ 1) { 1078 tp = findfunc(name, nhash, true); 1079 1080 if (tp->flag & ISSET) 1081 was_set = true; 1082 /* 1083 * If this function is currently being executed, we zap 1084 * this table entry so findfunc() won't see it 1085 */ 1086 if (tp->flag & FINUSE) { 1087 tp->name[0] = '\0'; 1088 /* ensure it won't be found */ 1089 tp->flag &= ~DEFINED; 1090 tp->flag |= FDELETE; 1091 } else 1092 break; 1093 } 1094 1095 if (tp->flag & ALLOC) { 1096 tp->flag &= ~(ISSET|ALLOC|FKSH); 1097 tfree(tp->val.t, tp->areap); 1098 } 1099 1100 if (t == NULL) { 1101 /* undefine */ 1102 ktdelete(tp); 1103 return (was_set ? 0 : 1); 1104 } 1105 1106 tp->val.t = tcopy(t->left, tp->areap); 1107 tp->flag |= (ISSET|ALLOC); 1108 if (t->u.ksh_func) 1109 tp->flag |= FKSH; 1110 1111 return (0); 1112 } 1113 1114 /* 1115 * add builtin 1116 */ 1117 const char * 1118 builtin(const char *name, int (*func) (const char **)) 1119 { 1120 struct tbl *tp; 1121 uint32_t flag = DEFINED; 1122 1123 /* see if any flags should be set for this builtin */ 1124 flags_loop: 1125 switch (*name) { 1126 case '=': 1127 /* command does variable assignment */ 1128 flag |= KEEPASN; 1129 break; 1130 case '*': 1131 /* POSIX special builtin */ 1132 flag |= SPEC_BI; 1133 break; 1134 case '~': 1135 /* external utility overrides built-in utility, always */ 1136 flag |= LOWER_BI; 1137 /* FALLTHROUGH */ 1138 case '!': 1139 /* external utility overrides built-in utility, with flags */ 1140 flag |= LOW_BI; 1141 break; 1142 case '-': 1143 /* is declaration utility if argv[1] is one (POSIX: command) */ 1144 flag |= DECL_FWDR; 1145 break; 1146 case '^': 1147 /* is declaration utility (POSIX: export, readonly) */ 1148 flag |= DECL_UTIL; 1149 break; 1150 default: 1151 goto flags_seen; 1152 } 1153 ++name; 1154 goto flags_loop; 1155 flags_seen: 1156 1157 /* enter into the builtins hash table */ 1158 tp = ktenter(&builtins, name, hash(name)); 1159 tp->flag = flag; 1160 tp->type = CSHELL; 1161 tp->val.f = func; 1162 1163 /* return name, for direct builtin call check in main.c */ 1164 return (name); 1165 } 1166 1167 /* 1168 * find command 1169 * either function, hashed command, or built-in (in that order) 1170 */ 1171 struct tbl * 1172 findcom(const char *name, int flags) 1173 { 1174 static struct tbl temp; 1175 uint32_t h = hash(name); 1176 struct tbl *tp = NULL, *tbi; 1177 /* insert if not found */ 1178 unsigned char insert = Flag(FTRACKALL); 1179 /* for function autoloading */ 1180 char *fpath; 1181 union mksh_cchack npath; 1182 1183 if (mksh_vdirsep(name)) { 1184 insert = 0; 1185 /* prevent FPATH search below */ 1186 flags &= ~FC_FUNC; 1187 goto Search; 1188 } 1189 tbi = (flags & FC_BI) ? ktsearch(&builtins, name, h) : NULL; 1190 /* 1191 * POSIX says special builtins first, then functions, then 1192 * regular builtins, then search path... 1193 */ 1194 if ((flags & FC_SPECBI) && tbi && (tbi->flag & SPEC_BI)) 1195 tp = tbi; 1196 if (!tp && (flags & FC_FUNC)) { 1197 tp = findfunc(name, h, false); 1198 if (tp && !(tp->flag & ISSET)) { 1199 if ((fpath = str_val(global(TFPATH))) == null) { 1200 tp->u.fpath = NULL; 1201 tp->u2.errnov = ENOENT; 1202 } else 1203 tp->u.fpath = search_path(name, fpath, R_OK, 1204 &tp->u2.errnov); 1205 } 1206 } 1207 if (!tp && (flags & FC_NORMBI) && tbi) 1208 tp = tbi; 1209 if (!tp && (flags & FC_PATH) && !(flags & FC_DEFPATH)) { 1210 tp = ktsearch(&taliases, name, h); 1211 if (tp && (tp->flag & ISSET) && 1212 ksh_access(tp->val.s, X_OK) != 0) { 1213 if (tp->flag & ALLOC) { 1214 tp->flag &= ~ALLOC; 1215 afree(tp->val.s, APERM); 1216 } 1217 tp->flag &= ~ISSET; 1218 } 1219 } 1220 1221 Search: 1222 if ((!tp || (tp->type == CTALIAS && !(tp->flag&ISSET))) && 1223 (flags & FC_PATH)) { 1224 if (!tp) { 1225 if (insert && !(flags & FC_DEFPATH)) { 1226 tp = ktenter(&taliases, name, h); 1227 tp->type = CTALIAS; 1228 } else { 1229 tp = &temp; 1230 tp->type = CEXEC; 1231 } 1232 /* make ~ISSET */ 1233 tp->flag = DEFINED; 1234 } 1235 npath.ro = search_path(name, 1236 (flags & FC_DEFPATH) ? def_path : path, 1237 X_OK, &tp->u2.errnov); 1238 if (npath.ro) { 1239 strdupx(tp->val.s, npath.ro, APERM); 1240 if (npath.ro != name) 1241 afree(npath.rw, ATEMP); 1242 tp->flag |= ISSET|ALLOC; 1243 } else if ((flags & FC_FUNC) && 1244 (fpath = str_val(global(TFPATH))) != null && 1245 (npath.ro = search_path(name, fpath, R_OK, 1246 &tp->u2.errnov)) != NULL) { 1247 /* 1248 * An undocumented feature of AT&T ksh is that 1249 * it searches FPATH if a command is not found, 1250 * even if the command hasn't been set up as an 1251 * autoloaded function (ie, no typeset -uf). 1252 */ 1253 tp = &temp; 1254 tp->type = CFUNC; 1255 /* make ~ISSET */ 1256 tp->flag = DEFINED; 1257 tp->u.fpath = npath.ro; 1258 } 1259 } 1260 return (tp); 1261 } 1262 1263 /* 1264 * flush executable commands with relative paths 1265 * (just relative or all?) 1266 */ 1267 void 1268 flushcom(bool all) 1269 { 1270 struct tbl *tp; 1271 struct tstate ts; 1272 1273 for (ktwalk(&ts, &taliases); (tp = ktnext(&ts)) != NULL; ) 1274 if ((tp->flag&ISSET) && (all || !mksh_abspath(tp->val.s))) { 1275 if (tp->flag&ALLOC) { 1276 tp->flag &= ~(ALLOC|ISSET); 1277 afree(tp->val.s, APERM); 1278 } 1279 tp->flag &= ~ISSET; 1280 } 1281 } 1282 1283 /* check if path is something we want to find */ 1284 int 1285 search_access(const char *fn, int mode) 1286 { 1287 struct stat sb; 1288 1289 if (stat(fn, &sb) < 0) 1290 /* file does not exist */ 1291 return (ENOENT); 1292 /* LINTED use of access */ 1293 if (access(fn, mode) < 0) { 1294 /* file exists, but we can't access it */ 1295 int eno; 1296 1297 eno = errno; 1298 return (eno ? eno : EACCES); 1299 } 1300 #ifdef __OS2__ 1301 /* treat all files as executable on OS/2 */ 1302 sb.st_mode |= S_IXUSR | S_IXGRP | S_IXOTH; 1303 #endif 1304 if (mode == X_OK && (!S_ISREG(sb.st_mode) || 1305 !(sb.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))) 1306 /* access(2) may say root can execute everything */ 1307 return (S_ISDIR(sb.st_mode) ? EISDIR : EACCES); 1308 return (0); 1309 } 1310 1311 #ifdef __OS2__ 1312 /* check if path is something we want to find, adding executable extensions */ 1313 #define search_access(fn, mode) access_ex((search_access), (fn), (mode)) 1314 #else 1315 #define search_access(fn, mode) (search_access)((fn), (mode)) 1316 #endif 1317 1318 /* 1319 * search for command with PATH 1320 */ 1321 const char * 1322 search_path(const char *name, const char *lpath, 1323 /* R_OK or X_OK */ 1324 int mode, 1325 /* set if candidate found, but not suitable */ 1326 int *errnop) 1327 { 1328 const char *sp, *p; 1329 char *xp; 1330 XString xs; 1331 size_t namelen; 1332 int ec = 0, ev; 1333 1334 if (mksh_vdirsep(name)) { 1335 if ((ec = search_access(name, mode)) == 0) { 1336 search_path_ok: 1337 if (errnop) 1338 *errnop = 0; 1339 #ifndef __OS2__ 1340 return (name); 1341 #else 1342 return (real_exec_name(name)); 1343 #endif 1344 } 1345 goto search_path_err; 1346 } 1347 1348 namelen = strlen(name) + 1; 1349 Xinit(xs, xp, 128, ATEMP); 1350 1351 sp = lpath; 1352 while (sp != NULL) { 1353 xp = Xstring(xs, xp); 1354 if (!(p = cstrchr(sp, MKSH_PATHSEPC))) 1355 p = strnul(sp); 1356 if (p != sp) { 1357 XcheckN(xs, xp, p - sp); 1358 memcpy(xp, sp, p - sp); 1359 xp += p - sp; 1360 #ifdef __OS2__ 1361 if (xp > Xstring(xs, xp) && mksh_cdirsep(xp[-1])) 1362 xp--; 1363 #endif 1364 *xp++ = '/'; 1365 } 1366 sp = p; 1367 XcheckN(xs, xp, namelen); 1368 memcpy(xp, name, namelen); 1369 if ((ev = search_access(Xstring(xs, xp), mode)) == 0) { 1370 name = Xclose(xs, xp + namelen); 1371 goto search_path_ok; 1372 } 1373 /* accumulate non-ENOENT errors only */ 1374 if (ev != ENOENT && ec == 0) 1375 ec = ev; 1376 if (*sp++ == '\0') 1377 sp = NULL; 1378 } 1379 Xfree(xs, xp); 1380 search_path_err: 1381 if (errnop) 1382 *errnop = ec ? ec : ENOENT; 1383 return (NULL); 1384 } 1385 1386 static int 1387 call_builtin(struct tbl *tp, const char **wp, const char *where, bool resetspec) 1388 { 1389 int rv; 1390 1391 if (!tp) 1392 internal_errorf(Tf_sD_s, where, wp[0]); 1393 builtin_argv0 = wp[0]; 1394 builtin_spec = tobool(!resetspec && (tp->flag & SPEC_BI)); 1395 shf_reopen(1, SHF_WR, shl_stdout); 1396 shl_stdout_ok = true; 1397 ksh_getopt_reset(&builtin_opt, GF_ERROR); 1398 rv = (*tp->val.f)(wp); 1399 shf_flush(shl_stdout); 1400 shl_stdout_ok = false; 1401 builtin_argv0 = NULL; 1402 builtin_spec = false; 1403 return (rv); 1404 } 1405 1406 /* 1407 * set up redirection, saving old fds in e->savefd 1408 */ 1409 static int 1410 iosetup(struct ioword *iop, struct tbl *tp) 1411 { 1412 int u = -1; 1413 char *cp = iop->ioname; 1414 int iotype = iop->ioflag & IOTYPE; 1415 bool do_open = true, do_close = false, do_fstat = false; 1416 int flags = 0; 1417 struct ioword iotmp; 1418 struct stat statb; 1419 1420 if (iotype != IOHERE) 1421 cp = evalonestr(cp, DOTILDE|(Flag(FTALKING_I) ? DOGLOB : 0)); 1422 1423 /* Used for tracing and error messages to print expanded cp */ 1424 iotmp = *iop; 1425 iotmp.ioname = (iotype == IOHERE) ? NULL : cp; 1426 iotmp.ioflag |= IONAMEXP; 1427 1428 if (Flag(FXTRACE)) { 1429 change_xtrace(2, false); 1430 fptreef(shl_xtrace, 0, Tft_R, &iotmp); 1431 change_xtrace(1, false); 1432 } 1433 1434 switch (iotype) { 1435 case IOREAD: 1436 flags = O_RDONLY; 1437 break; 1438 1439 case IOCAT: 1440 flags = O_WRONLY | O_APPEND | O_CREAT; 1441 break; 1442 1443 case IOWRITE: 1444 if (Flag(FNOCLOBBER) && !(iop->ioflag & IOCLOB)) { 1445 /* >file under set -C */ 1446 if (stat(cp, &statb)) { 1447 /* nonexistent file */ 1448 flags = O_WRONLY | O_CREAT | O_EXCL; 1449 } else if (S_ISREG(statb.st_mode)) { 1450 /* regular file, refuse clobbering */ 1451 goto clobber_refused; 1452 } else { 1453 /* 1454 * allow redirections to things 1455 * like /dev/null without error 1456 */ 1457 flags = O_WRONLY; 1458 /* but check again after opening */ 1459 do_fstat = true; 1460 } 1461 } else { 1462 /* >|file or set +C */ 1463 flags = O_WRONLY | O_CREAT | O_TRUNC; 1464 } 1465 break; 1466 1467 case IORDWR: 1468 flags = O_RDWR | O_CREAT; 1469 break; 1470 1471 case IOHERE: 1472 do_open = false; 1473 /* herein() returns -2 if error has been printed */ 1474 u = herein(iop, NULL); 1475 /* cp may have wrong name */ 1476 break; 1477 1478 case IODUP: { 1479 const char *emsg; 1480 1481 do_open = false; 1482 if (ksh_isdash(cp)) { 1483 /* prevent error return below */ 1484 u = 1009; 1485 do_close = true; 1486 } else if ((u = check_fd(cp, 1487 X_OK | ((iop->ioflag & IORDUP) ? R_OK : W_OK), 1488 &emsg)) < 0) { 1489 char *sp; 1490 1491 warningf(true, Tf_sD_s, 1492 (sp = snptreef(NULL, 32, Tft_R, &iotmp)), emsg); 1493 afree(sp, ATEMP); 1494 return (-1); 1495 } 1496 if (u == (int)iop->unit) { 1497 /* "dup from" == "dup to" */ 1498 iop->ioflag |= IODUPSELF; 1499 return (0); 1500 } 1501 break; 1502 } 1503 } 1504 1505 if (do_open) { 1506 if (Flag(FRESTRICTED) && (flags & O_CREAT)) { 1507 warningf(true, Tf_sD_s, cp, "restricted"); 1508 return (-1); 1509 } 1510 u = binopen3(cp, flags, 0666); 1511 if (do_fstat && u >= 0) { 1512 /* prevent race conditions */ 1513 if (fstat(u, &statb) || S_ISREG(statb.st_mode)) { 1514 close(u); 1515 clobber_refused: 1516 u = -1; 1517 errno = EEXIST; 1518 } 1519 } 1520 } 1521 if (u < 0) { 1522 /* herein() may already have printed message */ 1523 if (u == -1) { 1524 u = errno; 1525 warningf(true, Tf_cant_ss_s, 1526 #if 0 1527 /* can't happen */ 1528 iotype == IODUP ? "dup" : 1529 #endif 1530 (iotype == IOREAD || iotype == IOHERE) ? 1531 Topen : Tcreate, cp, cstrerror(u)); 1532 } 1533 return (-1); 1534 } 1535 /* Do not save if it has already been redirected (i.e. "cat >x >y"). */ 1536 if (e->savefd[iop->unit] == 0) { 1537 /* If these are the same, it means unit was previously closed */ 1538 if (u == (int)iop->unit) 1539 e->savefd[iop->unit] = -1; 1540 else 1541 /* 1542 * c_exec() assumes e->savefd[fd] set for any 1543 * redirections. Ask savefd() not to close iop->unit; 1544 * this allows error messages to be seen if iop->unit 1545 * is 2; also means we can't lose the fd (eg, both 1546 * dup2 below and dup2 in restfd() failing). 1547 */ 1548 e->savefd[iop->unit] = savefd(iop->unit); 1549 } 1550 1551 if (do_close) 1552 close(iop->unit); 1553 else if (u != (int)iop->unit) { 1554 if (ksh_dup2(u, iop->unit, true) < 0) { 1555 int eno; 1556 char *sp; 1557 1558 eno = errno; 1559 warningf(true, Tf_s_sD_s, Tredirection_dup, 1560 (sp = snptreef(NULL, 32, Tft_R, &iotmp)), 1561 cstrerror(eno)); 1562 afree(sp, ATEMP); 1563 if (iotype != IODUP) 1564 close(u); 1565 return (-1); 1566 } 1567 if (iotype != IODUP) 1568 close(u); 1569 /* 1570 * Touching any co-process fd in an empty exec 1571 * causes the shell to close its copies 1572 */ 1573 else if (tp && tp->type == CSHELL && tp->val.f == c_exec) { 1574 if (iop->ioflag & IORDUP) 1575 /* possible exec <&p */ 1576 coproc_read_close(u); 1577 else 1578 /* possible exec >&p */ 1579 coproc_write_close(u); 1580 } 1581 } 1582 if (u == 2) 1583 /* Clear any write errors */ 1584 shf_reopen(2, SHF_WR, shl_out); 1585 return (0); 1586 } 1587 1588 /* 1589 * Process here documents by providing the content, either as 1590 * result (globally allocated) string or in a temp file; if 1591 * unquoted, the string is expanded first. 1592 */ 1593 static int 1594 hereinval(struct ioword *iop, int sub, char **resbuf, struct shf *shf) 1595 { 1596 const char * volatile ccp = iop->heredoc; 1597 struct source *s, *osource; 1598 1599 osource = source; 1600 newenv(E_ERRH); 1601 if (kshsetjmp(e->jbuf)) { 1602 source = osource; 1603 quitenv(shf); 1604 /* special to iosetup(): don't print error */ 1605 return (-2); 1606 } 1607 if (iop->ioflag & IOHERESTR) { 1608 ccp = evalstr(iop->delim, DOHERESTR | DOSCALAR | DOHEREDOC); 1609 } else if (sub) { 1610 /* do substitutions on the content of heredoc */ 1611 s = pushs(SSTRING, ATEMP); 1612 s->start = s->str = ccp; 1613 source = s; 1614 if (yylex(sub) != LWORD) 1615 internal_errorf("herein: yylex"); 1616 source = osource; 1617 ccp = evalstr(yylval.cp, DOSCALAR | DOHEREDOC); 1618 } 1619 1620 if (resbuf == NULL) 1621 shf_puts(ccp, shf); 1622 else 1623 strdupx(*resbuf, ccp, APERM); 1624 1625 quitenv(NULL); 1626 return (0); 1627 } 1628 1629 int 1630 herein(struct ioword *iop, char **resbuf) 1631 { 1632 int fd = -1; 1633 struct shf *shf; 1634 struct temp *h; 1635 int i; 1636 1637 /* lexer substitution flags */ 1638 i = (iop->ioflag & IOEVAL) ? (ONEWORD | HEREDOC) : 0; 1639 1640 /* skip all the fd setup if we just want the value */ 1641 if (resbuf != NULL) 1642 return (hereinval(iop, i, resbuf, NULL)); 1643 1644 /* 1645 * Create temp file to hold content (done before newenv 1646 * so temp doesn't get removed too soon). 1647 */ 1648 h = maketemp(ATEMP, TT_HEREDOC_EXP, &e->temps); 1649 if (!(shf = h->shf) || (fd = binopen3(h->tffn, O_RDONLY, 0)) < 0) { 1650 i = errno; 1651 warningf(true, Tf_temp, 1652 !shf ? Tcreate : Topen, h->tffn, cstrerror(i)); 1653 if (shf) 1654 shf_close(shf); 1655 /* special to iosetup(): don't print error */ 1656 return (-2); 1657 } 1658 1659 if (hereinval(iop, i, NULL, shf) == -2) { 1660 close(fd); 1661 /* special to iosetup(): don't print error */ 1662 return (-2); 1663 } 1664 1665 if (shf_close(shf) == -1) { 1666 i = errno; 1667 close(fd); 1668 warningf(true, Tf_temp, 1669 Twrite, h->tffn, cstrerror(i)); 1670 /* special to iosetup(): don't print error */ 1671 return (-2); 1672 } 1673 1674 return (fd); 1675 } 1676 1677 /* 1678 * ksh special - the select command processing section 1679 * print the args in column form - assuming that we can 1680 */ 1681 static const char * 1682 do_selectargs(const char **ap, bool print_menu) 1683 { 1684 static const char *read_args[] = { 1685 Tread, "-r", "REPLY", NULL 1686 }; 1687 char *s; 1688 int i, argct; 1689 1690 for (argct = 0; ap[argct]; argct++) 1691 ; 1692 while (/* CONSTCOND */ 1) { 1693 /*- 1694 * Menu is printed if 1695 * - this is the first time around the select loop 1696 * - the user enters a blank line 1697 * - the REPLY parameter is empty 1698 */ 1699 if (print_menu || !*str_val(global("REPLY"))) 1700 pr_menu(ap); 1701 shellf(Tf_s, str_val(global("PS3"))); 1702 if (call_builtin(findcom(Tread, FC_BI), read_args, Tselect, 1703 false)) 1704 return (NULL); 1705 if (*(s = str_val(global("REPLY")))) 1706 return ((getn(s, &i) && i >= 1 && i <= argct) ? 1707 ap[i - 1] : null); 1708 print_menu = true; 1709 } 1710 } 1711 1712 struct select_menu_info { 1713 const char * const *args; 1714 int num_width; 1715 }; 1716 1717 /* format a single select menu item */ 1718 static void 1719 select_fmt_entry(char *buf, size_t buflen, unsigned int i, const void *arg) 1720 { 1721 const struct select_menu_info *smi = 1722 (const struct select_menu_info *)arg; 1723 1724 shf_snprintf(buf, buflen, "%*u) %s", 1725 smi->num_width, i + 1, smi->args[i]); 1726 } 1727 1728 /* 1729 * print a select style menu 1730 */ 1731 void 1732 pr_menu(const char * const *ap) 1733 { 1734 struct select_menu_info smi; 1735 const char * const *pp; 1736 size_t acols = 0, aocts = 0, i; 1737 unsigned int n; 1738 struct columnise_opts co; 1739 1740 /* 1741 * width/column calculations were done once and saved, but this 1742 * means select can't be used recursively so we re-calculate 1743 * each time (could save in a structure that is returned, but 1744 * it's probably not worth the bother) 1745 */ 1746 1747 /* 1748 * get dimensions of the list 1749 */ 1750 for (n = 0, pp = ap; *pp; n++, pp++) { 1751 i = strlen(*pp); 1752 if (i > aocts) 1753 aocts = i; 1754 i = utf_mbswidth(*pp); 1755 if (i > acols) 1756 acols = i; 1757 } 1758 1759 /* 1760 * we will print an index of the form "%d) " in front of 1761 * each entry, so get the maximum width of this 1762 */ 1763 for (i = n, smi.num_width = 1; i >= 10; i /= 10) 1764 smi.num_width++; 1765 1766 smi.args = ap; 1767 co.shf = shl_out; 1768 co.linesep = '\n'; 1769 co.prefcol = co.do_last = true; 1770 print_columns(&co, n, select_fmt_entry, (void *)&smi, 1771 smi.num_width + 2 + aocts, smi.num_width + 2 + acols); 1772 } 1773 1774 static void 1775 plain_fmt_entry(char *buf, size_t buflen, unsigned int i, const void *arg) 1776 { 1777 strlcpy(buf, ((const char * const *)arg)[i], buflen); 1778 } 1779 1780 void 1781 pr_list(struct columnise_opts *cop, char * const *ap) 1782 { 1783 size_t acols = 0, aocts = 0, i; 1784 unsigned int n; 1785 char * const *pp; 1786 1787 for (n = 0, pp = ap; *pp; n++, pp++) { 1788 i = strlen(*pp); 1789 if (i > aocts) 1790 aocts = i; 1791 i = utf_mbswidth(*pp); 1792 if (i > acols) 1793 acols = i; 1794 } 1795 1796 print_columns(cop, n, plain_fmt_entry, (const void *)ap, 1797 aocts, acols); 1798 } 1799 1800 /* 1801 * [[ ... ]] evaluation routines 1802 */ 1803 1804 /* 1805 * Test if the current token is a whatever. Accepts the current token if 1806 * it is. Returns 0 if it is not, non-zero if it is (in the case of 1807 * TM_UNOP and TM_BINOP, the returned value is a Test_op). 1808 */ 1809 static Test_op 1810 dbteste_isa(Test_env *te, Test_meta meta) 1811 { 1812 Test_op ret = TO_NONOP; 1813 bool uqword; 1814 const char *p; 1815 1816 if (!*te->pos.wp) 1817 return (meta == TM_END ? TO_NONNULL : TO_NONOP); 1818 1819 /* unquoted word? */ 1820 for (p = *te->pos.wp; *p == CHAR; p += 2) 1821 ; 1822 uqword = *p == EOS; 1823 1824 if (meta == TM_UNOP || meta == TM_BINOP) { 1825 if (uqword) { 1826 /* longer than the longest operator */ 1827 char buf[8]; 1828 char *q = buf; 1829 1830 p = *te->pos.wp; 1831 while (*p++ == CHAR && 1832 (size_t)(q - buf) < sizeof(buf) - 1) 1833 *q++ = *p++; 1834 *q = '\0'; 1835 ret = test_isop(meta, buf); 1836 } 1837 } else if (meta == TM_END) 1838 ret = TO_NONOP; 1839 else 1840 ret = (uqword && !strcmp(*te->pos.wp, 1841 dbtest_tokens[(int)meta])) ? TO_NONNULL : TO_NONOP; 1842 1843 /* Accept the token? */ 1844 if (ret != TO_NONOP) 1845 te->pos.wp++; 1846 1847 return (ret); 1848 } 1849 1850 static const char * 1851 dbteste_getopnd(Test_env *te, Test_op op, bool do_eval) 1852 { 1853 const char *s = *te->pos.wp; 1854 int flags = DOTILDE | DOSCALAR; 1855 1856 if (!s) 1857 return (NULL); 1858 1859 te->pos.wp++; 1860 1861 if (!do_eval) 1862 return (null); 1863 1864 if (op == TO_STEQL || op == TO_STNEQ) 1865 flags |= DOPAT; 1866 1867 return (evalstr(s, flags)); 1868 } 1869 1870 static void 1871 dbteste_error(Test_env *te, int offset, const char *msg) 1872 { 1873 te->flags |= TEF_ERROR; 1874 internal_warningf("dbteste_error: %s (offset %d)", msg, offset); 1875 } 1876