VirtualBox

Changeset 3437 in kBuild for trunk


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

kash: refactoring evalcommand - complicated, part II.

Location:
trunk/src/kash
Files:
12 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
  • trunk/src/kash/exec.c

    r3435 r3437  
    150150        } else {
    151151                /* Before we search the PATH, transform kmk_builtin_% to kmk_% so we don't
    152                    need to be too careful mixing internal and external kmk command. */
     152                   need to be too careful mixing internal and external kmk commands. */
    153153                if (   argv0len > 12
    154154                    && argv0len < 42
  • trunk/src/kash/generated/nodes.h

    r2290 r3437  
    102102struct nfile {
    103103      int type;
     104      int fd;
    104105      union node *next;
    105       int fd;
    106106      union node *fname;
    107107      char *expfname;
     
    111111struct ndup {
    112112      int type;
     113      int fd;
    113114      union node *next;
    114       int fd;
    115115      int dupfd;
    116116      union node *vname;
     
    120120struct nhere {
    121121      int type;
     122      int fd;
    122123      union node *next;
    123       int fd;
    124124      union node *doc;
    125125};
  • trunk/src/kash/jobs.c

    r3435 r3437  
    807807int forkshell2(struct shinstance *psh, struct job *jp, union node *n, int mode,
    808808               int (*child)(struct shinstance *, void *, union node *),
    809                union node *nchild, void *argp, size_t arglen)
     809               union node *nchild, void *argp, size_t arglen,
     810               void (*setupchild)(struct shinstance *, struct shinstance *, void *))
    810811{
    811812        pid_t pid;
     
    816817        {
    817818                /* child */
    818                 (void)arglen;
    819819                forkchild(psh, jp, n, mode);
    820820                sh_exit(psh, child(psh, nchild, argp));
     
    827827        TRACE((psh, "Fork failed, errno=%d\n", errno));
    828828        INTON;
     829        (void)arglen;
     830        (void)setupchild;
    829831        error(psh, "Cannot fork");
    830832        return -1; /* won't get here */
  • trunk/src/kash/jobs.h

    r3435 r3437  
    9898int forkshell2(struct shinstance *, struct job *, union node *, int,
    9999               int (*child)(struct shinstance *, void *, union node *),
    100                union node *, void *, size_t);
     100               union node *, void *, size_t,
     101               void (*setupchild)(struct shinstance *, struct shinstance *, void *));
    101102#else
    102103int forkshell(struct shinstance *, struct job *, union node *, int);
  • trunk/src/kash/memalloc.c

    r2638 r3437  
    146146        psh->stacknleft -= (int)nbytes;
    147147        return p;
     148}
     149
     150
     151char *
     152stsavestr(struct shinstance *psh, const char *src)
     153{
     154        if (src) {
     155                size_t size = strlen(src) + 1;
     156                char *dst = (char *)stalloc(psh, size);
     157                return (char *)memcpy(dst, src, size);
     158        }
     159        return NULL;
    148160}
    149161
  • trunk/src/kash/memalloc.h

    r2290 r3437  
    5252char *savestr(struct shinstance *, const char *);
    5353pointer stalloc(struct shinstance *, size_t);
     54char *stsavestr(struct shinstance *, const char *);
    5455void stunalloc(struct shinstance *, pointer);
    5556void setstackmark(struct shinstance *, struct stackmark *);
  • trunk/src/kash/nodetypes

    r1215 r3437  
    118118NAPPEND nfile                   # fd>> fname
    119119        type      int
    120         next      nodeptr               # next redirection in list
    121         fd        int                   # file descriptor being redirected
     120        fd        int                   # file descriptor being redirected (must match ndup)
     121        next      nodeptr               # next redirection in list         (must match ndup)
    122122        fname     nodeptr               # file name, in a NARG node
    123123        expfname  temp  char *expfname  # actual file name
     
    126126NFROMFD ndup                    # fd>&dupfd
    127127        type      int
    128         next      nodeptr               # next redirection in list
    129         fd        int                   # file descriptor being redirected
     128        fd        int                   # file descriptor being redirected (must match nfile)
     129        next      nodeptr               # next redirection in list         (must match nfile)
    130130        dupfd     int                   # file descriptor to duplicate
    131131        vname     nodeptr               # file name if fd>&$var
     
    135135NXHERE nhere                    # fd<<!
    136136        type      int
    137         next      nodeptr               # next redirection in list
    138         fd        int                   # file descriptor being redirected
     137        fd        int                   # file descriptor being redirected (must match nfile)
     138        next      nodeptr               # next redirection in list         (must match nfile)
    139139        doc       nodeptr               # input to command (NARG node)
    140140
  • trunk/src/kash/parser.c

    r3065 r3437  
    11971197
    11981198parseredir: {
     1199        union node *np;
    11991200        char fd = *out;
    1200         union node *np;
     1201        char dummy[   sizeof(struct nfile) >= sizeof(struct ndup)
     1202                   && sizeof(struct nfile) >= sizeof(struct nhere) ? 1 : 0];
     1203        (void)dummy;
    12011204
    12021205        np = (union node *)stalloc(psh, sizeof (struct nfile));
     
    12181221                switch (c = pgetc(psh)) {
    12191222                case '<':
    1220                         if (sizeof (struct nfile) != sizeof (struct nhere)) {
    1221                                 np = (union node *)stalloc(psh, sizeof (struct nhere));
    1222                                 np->nfile.fd = 0;
    1223                         }
    12241223                        np->type = NHERE;
    12251224                        psh->heredoc = (struct heredoc *)stalloc(psh, sizeof (struct heredoc));
     
    14171416
    14181417                        case '\\':
    1419                                 if ((pc = pgetc(psh)) == '\n') {
     1418                                if ((pc = pgetc(psh)) == '\n') {
    14201419                                        psh->plinno++;
    14211420                                        if (psh->doprompt)
     
    14311430                                        continue;
    14321431                                }
    1433                                 if (pc != '\\' && pc != '`' && pc != '$'
    1434                                     && (!ISDBLQUOTE() || pc != '"'))
    1435                                         STPUTC(psh, '\\', pout);
     1432                                if (pc != '\\' && pc != '`' && pc != '$' && (!ISDBLQUOTE() || pc != '"'))
     1433                                        STPUTC(psh, '\\', pout);
    14361434                                break;
    14371435
     
    17791777        }
    17801778}
     1779
     1780/*
     1781 * Helper to copyparsetree.
     1782 */
     1783static struct nodelist *
     1784copynodelist(shinstance *psh, struct nodelist *src)
     1785{
     1786        struct nodelist *ret = NULL;
     1787        if (src) {
     1788                struct nodelist **ppnext = &ret;
     1789                while (src) {
     1790                        struct nodelist *dst = stalloc(psh, sizeof(*dst));
     1791                        dst->next = NULL;
     1792                        *ppnext = dst;
     1793                        ppnext = &dst->next;
     1794                        dst->n = copyparsetree(psh, src->n);
     1795                }
     1796        }
     1797        return ret;
     1798}
     1799
     1800/*
     1801 * Duplicates a node tree.
     1802 *
     1803 * Note! This could probably be generated from nodelist.
     1804 */
     1805union node *
     1806copyparsetree(shinstance *psh, union node *src)
     1807{
     1808        /** @todo Try avoid recursion for one of the sub-nodes, esp. when there
     1809         *        is a list like 'next' one. */
     1810        union node *ret;
     1811        if (src) {
     1812                int const type = src->type;
     1813                switch (type) {
     1814                        case NSEMI:
     1815                        case NAND:
     1816                        case NOR:
     1817                        case NWHILE:
     1818                        case NUNTIL:
     1819                                ret = (union node *)stalloc(psh, sizeof(src->nbinary));
     1820                                ret->nbinary.type = type;
     1821                                ret->nbinary.ch1  = copyparsetree(psh, src->nbinary.ch1);
     1822                                ret->nbinary.ch2  = copyparsetree(psh, src->nbinary.ch2);
     1823                                break;
     1824
     1825                        case NCMD:
     1826                                ret = (union node *)stalloc(psh, sizeof(src->ncmd));
     1827                                ret->ncmd.type     = NCMD;
     1828                                ret->ncmd.backgnd  = src->ncmd.backgnd;
     1829                                ret->ncmd.args     = copyparsetree(psh, src->ncmd.args);
     1830                                ret->ncmd.redirect = copyparsetree(psh, src->ncmd.redirect);
     1831                                break;
     1832
     1833                        case NPIPE:
     1834                                ret = (union node *)stalloc(psh, sizeof(src->npipe));
     1835                                ret->npipe.type     = NPIPE;
     1836                                ret->npipe.backgnd  = src->ncmd.backgnd;
     1837                                ret->npipe.cmdlist  = copynodelist(psh, src->npipe.cmdlist);
     1838                                break;
     1839
     1840                        case NREDIR:
     1841                        case NBACKGND:
     1842                        case NSUBSHELL:
     1843                                ret = (union node *)stalloc(psh, sizeof(src->nredir));
     1844                                ret->nredir.type     = type;
     1845                                ret->nredir.n        = copyparsetree(psh, src->nredir.n);
     1846                                ret->nredir.redirect = copyparsetree(psh, src->nredir.redirect);
     1847                                break;
     1848
     1849                        case NIF:
     1850                                ret = (union node *)stalloc(psh, sizeof(src->nif));
     1851                                ret->nif.type        = NIF;
     1852                                ret->nif.test        = copyparsetree(psh, src->nif.test);
     1853                                ret->nif.ifpart      = copyparsetree(psh, src->nif.ifpart);
     1854                                ret->nif.elsepart    = copyparsetree(psh, src->nif.elsepart);
     1855                                break;
     1856
     1857                        case NFOR:
     1858                                ret = (union node *)stalloc(psh, sizeof(src->nfor));
     1859                                ret->nfor.type       = NFOR;
     1860                                ret->nfor.args       = copyparsetree(psh, src->nfor.args);
     1861                                ret->nfor.body       = copyparsetree(psh, src->nfor.body);
     1862                                ret->nfor.var        = stsavestr(psh, src->nfor.var);
     1863                                break;
     1864
     1865                        case NCASE:
     1866                                ret = (union node *)stalloc(psh, sizeof(src->ncase));
     1867                                ret->ncase.type      = NCASE;
     1868                                ret->ncase.expr      = copyparsetree(psh, src->ncase.expr);
     1869                                ret->ncase.cases     = copyparsetree(psh, src->ncase.cases);
     1870                                break;
     1871
     1872                        case NCLIST:
     1873                                ret = (union node *)stalloc(psh, sizeof(src->nclist));
     1874                                ret->nclist.type     = NCLIST;
     1875                                ret->nclist.next     = copyparsetree(psh, src->nclist.next);
     1876                                ret->nclist.pattern  = copyparsetree(psh, src->nclist.pattern);
     1877                                ret->nclist.body     = copyparsetree(psh, src->nclist.body);
     1878                                break;
     1879
     1880                        case NDEFUN:
     1881                        case NARG:
     1882                                ret = (union node *)stalloc(psh, sizeof(src->narg));
     1883                                ret->narg.type       = type;
     1884                                ret->narg.next       = copyparsetree(psh, src->narg.next);
     1885                                ret->narg.text       = stsavestr(psh, src->narg.text);
     1886                                ret->narg.backquote  = copynodelist(psh, src->narg.backquote);
     1887                                break;
     1888
     1889                        case NTO:
     1890                        case NCLOBBER:
     1891                        case NFROM:
     1892                        case NFROMTO:
     1893                        case NAPPEND:
     1894                                ret = (union node *)stalloc(psh, sizeof(src->nfile));
     1895                                ret->nfile.type      = type;
     1896                                ret->nfile.fd        = src->nfile.fd;
     1897                                ret->nfile.next      = copyparsetree(psh, src->nfile.next);
     1898                                ret->nfile.fname     = copyparsetree(psh, src->nfile.fname);
     1899                                ret->nfile.expfname  = stsavestr(psh, src->nfile.expfname);
     1900                                break;
     1901
     1902                        case NTOFD:
     1903                        case NFROMFD:
     1904                                ret = (union node *)stalloc(psh, sizeof(src->ndup));
     1905                                ret->ndup.type       = type;
     1906                                ret->ndup.fd         = src->ndup.fd;
     1907                                ret->ndup.next       = copyparsetree(psh, src->ndup.next);
     1908                                ret->ndup.dupfd      = src->ndup.dupfd;
     1909                                ret->ndup.vname      = copyparsetree(psh, src->ndup.vname);
     1910                                break;
     1911
     1912                        case NHERE:
     1913                        case NXHERE:
     1914                                ret = (union node *)stalloc(psh, sizeof(src->nhere));
     1915                                ret->nhere.type      = type;
     1916                                ret->nhere.fd        = src->nhere.fd;
     1917                                ret->nhere.next      = copyparsetree(psh, src->nhere.next);
     1918                                ret->nhere.doc       = copyparsetree(psh, src->nhere.doc);
     1919                                break;
     1920
     1921                        case NNOT:
     1922                                ret = (union node *)stalloc(psh, sizeof(src->nnot));
     1923                                ret->nnot.type      = NNOT;
     1924                                ret->nnot.com       = copyparsetree(psh, src->nnot.com);
     1925                                break;
     1926
     1927                        default:
     1928                                error(psh, "Unknown node type: %d (node=%p)", src->type, src);
     1929                                return NULL;
     1930                }
     1931        } else {
     1932                ret = NULL;
     1933        }
     1934        return ret;
     1935}
     1936
  • trunk/src/kash/parser.h

    r1233 r3437  
    8484int goodname(const char *);
    8585const char *getprompt(struct shinstance *, void *);
     86union node *copyparsetree(shinstance *, union node *);
    8687
    8788#endif
  • trunk/src/kash/redir.c

    r3435 r3437  
    289289                args.len = len;
    290290                forkshell2(psh, (struct job *)NULL, (union node *)NULL, FORK_NOJOB,
    291                            openhere_child, redir, &args, sizeof(args));
     291                           openhere_child, redir, &args, sizeof(args), NULL);
    292292        }
    293293#else
  • trunk/src/kash/shinstance.c

    r3409 r3437  
    241241    if (psh)
    242242    {
    243         /* Init it enought for sh_destroy() to not get upset */
     243        /* Init it enough for sh_destroy() to not get upset */
    244244          /* ... */
    245245
Note: See TracChangeset for help on using the changeset viewer.

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