Changeset 3437 for trunk/src/kash/eval.c


Ignore:
Timestamp:
Sep 3, 2020, 3:52:14 PM (5 years ago)
Author:
bird
Message:

kash: refactoring evalcommand - complicated, part II.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kash/eval.c

    r3435 r3437  
    458458                args.backgnd = backgnd;
    459459                forkshell2(psh, jp, n, backgnd ? FORK_BG : FORK_FG,
    460                            evalsubshell_child, n, &args, sizeof(args));
     460                           evalsubshell_child, n, &args, sizeof(args), NULL);
    461461        }
    462462#else
     
    578578                        args.pip[1] = pip[1];
    579579                        forkshell2(psh, jp, lp->n, n->npipe.backgnd ? FORK_BG : FORK_FG,
    580                                    evalpipe_child, lp->n, &args, sizeof(args));
     580                                   evalpipe_child, lp->n, &args, sizeof(args), NULL);
    581581                }
    582582#else
     
    677677                        args.pip[1] = pip[1];
    678678                        forkshell2(psh, jp, n, FORK_NOJOB,
    679                                    evalbackcmd_child, n, &args, sizeof(args));
     679                                   evalbackcmd_child, n, &args, sizeof(args), NULL);
    680680                }
    681681#else
     
    811811struct evalcommanddoit
    812812{
    813         struct cmdentry cmdentry;
    814         char *lastarg;
    815         const char *path;
     813        struct stackmark smark;
     814
    816815        struct backcmd *backcmd;
    817816        int flags;
    818817        int argc;
    819818        char **argv;
     819        char *lastarg;
    820820        struct arglist varlist;
    821         struct stackmark smark;
     821        const char *path;
     822        struct cmdentry cmdentry;
     823
     824        /* for child stuff only: */
     825        int pip[2];
    822826};
    823827
     
    9961000}
    9971001
     1002/* child callback. */
     1003static int evalcommand_child(shinstance *psh, union node *cmd, void *argp)
     1004{
     1005        struct evalcommanddoit *args = (struct evalcommanddoit *)argp;
     1006
     1007        if (args->flags & EV_BACKCMD) {
     1008                FORCEINTON;
     1009                shfile_close(&psh->fdtab, args->pip[0]);
     1010                if (args->pip[1] != 1) {
     1011                        movefd(psh, args->pip[1], 1);
     1012                }
     1013        }
     1014        args->flags |= EV_EXIT;
     1015
     1016        evalcommand_doit(psh, cmd, args);
     1017        /* not reached */  /** @todo make it return here */
     1018        return 0;
     1019}
     1020
     1021/* Copies data in the argument structure from parent to child. */
     1022static void evalcommand_setup_child(shinstance *pshchild, shinstance *pshparent, void *argp)
     1023{
     1024        struct evalcommanddoit *args = (struct evalcommanddoit *)argp;
     1025        char **argv;
     1026        char **srcargv;
     1027        struct strlist *sp;
     1028        int argc, i;
     1029
     1030        setstackmark(pshchild, &args->smark);
     1031
     1032        /* copy arguments. */
     1033        srcargv = args->argv;
     1034        argc = args->argc;
     1035        args->argv = argv = stalloc(pshchild, sizeof(char *) * (argc + 1));
     1036        for (i = 0; i < argc; i++)
     1037                argv[i] = stsavestr(pshchild, srcargv[i]);
     1038        argv[argc] = NULL;
     1039        if (args->lastarg)
     1040                args->lastarg = argv[argc - 1];
     1041
     1042        /* copy variable list, checking for the 'path'. */
     1043        sp = args->varlist.list;
     1044        args->varlist.list = NULL;
     1045        args->varlist.lastp = &args->varlist.list;
     1046        for (; sp; sp = sp->next) {
     1047                struct strlist *snew = (struct strlist *)stalloc(pshchild, sizeof(*snew));
     1048                char *text;
     1049                snew->next = NULL;
     1050                snew->text = text = stsavestr(pshchild, sp->text);
     1051
     1052                if (&text[5] == args->path)
     1053                        args->path = &text[sizeof("PATH=") - 1];
     1054
     1055                *args->varlist.lastp = snew;
     1056                args->varlist.lastp = &snew->next;
     1057        }
     1058
     1059        if (args->path == pathval(pshparent))
     1060                args->path = pathval(pshchild);
     1061
     1062        /* back tick command should be ignored in this codepath
     1063           (flags != EV_BACKCMD as EV_EXIT is ORed in). */
     1064
     1065        /* If cmdentry references an internal function, we must duplicates it's nodes. */
     1066        if (args->cmdentry.cmdtype == CMDFUNCTION)
     1067                args->cmdentry.u.func = copyparsetree(pshchild, args->cmdentry.u.func); /** @todo isn't this duplicated already? */
     1068}
     1069
    9981070/*
    9991071 * Execute a simple command.
     
    11351207                   || args.cmdentry.u.bltin == evalcmd))) {
    11361208                struct job *jp;
    1137                 int pip[2];
    11381209                int mode;
     1210
    11391211                INTOFF;
    11401212                jp = makejob(psh, cmd, 1);
    11411213                mode = cmd->ncmd.backgnd;
     1214                args.pip[0] = -1;
     1215                args.pip[1] = -1;
    11421216                if (flags & EV_BACKCMD) {
    11431217                        mode = FORK_NOJOB;
    1144                         if (sh_pipe(psh, pip) < 0)
     1218                        if (sh_pipe(psh, args.pip) < 0)
    11451219                                error(psh, "Pipe call failed");
    11461220                }
     1221
     1222                args.backcmd = backcmd;
     1223                args.flags = flags;
     1224                args.path = path;
     1225#ifdef KASH_USE_FORKSHELL2
     1226                forkshell2(psh, jp, cmd, mode, evalcommand_child, cmd,
     1227                           &args, sizeof(args), evalcommand_setup_child);
     1228                evalcommand_parent(psh, flags, args.lastarg, &args.smark, mode, jp,
     1229                                                   args.pip, backcmd);
     1230#else
    11471231                if (forkshell(psh, jp, cmd, mode) != 0) {
    1148                         evalcommand_parent(psh, flags, args.lastarg, &args.smark, mode, jp, pip, backcmd);
     1232                        evalcommand_parent(psh, flags, args.lastarg, &args.smark, mode, jp,
     1233                                                           args.pip, backcmd);
    11491234                        return; /* at end of routine */
    11501235                }
    1151 
    1152                 if (flags & EV_BACKCMD) {
    1153                         FORCEINTON;
    1154                         shfile_close(&psh->fdtab, pip[0]);
    1155                         if (pip[1] != 1) {
    1156                                 movefd(psh, pip[1], 1);
    1157                         }
    1158                 }
    1159                 flags |= EV_EXIT;
    1160 
     1236                evalcommand_child(psh, cmd, &args);
     1237#endif
     1238        } else {
    11611239                args.backcmd = backcmd;
    11621240                args.flags = flags;
     
    11641242                evalcommand_doit(psh, cmd, &args);
    11651243        }
    1166         else {
    1167                 args.backcmd = backcmd;
    1168                 args.flags = flags;
    1169                 args.path = path;
    1170                 evalcommand_doit(psh, cmd, &args);
    1171         }
    11721244}
    11731245
     
    11881260                if (goodname(n->ncmd.args->narg.text))
    11891261                        find_command(psh, n->ncmd.args->narg.text, &entry, 0,
    1190                                      pathval(psh));
     1262                                         pathval(psh));
    11911263}
    11921264
Note: See TracChangeset for help on using the changeset viewer.