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