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