Ignore:
Timestamp:
Sep 9, 2020, 10:01:39 PM (5 years ago)
Author:
bird
Message:

kash: Hammering on threaded mode.

File:
1 edited

Legend:

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

    r2652 r3438  
    4141#endif
    4242
     43#include <assert.h>
    4344#include <stdlib.h>
    4445
     
    7778STATIC int getopts(shinstance *, char *, char *, char **, char ***, char **);
    7879
     80#ifndef SH_FORKED_MODE
     81void
     82subshellinitoptions(shinstance *psh, shinstance *inherit)
     83{
     84    unsigned i;
     85    int left;
     86    const char *arg;
     87    memcpy(&psh->optlist[0], &inherit->optlist[0], sizeof(psh->optlist));
     88
     89    /** @todo opimize: skip this when executing builtins. */
     90    /* Whether the subshell uses argptr/shellparam/arg0 or replaces them depends
     91       on whether the shell will execute a builtin command or not.
     92
     93       orgargv is already set by the shinstance.c core code, scan the original
     94       again and update arg0, shellparm, argptr and optptr. */
     95
     96    /* arg0 is either something from orgargv, or in the EXSHELLPROC case a
     97       separate allocation that we need to dupe here. The (new) arg0malloc
     98       flag indicates which. */
     99    i = 0;
     100    psh->arg0malloc = inherit->arg0malloc;
     101    if (inherit->arg0malloc) {
     102        psh->arg0 = savestr(psh, inherit->arg0);
     103    } else {
     104        while ((arg = inherit->orgargv[i]) != NULL) {
     105            if (inherit->arg0 == arg) {
     106                psh->arg0 = psh->orgargv[i];
     107                break;
     108            }
     109            i++;
     110        }
     111        assert(psh->arg0 != NULL);
     112    }
     113
     114    /* eval.h's commandname is same as arg0 when set unless we're doing a dot-include. */
     115    if (inherit->commandname) {
     116        if (inherit->commandname == inherit->arg0) {
     117            psh->commandname = psh->arg0;
     118        } else {
     119            psh->commandname = savestr(psh, inherit->commandname);
     120            psh->commandnamemalloc = 1;
     121        }
     122    }
     123
     124    /* shellparam is either pointing right after arg0 in orgargv, though it may
     125       also be a separately allocated thing (see setparam), or pointing to the
     126       arguments of a shell function we're executing (see eval.c).  All in all,
     127       it's simpler if we just copy the whole darn thing, ASSUMING no
     128       modifications will be made that are needed to be visible elsewhere.
     129       */
     130    psh->shellparam.malloc = 1;
     131    psh->shellparam.reset  = inherit->shellparam.reset;
     132    psh->shellparam.nparam = left = inherit->shellparam.nparam;
     133    assert(left >= 0);
     134    psh->shellparam.p = (char **)ckmalloc(psh, left + 1);
     135    psh->shellparam.p[left] = NULL;
     136    while (left-- > 0) {
     137        arg = inherit->shellparam.p[left];
     138        psh->shellparam.p[left] = savestr(psh, arg);
     139    }
     140
     141    /* The shellparam.optnext member is either NULL or points to a 'p' entry. */
     142    if (inherit->shellparam.optnext) {
     143        size_t idx = (size_t)(inherit->shellparam.optnext - inherit->shellparam.p);
     144        assert(idx <= inherit->shellparam.nparam);
     145        if (idx <= inherit->shellparam.nparam)
     146            psh->shellparam.optnext = &psh->shellparam.p[idx];
     147    }
     148
     149    /* The shellparam.optptr member is either NULL or points within argument
     150       prior to shellparam.optnext.  We can leave it as NULL if at the EOS. */
     151    if (inherit->shellparam.optptr && *inherit->shellparam.optptr != '\0') {
     152        intptr_t idx;
     153        if (!inherit->shellparam.optnext || inherit->shellparam.optnext == inherit->shellparam.p)
     154            idx = (intptr_t)(inherit->shellparam.nparam - 1);
     155        else {
     156            idx = (intptr_t)(inherit->shellparam.optnext - inherit->shellparam.p - 1);
     157            if (idx > inherit->shellparam.nparam)
     158                idx = inherit->shellparam.nparam - 1;
     159        }
     160        while (idx >= 0) {
     161            size_t arglen, off;
     162            arg = inherit->shellparam.p[idx];
     163            arglen = strlen(arg);
     164            off = (size_t)(inherit->shellparam.optptr - arg);
     165            if (off < arglen) {
     166                psh->shellparam.optptr = psh->shellparam.p[idx] + off;
     167                break;
     168            }
     169            off--;
     170        }
     171        assert(psh->shellparam.optptr != NULL);
     172    }
     173
     174    /* minusc:    only used in main.c, so not applicable to subshells. */
     175    /* optionarg: only used by callers of nextopt, so not relevant when forking subhells. */
     176}
     177#endif /* SH_FORKED_MODE */
     178
    79179
    80180/*
     
    105205        debug(psh) = 1;
    106206#endif
     207        psh->commandnamemalloc = 0;
     208        psh->arg0malloc = 0;
    107209        psh->arg0 = argv[0];
    108210        if (sflag(psh) == 0 && psh->minusc == NULL) {
Note: See TracChangeset for help on using the changeset viewer.