VirtualBox

Changeset 3434 in kBuild


Ignore:
Timestamp:
Sep 2, 2020 8:19:25 PM (5 years ago)
Author:
bird
Message:

kash: refactoring evalcommand - complicated, part I.

Location:
trunk/src/kash
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kash/Makefile.kmk

    r3433 r3434  
    4444        BSD YY_NO_UNISTD_H \
    4545        SH_DEAL_WITH_CRLF PC_PATH_SEP PC_DRIVE_LETTERS PC_EXE_EXTS EXEC_HASH_BANG_SCRIPT \
    46         KASH_USE_FORKSHELL2
     46#       KASH_USE_FORKSHELL2
    4747kash_DEFS.os2 = \
    4848        HAVE_SYS_SIGNAME HAVE_SYSCTL_H HAVE_SETPROGNAME PC_OS2_LIBPATHS \
  • trunk/src/kash/eval.c

    r3433 r3434  
    768768}
    769769
     770
     771/*
     772 * The split up evalcommand code:
     773 *      evalcommand_out, evalcommand_parent, evalcommand_doit, evalcommand_child
     774 */
    770775/*int vforked = 0;*/
     776
     777/* Both child and parent exits thru here. */
     778STATIC void
     779evalcommand_out(shinstance *psh, int flags, char *lastarg, struct stackmark *smarkp)
     780{
     781        if (lastarg)
     782                /* dsl: I think this is intended to be used to support
     783                 * '_' in 'vi' command mode during line editing...
     784                 * However I implemented that within libedit itself.
     785                 */
     786                setvar(psh, "_", lastarg, 0);
     787        popstackmark(psh, smarkp);
     788
     789        if (eflag(psh) && psh->exitstatus && !(flags & EV_TESTED))
     790                exitshell(psh, psh->exitstatus);
     791}
     792
     793
     794/* Called if we forkshell(). */
     795STATIC void
     796evalcommand_parent(shinstance *psh, int flags, char *lastarg, struct stackmark *smarkp,
     797                   int mode, struct job *jp, int pip[2], struct backcmd *backcmd)
     798{
     799        if (mode == FORK_FG) {  /* argument to fork */
     800                psh->exitstatus = waitforjob(psh, jp);
     801        } else if (mode == FORK_NOJOB) {
     802                backcmd->fd = pip[0];
     803                shfile_close(&psh->fdtab, pip[1]);
     804                backcmd->jp = jp;
     805        }
     806        FORCEINTON;
     807
     808        evalcommand_out(psh, flags, lastarg, smarkp);
     809}
     810
     811struct evalcommanddoit
     812{
     813        struct cmdentry cmdentry;
     814        char *lastarg;
     815        const char *path;
     816        struct backcmd *backcmd;
     817        int flags;
     818        int argc;
     819        char **argv;
     820        struct arglist varlist;
     821        struct stackmark smark;
     822};
     823
     824STATIC void
     825evalcommand_doit(shinstance *psh, union node *cmd, struct evalcommanddoit *args)
     826{
     827        struct jmploc jmploc;
     828        struct jmploc *volatile savehandler;
     829        struct localvar *volatile savelocalvars;
     830
     831        /* This is the child process if a fork occurred. */
     832        /* Execute the command. */
     833        switch (args->cmdentry.cmdtype) {
     834                case CMDFUNCTION: {
     835                        volatile struct shparam saveparam;
     836#ifdef DEBUG
     837                        trputs(psh, "Shell function:  ");  trargs(psh, args->argv);
     838#endif
     839                        redirect(psh, cmd->ncmd.redirect, REDIR_PUSH);
     840                        saveparam = psh->shellparam;
     841                        psh->shellparam.malloc = 0;
     842                        psh->shellparam.reset = 1;
     843                        psh->shellparam.nparam = args->argc - 1;
     844                        psh->shellparam.p = args->argv + 1;
     845                        psh->shellparam.optnext = NULL;
     846                        INTOFF;
     847                        savelocalvars = psh->localvars;
     848                        psh->localvars = NULL;
     849                        INTON;
     850                        if (setjmp(jmploc.loc)) {
     851                                if (psh->exception == EXSHELLPROC) {
     852                                        freeparam(psh, (volatile struct shparam *)
     853                                                &saveparam);
     854                                } else {
     855                                        freeparam(psh, &psh->shellparam);
     856                                        psh->shellparam = saveparam;
     857                                }
     858                                poplocalvars(psh);
     859                                psh->localvars = savelocalvars;
     860                                psh->handler = savehandler;
     861                                longjmp(psh->handler->loc, 1);
     862                        }
     863                        savehandler = psh->handler;
     864                        psh->handler = &jmploc;
     865                        listmklocal(psh, args->varlist.list, 0);
     866                        /* stop shell blowing its stack */
     867                        if (++psh->funcnest > 1000)
     868                                error(psh, "too many nested function calls");
     869                        evaltree(psh, args->cmdentry.u.func, args->flags & EV_TESTED);
     870                        psh->funcnest--;
     871                        INTOFF;
     872                        poplocalvars(psh);
     873                        psh->localvars = savelocalvars;
     874                        freeparam(psh, &psh->shellparam);
     875                        psh->shellparam = saveparam;
     876                        psh->handler = savehandler;
     877                        popredir(psh);
     878                        INTON;
     879                        if (psh->evalskip == SKIPFUNC) {
     880                                psh->evalskip = 0;
     881                                psh->skipcount = 0;
     882                        }
     883                        if (args->flags & EV_EXIT)
     884                                exitshell(psh, psh->exitstatus);
     885                        break;
     886                }
     887
     888                case CMDBUILTIN:
     889                case CMDSPLBLTIN: {
     890                        volatile int temp_path = 0;
     891                        char *volatile savecmdname;
     892                        volatile int e;
     893                        int mode;
     894#ifdef DEBUG
     895                        trputs(psh, "builtin command:  ");  trargs(psh, args->argv);
     896#endif
     897                        mode = (args->cmdentry.u.bltin == execcmd) ? 0 : REDIR_PUSH;
     898                        if (args->flags == EV_BACKCMD) {
     899                                psh->memout.nleft = 0;
     900                                psh->memout.nextc = psh->memout.buf;
     901                                psh->memout.bufsize = 64;
     902                                mode |= REDIR_BACKQ;
     903                        }
     904                        e = -1;
     905                        savehandler = psh->handler;
     906                        savecmdname = psh->commandname;
     907                        psh->handler = &jmploc;
     908                        if (!setjmp(jmploc.loc)) {
     909                                /* We need to ensure the command hash table isn't
     910                                 * corruped by temporary PATH assignments.
     911                                 * However we must ensure the 'local' command works!
     912                                 */
     913                                if (args->path != pathval(psh) && (args->cmdentry.u.bltin == hashcmd ||
     914                                        args->cmdentry.u.bltin == typecmd)) {
     915                                        savelocalvars = psh->localvars;
     916                                        psh->localvars = 0;
     917                                        mklocal(psh, args->path - 5 /* PATH= */, 0);
     918                                        temp_path = 1;
     919                                } else
     920                                        temp_path = 0;
     921                                redirect(psh, cmd->ncmd.redirect, mode);
     922
     923                                /* exec is a special builtin, but needs this list... */
     924                                psh->cmdenviron = args->varlist.list;
     925                                /* we must check 'readonly' flag for all builtins */
     926                                listsetvar(psh, args->varlist.list,
     927                                        args->cmdentry.cmdtype == CMDSPLBLTIN ? 0 : VNOSET);
     928                                psh->commandname = args->argv[0];
     929                                /* initialize nextopt */
     930                                psh->argptr = args->argv + 1;
     931                                psh->optptr = NULL;
     932                                /* and getopt */
     933#if 0 /** @todo fix getop usage! */
     934#if defined(__FreeBSD__) || defined(__EMX__) || defined(__APPLE__)
     935                                optreset = 1;
     936                                optind = 1;
     937#else
     938                                optind = 0; /* init */
     939#endif
     940#endif
     941
     942                                psh->exitstatus = args->cmdentry.u.bltin(psh, args->argc, args->argv);
     943                        } else {
     944                                e = psh->exception;
     945                                psh->exitstatus = e == EXINT ? SIGINT + 128 :
     946                                                e == EXEXEC ? psh->exerrno : 2;
     947                        }
     948                        psh->handler = savehandler;
     949                        output_flushall(psh);
     950                        psh->out1 = &psh->output;
     951                        psh->out2 = &psh->errout;
     952                        freestdout(psh);
     953                        if (temp_path) {
     954                                poplocalvars(psh);
     955                                psh->localvars = savelocalvars;
     956                        }
     957                        psh->cmdenviron = NULL;
     958                        if (e != EXSHELLPROC) {
     959                                psh->commandname = savecmdname;
     960                                if (args->flags & EV_EXIT)
     961                                        exitshell(psh, psh->exitstatus);
     962                        }
     963                        if (e != -1) {
     964                                if ((e != EXERROR && e != EXEXEC)
     965                                        || args->cmdentry.cmdtype == CMDSPLBLTIN)
     966                                        exraise(psh, e);
     967                                FORCEINTON;
     968                        }
     969                        if (args->cmdentry.u.bltin != execcmd)
     970                                popredir(psh);
     971                        if (args->flags == EV_BACKCMD) {
     972                                args->backcmd->buf = psh->memout.buf;
     973                                args->backcmd->nleft = (int)(psh->memout.nextc - psh->memout.buf);
     974                                psh->memout.buf = NULL;
     975                        }
     976                        break;
     977                }
     978
     979                default: {
     980                        struct strlist *sp;
     981                        char **envp;
     982#ifdef DEBUG
     983                        trputs(psh, "normal command:  ");  trargs(psh, args->argv);
     984#endif
     985                        clearredir(psh, psh->vforked);
     986                        redirect(psh, cmd->ncmd.redirect, psh->vforked ? REDIR_VFORK : 0);
     987                        if (!psh->vforked)
     988                                for (sp = args->varlist.list ; sp ; sp = sp->next)
     989                                        setvareq(psh, sp->text, VEXPORT|VSTACK);
     990                        envp = environment(psh);
     991                        shellexec(psh, args->argv, envp, args->path, args->cmdentry.u.index, psh->vforked);
     992                        break;
     993                }
     994        }
     995
     996        evalcommand_out(psh, args->flags, args->lastarg, &args->smark);
     997}
    771998
    772999/*
     
    7771004evalcommand(shinstance *psh, union node *cmd, int flags, struct backcmd *backcmd)
    7781005{
    779         struct stackmark smark;
    780         union node *argp;
    781         struct arglist arglist;
    782         struct arglist varlist;
     1006        struct evalcommanddoit args;
    7831007        char **argv;
    7841008        int argc;
    785         char **envp;
     1009
     1010        union node *argp;
    7861011        int numvars;
     1012        struct arglist arglist;
    7871013        struct strlist *sp;
    788         int mode = 0;
    789         int pip[2];
    790         struct cmdentry cmdentry;
    791         struct job *jp;
    792         struct jmploc jmploc;
    793         struct jmploc *volatile savehandler;
    794         char *volatile savecmdname;
    795         volatile struct shparam saveparam;
    796         struct localvar *volatile savelocalvars;
    797         volatile int e;
    798         char *lastarg;
    7991014        const char *path = pathval(psh);
    800         volatile int temp_path;
    801 #if __GNUC__
    802         /* Try avoid longjmp clobbering */
    803         (void) &argv;
    804         (void) &argc;
    805         (void) &lastarg;
    806         (void) &flags;
    807         (void) &path;
    808         (void) &mode;
    809 #endif
    8101015
    8111016        psh->vforked = 0;
    8121017        /* First expand the arguments. */
    8131018        TRACE((psh, "evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
    814         setstackmark(psh, &smark);
     1019        setstackmark(psh, &args.smark);
    8151020        psh->back_exitstatus = 0;
    8161021
     
    8351040
    8361041        /* Now do the initial 'name=value' ones we skipped above */
    837         varlist.lastp = &varlist.list;
     1042        args.varlist.lastp = &args.varlist.list;
    8381043        for (argp = cmd->ncmd.args ; numvars > 0 && argp ; argp = argp->narg.next, numvars--)
    839                 expandarg(psh, argp, &varlist, EXP_VARTILDE);
    840         *varlist.lastp = NULL;
     1044                expandarg(psh, argp, &args.varlist, EXP_VARTILDE);
     1045        *args.varlist.lastp = NULL;
    8411046
    8421047        argc = 0;
    8431048        for (sp = arglist.list ; sp ; sp = sp->next)
    8441049                argc++;
    845         argv = stalloc(psh, sizeof (char *) * (argc + 1));
     1050        args.argc = argc;
     1051        args.argv = argv = stalloc(psh, sizeof (char *) * (argc + 1));
    8461052
    8471053        for (sp = arglist.list ; sp ; sp = sp->next) {
     
    8501056        }
    8511057        *argv = NULL;
    852         lastarg = NULL;
     1058        args.lastarg = NULL;
    8531059        if (iflag(psh) && psh->funcnest == 0 && argc > 0)
    854                 lastarg = argv[-1];
     1060                args.lastarg = argv[-1];
    8551061        argv -= argc;
    8561062
     
    8591065                char sep = 0;
    8601066                out2str(psh, ps4val(psh));
    861                 for (sp = varlist.list ; sp ; sp = sp->next) {
     1067                for (sp = args.varlist.list ; sp ; sp = sp->next) {
    8621068                        if (sep != 0)
    8631069                                outc(sep, &psh->errout);
     
    8771083        /* Now locate the command. */
    8781084        if (argc == 0) {
    879                 cmdentry.cmdtype = CMDSPLBLTIN;
    880                 cmdentry.u.bltin = bltincmd;
     1085                args.cmdentry.cmdtype = CMDSPLBLTIN;
     1086                args.cmdentry.u.bltin = bltincmd;
    8811087        } else {
    8821088                static const char PATH[] = "PATH=";
     
    8871093                 * is present
    8881094                 */
    889                 for (sp = varlist.list; sp; sp = sp->next)
     1095                for (sp = args.varlist.list; sp; sp = sp->next)
    8901096                        if (strncmp(sp->text, PATH, sizeof(PATH) - 1) == 0)
    8911097                                path = sp->text + sizeof(PATH) - 1;
     
    8931099                do {
    8941100                        int argsused, use_syspath;
    895                         find_command(psh, argv[0], &cmdentry, cmd_flags, path);
    896                         if (cmdentry.cmdtype == CMDUNKNOWN) {
     1101                        find_command(psh, argv[0], &args.cmdentry, cmd_flags, path);
     1102                        if (args.cmdentry.cmdtype == CMDUNKNOWN) {
    8971103                                psh->exitstatus = 127;
    8981104                                flushout(&psh->errout);
    899                                 goto out;
     1105                                evalcommand_out(psh, flags, args.lastarg, &args.smark);
     1106                                return;
    9001107                        }
    9011108
    9021109                        /* implement the 'command' builtin here */
    903                         if (cmdentry.cmdtype != CMDBUILTIN ||
    904                             cmdentry.u.bltin != bltincmd)
     1110                        if (args.cmdentry.cmdtype != CMDBUILTIN ||
     1111                            args.cmdentry.u.bltin != bltincmd)
    9051112                                break;
    9061113                        cmd_flags |= DO_NOFUNC;
     
    9081115                        if (argsused == 0) {
    9091116                                /* use 'type' builting to display info */
    910                                 cmdentry.u.bltin = typecmd;
     1117                                args.cmdentry.u.bltin = typecmd;
    9111118                                break;
    9121119                        }
     
    9161123                                path = syspath(psh) + 5;
    9171124                } while (argc != 0);
    918                 if (cmdentry.cmdtype == CMDSPLBLTIN && cmd_flags & DO_NOFUNC)
     1125                if (args.cmdentry.cmdtype == CMDSPLBLTIN && cmd_flags & DO_NOFUNC)
    9191126                        /* posix mandates that 'command <splbltin>' act as if
    9201127                           <splbltin> was a normal builtin */
    921                         cmdentry.cmdtype = CMDBUILTIN;
     1128                        args.cmdentry.cmdtype = CMDBUILTIN;
    9221129        }
    9231130
    9241131        /* Fork off a child process if necessary. */
    9251132        if (cmd->ncmd.backgnd
    926          || (cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0)
    927          || ((flags & EV_BACKCMD) != 0
    928             && ((cmdentry.cmdtype != CMDBUILTIN && cmdentry.cmdtype != CMDSPLBLTIN)
    929                  || cmdentry.u.bltin == dotcmd
    930                  || cmdentry.u.bltin == evalcmd))) {
     1133         || (args.cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0)
     1134         || (  (flags & EV_BACKCMD) != 0
     1135            && (  (args.cmdentry.cmdtype != CMDBUILTIN && args.cmdentry.cmdtype != CMDSPLBLTIN)
     1136                   || args.cmdentry.u.bltin == dotcmd
     1137                   || args.cmdentry.u.bltin == evalcmd))) {
     1138                struct job *jp;
     1139                int pip[2];
     1140                int mode;
    9311141                INTOFF;
    9321142                jp = makejob(psh, cmd, 1);
     
    9371147                                error(psh, "Pipe call failed");
    9381148                }
    939 #ifdef DO_SHAREDVFORK
    940                 /* It is essential that if DO_SHAREDVFORK is defined that the
    941                  * child's address space is actually shared with the parent as
    942                  * we rely on this.
    943                  */
    944                 if (cmdentry.cmdtype == CMDNORMAL) {
    945                         pid_t   pid;
    946 
    947                         savelocalvars = psh->localvars;
    948                         psh->localvars = NULL;
    949                         psh->vforked = 1;
    950                         switch (pid = vfork()) {
    951                         case -1:
    952                                 TRACE((psh, "Vfork failed, errno=%d\n", errno));
    953                                 INTON;
    954                                 error(psh, "Cannot vfork");
    955                                 break;
    956                         case 0:
    957                                 /* Make sure that exceptions only unwind to
    958                                  * after the vfork(2)
    959                                  */
    960                                 if (setjmp(jmploc.loc)) {
    961                                         if (psh->exception == EXSHELLPROC) {
    962                                                 /* We can't progress with the vfork,
    963                                                  * so, set vforked = 2 so the parent
    964                                                  * knows, and _exit();
    965                                                  */
    966                                                 psh->vforked = 2;
    967                                                 sh__exit(psh, 0);
    968                                         } else {
    969                                                 sh__exit(psh, psh->exerrno);
    970                                         }
    971                                 }
    972                                 savehandler = psh->handler;
    973                                 psh->handler = &jmploc;
    974                                 listmklocal(psh, varlist.list, VEXPORT | VNOFUNC);
    975                                 forkchild(psh, jp, cmd, mode, psh->vforked);
    976                                 break;
    977                         default:
    978                                 psh->handler = savehandler;     /* restore from vfork(2) */
    979                                 poplocalvars(psh);
    980                                 psh->localvars = savelocalvars;
    981                                 if (psh->vforked == 2) {
    982                                         psh->vforked = 0;
    983 
    984                                         (void)sh_waitpid(psh, pid, NULL, 0);
    985                                         /* We need to progress in a normal fork fashion */
    986                                         goto normal_fork;
    987                                 }
    988                                 psh->vforked = 0;
    989                                 forkparent(psh, jp, cmd, mode, pid);
    990                                 goto parent;
    991                         }
    992                 } else {
    993 normal_fork:
    994 #endif
    995                         if (forkshell(psh, jp, cmd, mode) != 0)
    996                                 goto parent;    /* at end of routine */
    997                         FORCEINTON;
    998 #ifdef DO_SHAREDVFORK
    999                 }
    1000 #endif
     1149                if (forkshell(psh, jp, cmd, mode) != 0) {
     1150                        evalcommand_parent(psh, flags, args.lastarg, &args.smark, mode, jp, pip, backcmd);
     1151                        return; /* at end of routine */
     1152                }
     1153
    10011154                if (flags & EV_BACKCMD) {
    10021155                        if (!psh->vforked) {
     
    10091162                }
    10101163                flags |= EV_EXIT;
    1011         }
    1012 
    1013         /* This is the child process if a fork occurred. */
    1014         /* Execute the command. */
    1015         switch (cmdentry.cmdtype) {
    1016         case CMDFUNCTION:
    1017 #ifdef DEBUG
    1018                 trputs(psh, "Shell function:  ");  trargs(psh, argv);
    1019 #endif
    1020                 redirect(psh, cmd->ncmd.redirect, REDIR_PUSH);
    1021                 saveparam = psh->shellparam;
    1022                 psh->shellparam.malloc = 0;
    1023                 psh->shellparam.reset = 1;
    1024                 psh->shellparam.nparam = argc - 1;
    1025                 psh->shellparam.p = argv + 1;
    1026                 psh->shellparam.optnext = NULL;
    1027                 INTOFF;
    1028                 savelocalvars = psh->localvars;
    1029                 psh->localvars = NULL;
    1030                 INTON;
    1031                 if (setjmp(jmploc.loc)) {
    1032                         if (psh->exception == EXSHELLPROC) {
    1033                                 freeparam(psh, (volatile struct shparam *)
    1034                                     &saveparam);
    1035                         } else {
    1036                                 freeparam(psh, &psh->shellparam);
    1037                                 psh->shellparam = saveparam;
    1038                         }
    1039                         poplocalvars(psh);
    1040                         psh->localvars = savelocalvars;
    1041                         psh->handler = savehandler;
    1042                         longjmp(psh->handler->loc, 1);
    1043                 }
    1044                 savehandler = psh->handler;
    1045                 psh->handler = &jmploc;
    1046                 listmklocal(psh, varlist.list, 0);
    1047                 /* stop shell blowing its stack */
    1048                 if (++psh->funcnest > 1000)
    1049                         error(psh, "too many nested function calls");
    1050                 evaltree(psh, cmdentry.u.func, flags & EV_TESTED);
    1051                 psh->funcnest--;
    1052                 INTOFF;
    1053                 poplocalvars(psh);
    1054                 psh->localvars = savelocalvars;
    1055                 freeparam(psh, &psh->shellparam);
    1056                 psh->shellparam = saveparam;
    1057                 psh->handler = savehandler;
    1058                 popredir(psh);
    1059                 INTON;
    1060                 if (psh->evalskip == SKIPFUNC) {
    1061                         psh->evalskip = 0;
    1062                         psh->skipcount = 0;
    1063                 }
    1064                 if (flags & EV_EXIT)
    1065                         exitshell(psh, psh->exitstatus);
    1066                 break;
    1067 
    1068         case CMDBUILTIN:
    1069         case CMDSPLBLTIN:
    1070 #ifdef DEBUG
    1071                 trputs(psh, "builtin command:  ");  trargs(psh, argv);
    1072 #endif
    1073                 mode = (cmdentry.u.bltin == execcmd) ? 0 : REDIR_PUSH;
    1074                 if (flags == EV_BACKCMD) {
    1075                         psh->memout.nleft = 0;
    1076                         psh->memout.nextc = psh->memout.buf;
    1077                         psh->memout.bufsize = 64;
    1078                         mode |= REDIR_BACKQ;
    1079                 }
    1080                 e = -1;
    1081                 savehandler = psh->handler;
    1082                 savecmdname = psh->commandname;
    1083                 psh->handler = &jmploc;
    1084                 if (!setjmp(jmploc.loc)) {
    1085                         /* We need to ensure the command hash table isn't
    1086                          * corruped by temporary PATH assignments.
    1087                          * However we must ensure the 'local' command works!
    1088                          */
    1089                         if (path != pathval(psh) && (cmdentry.u.bltin == hashcmd ||
    1090                             cmdentry.u.bltin == typecmd)) {
    1091                                 savelocalvars = psh->localvars;
    1092                                 psh->localvars = 0;
    1093                                 mklocal(psh, path - 5 /* PATH= */, 0);
    1094                                 temp_path = 1;
    1095                         } else
    1096                                 temp_path = 0;
    1097                         redirect(psh, cmd->ncmd.redirect, mode);
    1098 
    1099                         /* exec is a special builtin, but needs this list... */
    1100                         psh->cmdenviron = varlist.list;
    1101                         /* we must check 'readonly' flag for all builtins */
    1102                         listsetvar(psh, varlist.list,
    1103                                 cmdentry.cmdtype == CMDSPLBLTIN ? 0 : VNOSET);
    1104                         psh->commandname = argv[0];
    1105                         /* initialize nextopt */
    1106                         psh->argptr = argv + 1;
    1107                         psh->optptr = NULL;
    1108                         /* and getopt */
    1109 #if 0 /** @todo fix getop usage! */
    1110 #if defined(__FreeBSD__) || defined(__EMX__) || defined(__APPLE__)
    1111                         optreset = 1;
    1112                         optind = 1;
    1113 #else
    1114                         optind = 0; /* init */
    1115 #endif
    1116 #endif
    1117 
    1118                         psh->exitstatus = cmdentry.u.bltin(psh, argc, argv);
    1119                 } else {
    1120                         e = psh->exception;
    1121                         psh->exitstatus = e == EXINT ? SIGINT + 128 :
    1122                                         e == EXEXEC ? psh->exerrno : 2;
    1123                 }
    1124                 psh->handler = savehandler;
    1125                 output_flushall(psh);
    1126                 psh->out1 = &psh->output;
    1127                 psh->out2 = &psh->errout;
    1128                 freestdout(psh);
    1129                 if (temp_path) {
    1130                         poplocalvars(psh);
    1131                         psh->localvars = savelocalvars;
    1132                 }
    1133                 psh->cmdenviron = NULL;
    1134                 if (e != EXSHELLPROC) {
    1135                         psh->commandname = savecmdname;
    1136                         if (flags & EV_EXIT)
    1137                                 exitshell(psh, psh->exitstatus);
    1138                 }
    1139                 if (e != -1) {
    1140                         if ((e != EXERROR && e != EXEXEC)
    1141                             || cmdentry.cmdtype == CMDSPLBLTIN)
    1142                                 exraise(psh, e);
    1143                         FORCEINTON;
    1144                 }
    1145                 if (cmdentry.u.bltin != execcmd)
    1146                         popredir(psh);
    1147                 if (flags == EV_BACKCMD) {
    1148                         backcmd->buf = psh->memout.buf;
    1149                         backcmd->nleft = (int)(psh->memout.nextc - psh->memout.buf);
    1150                         psh->memout.buf = NULL;
    1151                 }
    1152                 break;
    1153 
    1154         default:
    1155 #ifdef DEBUG
    1156                 trputs(psh, "normal command:  ");  trargs(psh, argv);
    1157 #endif
    1158                 clearredir(psh, psh->vforked);
    1159                 redirect(psh, cmd->ncmd.redirect, psh->vforked ? REDIR_VFORK : 0);
    1160                 if (!psh->vforked)
    1161                         for (sp = varlist.list ; sp ; sp = sp->next)
    1162                                 setvareq(psh, sp->text, VEXPORT|VSTACK);
    1163                 envp = environment(psh);
    1164                 shellexec(psh, argv, envp, path, cmdentry.u.index, psh->vforked);
    1165                 break;
    1166         }
    1167         goto out;
    1168 
    1169 parent: /* parent process gets here (if we forked) */
    1170         if (mode == FORK_FG) {  /* argument to fork */
    1171                 psh->exitstatus = waitforjob(psh, jp);
    1172         } else if (mode == FORK_NOJOB) {
    1173                 backcmd->fd = pip[0];
    1174                 shfile_close(&psh->fdtab, pip[1]);
    1175                 backcmd->jp = jp;
    1176         }
    1177         FORCEINTON;
    1178 
    1179 out:
    1180         if (lastarg)
    1181                 /* dsl: I think this is intended to be used to support
    1182                  * '_' in 'vi' command mode during line editing...
    1183                  * However I implemented that within libedit itself.
    1184                  */
    1185                 setvar(psh, "_", lastarg, 0);
    1186         popstackmark(psh, &smark);
    1187 
    1188         if (eflag(psh) && psh->exitstatus && !(flags & EV_TESTED))
    1189                 exitshell(psh, psh->exitstatus);
     1164
     1165                args.backcmd = backcmd;
     1166                args.flags = flags;
     1167                args.path = path;
     1168                evalcommand_doit(psh, cmd, &args);
     1169        }
     1170        else {
     1171                args.backcmd = backcmd;
     1172                args.flags = flags;
     1173                args.path = path;
     1174                evalcommand_doit(psh, cmd, &args);
     1175        }
    11901176}
    11911177
  • trunk/src/kash/jobs.c

    r3433 r3434  
    8484STATIC void cmdlist(shinstance *, union node *, int);
    8585STATIC void cmdputs(shinstance *, const char *);
     86#ifdef KASH_USE_FORKSHELL2
     87static int forkparent(shinstance *psh, struct job *jp, union node *n, int mode, pid_t pid);
     88static void forkchild(shinstance *psh, struct job *jp, union node *n, int mode, int vforked);
     89#endif
    8690
    8791
     
    780784 */
    781785
     786#ifndef KASH_USE_FORKSHELL2
    782787int
    783788forkshell(shinstance *psh, struct job *jp, union node *n, int mode)
     
    799804        }
    800805}
    801 
     806#else /* KASH_USE_FORKSHELL2 */
    802807int forkshell2(struct shinstance *psh, struct job *jp, union node *n, int mode,
    803808               int (*child)(struct shinstance *, void *, union node *),
     
    825830        return -1; /* won't get here */
    826831}
    827 
     832#endif
     833
     834#ifdef KASH_USE_FORKSHELL2
     835static
     836#endif
    828837int
    829838forkparent(shinstance *psh, struct job *jp, union node *n, int mode, pid_t pid)
     
    853862}
    854863
     864#ifdef KASH_USE_FORKSHELL2
     865static
     866#endif
    855867void
    856868forkchild(shinstance *psh, struct job *jp, union node *n, int mode, int vforked)
  • trunk/src/kash/jobs.h

    r3433 r3434  
    9595union node;
    9696struct job *makejob(struct shinstance *, union node *, int);
    97 int forkshell(struct shinstance *, struct job *, union node *, int);
    9897#ifdef KASH_USE_FORKSHELL2
    9998int forkshell2(struct shinstance *, struct job *, union node *, int,
    10099               int (*child)(struct shinstance *, void *, union node *),
    101100               union node *, void *, size_t);
    102 #endif
     101#else
     102int forkshell(struct shinstance *, struct job *, union node *, int);
    103103void forkchild(struct shinstance *, struct job *, union node *, int, int);
    104104int forkparent(struct shinstance *, struct job *, union node *, int, pid_t);
     105#endif
    105106int waitforjob(struct shinstance *, struct job *);
    106107int stoppedjobs(struct shinstance *);
  • trunk/src/kash/shinstance.h

    r3409 r3434  
    180180
    181181    /* eval.c */
    182     int                 vforked;
     182    int                 vforked; /** @todo remove this */
    183183
    184184    /* expand.c */
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette