Changeset 3439 for trunk/src


Ignore:
Timestamp:
Sep 10, 2020, 2:47:29 AM (5 years ago)
Author:
bird
Message:

kash: Hammering on threaded mode. Got shexit half working. Incomplete sh_destroy.

Location:
trunk/src/kash
Files:
6 edited

Legend:

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

    r3438 r3439  
    18971897                                ret->nfile.next      = copyparsetree(psh, src->nfile.next);
    18981898                                ret->nfile.fname     = copyparsetree(psh, src->nfile.fname);
     1899                                /** @todo complicated, we should copy it in some contexts but no all. sigh.  */
    18991900                                ret->nfile.expfname  = stsavestr(psh, src->nfile.expfname);
    19001901                                break;
  • trunk/src/kash/shfile.c

    r3438 r3439  
    9999{
    100100    ULONG           Attributes;
    101         ACCESS_MASK     GrantedAccess;
    102         ULONG           HandleCount;
    103         ULONG           PointerCount;
    104         ULONG           PagedPoolUsage;
    105         ULONG           NonPagedPoolUsage;
    106         ULONG           Reserved[3];
    107         ULONG           NameInformationLength;
    108         ULONG           TypeInformationLength;
    109         ULONG           SecurityDescriptorLength;
    110         LARGE_INTEGER   CreateTime;
     101    ACCESS_MASK     GrantedAccess;
     102    ULONG           HandleCount;
     103    ULONG           PointerCount;
     104    ULONG           PagedPoolUsage;
     105    ULONG           NonPagedPoolUsage;
     106    ULONG           Reserved[3];
     107    ULONG           NameInformationLength;
     108    ULONG           TypeInformationLength;
     109    ULONG           SecurityDescriptorLength;
     110    LARGE_INTEGER   CreateTime;
    111111} MY_OBJECT_BASIC_INFORMATION;
    112112
     
    910910}
    911911
     912/**
     913 * Deletes the file descriptor table.
     914 *
     915 * Safe to call more than once.
     916 */
     917void shfile_uninit(shfdtab *pfdtab)
     918{
     919    if (!pfdtab)
     920        return;
     921
     922    if (pfdtab->tab)
     923    {
     924        unsigned left = pfdtab->size;
     925        struct shfile *pfd = pfdtab->tab;
     926        while (left-- > 0)
     927        {
     928            if (pfd->fd != -1)
     929            {
     930#if K_OS == K_OS_WINDOWS
     931                BOOL rc = CloseHandle((HANDLE)pfd->native);
     932                assert(rc == TRUE); K_NOREF(rc);
     933#else
     934                int rc = close((int)pfd->native);
     935                assert(rc == 0); K_NOREF(rc);
     936#endif
     937                pfd->fd     = -1;
     938                pfd->native = -1;
     939            }
     940            pfd++;
     941        }
     942
     943        sh_free(NULL, pfdtab->tab);
     944        pfdtab->tab = NULL;
     945    }
     946
     947    shmtx_delete(&pfdtab->mtx);
     948
     949    sh_free(NULL, pfdtab->cwd);
     950    pfdtab->cwd = NULL;
     951}
     952
    912953#if K_OS == K_OS_WINDOWS && defined(SHFILE_IN_USE)
    913954
     
    956997}
    957998
     999# ifdef SH_FORKED_MODE
    9581000/**
    9591001 * Helper for shfork.
     
    10001042    shmtx_leave(&pfdtab->mtx, &tmp);
    10011043}
     1044# endif /* SH_FORKED_MODE */
    10021045
    10031046/**
  • trunk/src/kash/shfile.h

    r2546 r3439  
    131131
    132132int shfile_init(shfdtab *, shfdtab *);
     133void shfile_uninit(shfdtab *);
    133134void shfile_fork_win(shfdtab *pfdtab, int set, intptr_t *hndls);
    134135void *shfile_exec_win(shfdtab *pfdtab, int prepare, unsigned short *sizep, intptr_t *hndls);
  • trunk/src/kash/shinstance.c

    r3438 r3439  
    2626 */
    2727
    28 /*******************************************************************************
    29 *   Header Files                                                               *
    30 *******************************************************************************/
     28
     29/*********************************************************************************************************************************
     30*   Header Files                                                                                                                 *
     31*********************************************************************************************************************************/
    3132#include <string.h>
    3233#include <stdlib.h>
     
    4142
    4243#include "alias.h"
     44#include "error.h"
    4345#include "memalloc.h"
    4446#include "shell.h"
     
    5355
    5456
    55 /*******************************************************************************
    56 *   Global Variables                                                           *
    57 *******************************************************************************/
     57/*********************************************************************************************************************************
     58*   Defined Constants And Macros                                                                                                 *
     59*********************************************************************************************************************************/
     60#ifndef SH_FORKED_MODE
     61/** Used by sh__exit/sh_thread_wrapper for passing zero via longjmp.  */
     62# define SH_EXIT_ZERO    0x0d15ea5e
     63#endif
     64
     65
     66/*********************************************************************************************************************************
     67*   Global Variables                                                                                                             *
     68*********************************************************************************************************************************/
    5869/** The mutex protecting the the globals and some shell instance members (sigs). */
    5970static shmtx        g_sh_mtx;
     
    93104
    94105
     106/** Magic mutex value (final u64).
     107 * This is used to detect whether the mutex has been initialized or not,
     108 * allowing shmtx_delete to be called more than once without doing harm.
     109 * @internal */
     110#define SHMTX_MAGIC        KU64_C(0x8888000019641018) /**< Charles Stross */
     111/** Index into shmtx::au64 of the SHMTX_MAGIC value.
     112 * @internal */
     113#define SHMTX_MAGIC_IDX    (sizeof(shmtx) / sizeof(KU64) - 1)
     114
    95115int shmtx_init(shmtx *pmtx)
    96116{
     117#if K_OS == K_OS_WINDOWS
     118    typedef int mtxsizecheck[sizeof(CRITICAL_SECTION) + sizeof(KU64) <= sizeof(*pmtx) ? 2 : 0];
     119    InitializeCriticalSection((CRITICAL_SECTION *)pmtx);
     120#else
    97121    pmtx->b[0] = 0;
     122#endif
     123    pmtx->au64[SHMTX_MAGIC_IDX] = SHMTX_MAGIC;
    98124    return 0;
    99125}
    100126
     127/**
     128 * Safe to call more than once.
     129 */
    101130void shmtx_delete(shmtx *pmtx)
    102131{
    103     pmtx->b[0] = 0;
     132    if (pmtx->au64[SHMTX_MAGIC_IDX] != SHMTX_MAGIC)
     133    {
     134#if K_OS == K_OS_WINDOWS
     135        DeleteCriticalSection((CRITICAL_SECTION *)pmtx);
     136#else
     137        pmtx->b[0] = 0;
     138#endif
     139        pmtx->au64[SHMTX_MAGIC_IDX] = ~SHMTX_MAGIC;
     140    }
    104141}
    105142
    106143void shmtx_enter(shmtx *pmtx, shmtxtmp *ptmp)
    107144{
     145#if K_OS == K_OS_WINDOWS
     146    EnterCriticalSection((CRITICAL_SECTION *)pmtx);
     147    ptmp->i = 0x42;
     148#else
    108149    pmtx->b[0] = 0;
    109150    ptmp->i = 0;
     151#endif
    110152}
    111153
    112154void shmtx_leave(shmtx *pmtx, shmtxtmp *ptmp)
    113155{
     156#if K_OS == K_OS_WINDOWS
     157    assert(ptmp->i == 0x42);
     158    LeaveCriticalSection((CRITICAL_SECTION *)pmtx);
     159    ptmp->i = 0x21;
     160#else
    114161    pmtx->b[0] = 0;
    115162    ptmp->i = 432;
     163#endif
    116164}
    117165
     
    139187    g_num_shells++;
    140188
     189    psh->linked = 1;
     190
    141191    shmtx_leave(&g_sh_mtx, &tmp);
    142192}
    143193
    144 #if 0
    145194/**
    146195 * Unlink the shell instance.
     
    150199static void sh_int_unlink(shinstance *psh)
    151200{
    152     shmtxtmp tmp;
    153     shmtx_enter(&g_sh_mtx, &tmp);
    154 
    155     g_num_shells--;
    156 
    157     if (g_sh_tail == psh)
    158         g_sh_tail = psh->prev;
    159     else
    160         psh->next->prev = psh->prev;
    161 
    162     if (g_sh_head == psh)
    163         g_sh_head = psh->next;
    164     else
    165         psh->prev->next = psh->next;
    166 
    167     if (g_sh_root == psh)
    168         g_sh_root = 0;
    169 
    170     shmtx_leave(&g_sh_mtx, &tmp);
    171 }
    172 #endif
     201    if (psh->linked)
     202    {
     203        shinstance *pshcur;
     204        shmtxtmp tmp;
     205        shmtx_enter(&g_sh_mtx, &tmp);
     206
     207        g_num_shells--;
     208
     209        if (g_sh_tail == psh)
     210            g_sh_tail = psh->prev;
     211        else
     212            psh->next->prev = psh->prev;
     213
     214        if (g_sh_head == psh)
     215            g_sh_head = psh->next;
     216        else
     217            psh->prev->next = psh->next;
     218
     219        if (g_sh_root == psh)
     220            g_sh_root = NULL;
     221
     222        /* Orphan children: */
     223        for (pshcur = g_sh_head; pshcur; pshcur = pshcur->next)
     224            if (pshcur->parent == psh)
     225                pshcur->parent = NULL;
     226
     227        shmtx_leave(&g_sh_mtx, &tmp);
     228    }
     229}
     230
     231/**
     232 * Frees a string vector like environ or argv.
     233 *
     234 * @param   psh     The shell to associate the deallocations with.
     235 * @param   vecp    Pointer to the vector pointer.
     236 */
     237static void sh_free_string_vector(shinstance *psh, char ***vecp)
     238{
     239    char **vec = *vecp;
     240    if (vec)
     241    {
     242        char *str;
     243        size_t i = 0;
     244        while ((str = vec[i]) != NULL)
     245        {
     246            sh_free(psh, str);
     247            vec[i] = NULL;
     248            i++;
     249        }
     250
     251        sh_free(psh, vec);
     252        *vecp = NULL;
     253    }
     254}
     255
    173256
    174257/**
     
    178261 *
    179262 * @param   psh     The shell instance to be destroyed.
     263 * @note    invalidate thread arguments.
    180264 */
    181265static void sh_destroy(shinstance *psh)
    182266{
     267    unsigned left, i;
     268
     269    sh_int_unlink(psh);
     270    shfile_uninit(&psh->fdtab);
     271    sh_free_string_vector(psh, &psh->shenviron);
     272
     273    /** @todo children. */
     274    sh_free(psh, psh->threadarg);
     275    psh->threadarg = NULL;
     276
     277    /* alias.c */
     278    left = psh->aliases;
     279    if (left > 0)
     280        for (i = 0; i < K_ELEMENTS(psh->atab); i++)
     281        {
     282            struct alias *cur = psh->atab[i];
     283            if (cur)
     284            {
     285                do
     286                {
     287                    struct alias *next = cur->next;
     288                    sh_free(psh, cur->val);
     289                    sh_free(psh, cur->name);
     290                    sh_free(psh, cur);
     291                    cur = next;
     292                    left--;
     293                } while (cur);
     294                psh->atab[i] = NULL;
     295                if (!left)
     296                    break;
     297            }
     298        }
     299
     300    /* cd.c */
     301    sh_free(psh, psh->curdir);
     302    psh->curdir = NULL;
     303    sh_free(psh, psh->prevdir);
     304    psh->prevdir = NULL;
     305    psh->cdcomppath = NULL; /* stalloc */
     306
     307    /* eval.h */
     308    if (psh->commandnamemalloc)
     309        sh_free(psh, psh->commandname);
     310    psh->commandname = NULL;
     311    psh->cmdenviron = NULL;
     312
     313#if 0
     314    /* expand.c */
     315    char               *expdest;        /**< output of current string */
     316    struct nodelist    *argbackq;       /**< list of back quote expressions */
     317    struct ifsregion    ifsfirst;       /**< first struct in list of ifs regions */
     318    struct ifsregion   *ifslastp;       /**< last struct in list */
     319    struct arglist      exparg;         /**< holds expanded arg list */
     320    char               *expdir;         /**< Used by expandmeta. */
     321
     322    /* exec.h */
     323    const char         *pathopt;        /**< set by padvance */
     324
     325    /* exec.c */
     326    struct tblentry    *cmdtable[CMDTABLESIZE];
     327    int                 builtinloc/* = -1*/;    /**< index in path of %builtin, or -1 */
     328
     329    /* input.h */
     330    int                 plinno/* = 1 */;/**< input line number */
     331    int                 parsenleft;     /**< number of characters left in input buffer */
     332    char               *parsenextc;     /**< next character in input buffer */
     333    int                 init_editline/* = 0 */;     /**< 0 == not setup, 1 == OK, -1 == failed */
     334
     335    /* input.c */
     336    int                 parselleft;     /**< copy of parsefile->lleft */
     337    struct parsefile    basepf;         /**< top level input file */
     338    char                basebuf[BUFSIZ];/**< buffer for top level input file */
     339    struct parsefile   *parsefile/* = &basepf*/;    /**< current input file */
     340#ifndef SMALL
     341    EditLine           *el;             /**< cookie for editline package */
     342#endif
     343
     344    /* jobs.h */
     345    shpid               backgndpid/* = -1 */;   /**< pid of last background process */
     346    int                 job_warning;    /**< user was warned about stopped jobs */
     347
     348    /* jobs.c */
     349    struct job         *jobtab;         /**< array of jobs */
     350    int                 njobs;          /**< size of array */
     351    int                 jobs_invalid;   /**< set in child */
     352    shpid               initialpgrp;    /**< pgrp of shell on invocation */
     353    int                 curjob/* = -1*/;/**< current job */
     354    int                 ttyfd/* = -1*/;
     355    int                 jobctl;         /**< job control enabled / disabled */
     356    char               *cmdnextc;
     357    int                 cmdnleft;
     358
     359
     360    /* mail.c */
     361#define MAXMBOXES 10
     362    int                 nmboxes;        /**< number of mailboxes */
     363    time_t              mailtime[MAXMBOXES]; /**< times of mailboxes */
     364
     365    /* main.h */
     366    shpid               rootpid;        /**< pid of main shell. */
     367    int                 rootshell;      /**< true if we aren't a child of the main shell. */
     368    struct shinstance  *psh_rootshell;  /**< The root shell pointer. (!rootshell) */
     369
     370    /* memalloc.h */
     371    char               *stacknxt/* = stackbase.space*/;
     372    int                 stacknleft/* = MINSIZE*/;
     373    int                 sstrnleft;
     374    int                 herefd/* = -1 */;
     375
     376    /* memalloc.c */
     377    struct stack_block  stackbase;
     378    struct stack_block *stackp/* = &stackbase*/;
     379    struct stackmark   *markp;
     380
     381    /* myhistedit.h */
     382    int                 displayhist;
     383#ifndef SMALL
     384    History            *hist;
     385    EditLine           *el;
     386#endif
     387
     388    /* output.h */
     389    struct output       output;
     390    struct output       errout;
     391    struct output       memout;
     392    struct output      *out1;
     393    struct output      *out2;
     394
     395    /* output.c */
     396#define OUTBUFSIZ BUFSIZ
     397#define MEM_OUT -3                      /**< output to dynamically allocated memory */
     398
     399    /* options.h */
     400    struct optent       optlist[NOPTS];
     401    char               *minusc;         /**< argument to -c option */
     402    char               *arg0;           /**< $0 */
     403    struct shparam      shellparam;     /**< $@ */
     404    char              **argptr;         /**< argument list for builtin commands */
     405    char               *optionarg;      /**< set by nextopt */
     406    char               *optptr;         /**< used by nextopt */
     407    char              **orgargv;        /**< The original argument vector (for cleanup). */
     408    int                 arg0malloc;     /**< Indicates whether arg0 was allocated or is part of orgargv. */
     409
     410    /* parse.h */
     411    int                 tokpushback;
     412    int                 whichprompt;    /**< 1 == PS1, 2 == PS2 */
     413
     414    /* parser.c */
     415    int                 noalias/* = 0*/;/**< when set, don't handle aliases */
     416    struct heredoc     *heredoclist;    /**< list of here documents to read */
     417    int                 parsebackquote; /**< nonzero if we are inside backquotes */
     418    int                 doprompt;       /**< if set, prompt the user */
     419    int                 needprompt;     /**< true if interactive and at start of line */
     420    int                 lasttoken;      /**< last token read */
     421    char               *wordtext;       /**< text of last word returned by readtoken */
     422    int                 checkkwd;       /**< 1 == check for kwds, 2 == also eat newlines */
     423    struct nodelist    *backquotelist;
     424    union node         *redirnode;
     425    struct heredoc     *heredoc;
     426    int                 quoteflag;      /**< set if (part of) last token was quoted */
     427    int                 startlinno;     /**< line # where last token started */
     428
     429    /* redir.c */
     430    struct redirtab    *redirlist;
     431    int                 fd0_redirected/* = 0*/;
     432
     433    /* show.c */
     434    char                tracebuf[1024];
     435    size_t              tracepos;
     436    int                 tracefd;
     437
     438    /* trap.h */
     439    int                 pendingsigs;    /**< indicates some signal received */
     440
     441    /* trap.c */
     442    char                gotsig[NSIG];   /**< indicates specified signal received */
     443    char               *trap[NSIG+1];   /**< trap handler commands */
     444    char                sigmode[NSIG];  /**< current value of signal */
     445
     446    /* var.h */
     447    struct localvar    *localvars;
     448    struct var          vatty;
     449    struct var          vifs;
     450    struct var          vmail;
     451    struct var          vmpath;
     452    struct var          vpath;
     453#ifdef _MSC_VER
     454    struct var          vpath2;
     455#endif
     456    struct var          vps1;
     457    struct var          vps2;
     458    struct var          vps4;
     459#ifndef SMALL
     460    struct var          vterm;
     461    struct var          vhistsize;
     462#endif
     463    struct var          voptind;
     464#ifdef PC_OS2_LIBPATHS
     465    struct var          libpath_vars[4];
     466#endif
     467#ifdef SMALL
     468# define VTABSIZE 39
     469#else
     470# define VTABSIZE 517
     471#endif
     472    struct var         *vartab[VTABSIZE];
     473
     474    /* builtins.h */
     475
     476    /* bltin/test.c */
     477    char              **t_wp;
     478    struct t_op const  *t_wp_op;
     479#endif
     480
    183481/** @todo finish this...   */
    184482    memset(psh, 0, sizeof(*psh));
     
    196494static int sh_clone_string_vector(shinstance *psh, char ***dstp, char **src)
    197495{
    198    char **dst;
    199    size_t items;
    200 
    201    /* count first */
    202    items = 0;
    203    while (src[items])
    204        items++;
    205 
    206    /* alloc clone array. */
    207    *dstp = dst = sh_malloc(psh, sizeof(*dst) * (items + 1));
    208    if (!dst)
    209        return -1;
    210 
    211    /* copy the items */
    212    dst[items] = NULL;
    213    while (items-- > 0)
    214    {
    215        dst[items] = sh_strdup(psh, src[items]);
    216        if (!dst[items])
    217        {
    218            /* allocation error, clean up. */
    219            while (dst[++items])
    220                sh_free(psh, dst[items]);
    221            sh_free(psh, dst);
    222            errno = ENOMEM;
    223            return -1;
    224        }
    225    }
    226 
    227    return 0;
     496    char **dst;
     497    size_t items;
     498
     499    /* count first */
     500    items = 0;
     501    while (src[items])
     502        items++;
     503
     504    /* alloc clone array. */
     505    *dstp = dst = sh_malloc(psh, sizeof(*dst) * (items + 1));
     506    if (!dst)
     507        return -1;
     508
     509    /* copy the items */
     510    dst[items] = NULL;
     511    while (items-- > 0)
     512    {
     513        dst[items] = sh_strdup(psh, src[items]);
     514        if (!dst[items])
     515        {
     516            /* allocation error, clean up. */
     517            while (dst[++items])
     518                sh_free(psh, dst[items]);
     519            sh_free(psh, dst);
     520            errno = ENOMEM;
     521            return -1;
     522        }
     523    }
     524
     525    return 0;
    228526}
    229527
     
    338636shinstance *sh_create_root_shell(char **argv, char **envp)
    339637{
    340     shinstance *psh = sh_create_shell_common(argv, envp, NULL /*parentfdtab*/);
     638    shinstance *psh;
     639
     640    assert(g_sh_mtx.au64[SHMTX_MAGIC_IDX] != SHMTX_MAGIC);
     641    shmtx_init(&g_sh_mtx);
     642
     643    psh = sh_create_shell_common(argv, envp, NULL /*parentfdtab*/);
    341644    if (psh)
    342645    {
     
    10491352{
    10501353    /* get a free table entry. */
    1051     int i = psh->num_children++;
     1354    unsigned i = psh->num_children++;
    10521355    if (!(i % 32))
    10531356    {
     
    11181421static unsigned __stdcall sh_thread_wrapper(void *user)
    11191422{
     1423    shinstance * volatile volpsh = (shinstance *)user;
    11201424    shinstance *psh = (shinstance *)user;
     1425    struct jmploc exitjmp;
    11211426    int iExit;
    11221427
     
    11331438
    11341439    TRACE2((psh, "sh_thread_wrapper: enter\n"));
    1135     iExit = psh->thread(psh, psh->threadarg);
    1136 /** @todo do shell cleanup. */
     1440    if ((iExit = setjmp(exitjmp.loc)) == 0)
     1441    {
     1442        psh->exitjmp = &exitjmp;
     1443        iExit = psh->thread(psh, psh->threadarg);
     1444        TRACE2((psh, "sh_thread_wrapper: thread proc returns %d (%#x)\n", iExit, iExit));
     1445    }
     1446    else
     1447    {
     1448        psh = volpsh; /* paranoia */
     1449        psh->exitjmp = NULL;
     1450        TRACE2((psh, "sh_thread_wrapper: longjmp: iExit=%d (%#x)\n", iExit, iExit));
     1451        if (iExit == SH_EXIT_ZERO)
     1452            iExit = 0;
     1453    }
     1454
     1455    /* destroy the shell instance and exit the thread. */
    11371456    TRACE2((psh, "sh_thread_wrapper: quits - iExit=%d\n", iExit));
    1138 
     1457    sh_destroy(psh);
     1458    shthread_set_shell(NULL);
    11391459    _endthreadex(iExit);
    11401460    return iExit;
     
    11791499shpid sh_waitpid(shinstance *psh, shpid pid, int *statusp, int flags)
    11801500{
    1181     shpid   pidret;
     1501    shpid       pidret;
    11821502#if K_OS == K_OS_WINDOWS //&& defined(SH_FORKED_MODE)
    1183     DWORD   dwRet;
    1184     HANDLE  hChild = INVALID_HANDLE_VALUE;
    1185     int     i;
     1503    DWORD       dwRet;
     1504    HANDLE      hChild = INVALID_HANDLE_VALUE;
     1505    unsigned    i;
    11861506
    11871507    *statusp = 0;
     
    12041524            else if (dwRet == WAIT_TIMEOUT)
    12051525            {
    1206                 i = -1; /* don't try close anything */
     1526                i = ~0; /* don't try close anything */
    12071527                pidret = 0;
    12081528            }
     
    12221542                                       flags & WNOHANG ? 0 : INFINITE);
    12231543        i = dwRet - WAIT_OBJECT_0;
    1224         if ((unsigned)i < (unsigned)psh->num_children)
     1544        if (i < psh->num_children)
    12251545        {
    12261546            hChild = psh->children[i].hChild;
     
    12281548        else if (dwRet == WAIT_TIMEOUT)
    12291549        {
    1230             i = -1; /* don't try close anything */
     1550            i = ~0; /* don't try close anything */
    12311551            pidret = 0;
    12321552        }
    12331553        else
    12341554        {
    1235             i = -1; /* don't try close anything */
     1555            i = ~0; /* don't try close anything */
    12361556            errno = EINVAL;
    12371557        }
     
    12401560    {
    12411561        fprintf(stderr, "panic! too many children!\n");
    1242         i = -1;
     1562        i = ~0;
    12431563        *(char *)1 = '\0'; /** @todo implement this! */
    12441564    }
     
    12471567     * Close the handle, and if we succeeded collect the exit code first.
    12481568     */
    1249     if (    i >= 0
    1250         &&  i < psh->num_children)
     1569    if (i < psh->num_children)
    12511570    {
    12521571        if (hChild != INVALID_HANDLE_VALUE)
     
    12971616{
    12981617    TRACE2((psh, "sh__exit(%d)\n", rc));
    1299     (void)psh;
    13001618
    13011619#if defined(SH_FORKED_MODE)
    13021620    _exit(rc);
    1303 
    1304 #else
     1621    (void)psh;
     1622
     1623#else
     1624    psh->exitstatus = rc;
     1625
     1626    /*
     1627     * If we're a thread, jump to the sh_thread_wrapper and make a clean exit.
     1628     */
     1629    if (psh->thread)
     1630    {
     1631        if (psh->exitjmp)
     1632            longjmp(psh->exitjmp->loc, !rc ? SH_EXIT_ZERO : rc);
     1633        else
     1634        {
     1635            static char const s_msg[] = "fatal error in sh__exit: exitjmp is NULL!\n";
     1636            shfile_write(&psh->fdtab, 2, s_msg, sizeof(s_msg) - 1);
     1637            _exit(rc);
     1638        }
     1639    }
     1640
     1641    /*
     1642     * The main thread will typically have to stick around till all subshell
     1643     * threads have been stopped.  We must tear down this shell instance as
     1644     * much as possible before doing this, though, as subshells could be
     1645     * waiting for pipes and such to be closed before they're willing to exit.
     1646     */
     1647    if (g_num_shells > 1)
     1648    {
     1649        TRACE2((psh, "sh__exit: %u shells around, must wait...\n", g_num_shells));
     1650        shfile_uninit(&psh->fdtab);
     1651        sh_int_unlink(psh);
     1652    }
     1653
     1654    _exit(rc);
    13051655#endif
    13061656}
  • trunk/src/kash/shinstance.h

    r3438 r3439  
    150150    shsigset_t          sigmask;        /**< Our signal mask. */
    151151    char              **shenviron;      /**< The environment vector. */
    152     int                 num_children;   /**< Number of children in the array. */
     152    int                 linked;         /**< Set if we're still linked. */
     153    unsigned            num_children;   /**< Number of children in the array. */
    153154    shchild            *children;       /**< The child array. */
    154155#ifndef SH_FORKED_MODE
    155156    int (*thread)(struct shinstance *, void *); /**< The thread procedure. */
    156157    void               *threadarg;      /**< The thread argument. */
     158    struct jmploc      *exitjmp;        /**< Long jump target in sh_thread_wrapper for use by sh__exit. */
    157159#endif
    158160
     
    165167    char               *curdir;         /**< current working directory */
    166168    char               *prevdir;        /**< previous working directory */
    167     char               *cdcomppath;
     169    char               *cdcomppath;     /**< (stalloc) */
    168170    int                 getpwd_first;   /**< static in getpwd. (initialized to 1!) */
    169171
     
    182184    int                 exitstatus;     /**< exit status of last command */
    183185    int                 back_exitstatus;/**< exit status of backquoted command */
    184     struct strlist     *cmdenviron;     /**< environment for builtin command */
     186    struct strlist     *cmdenviron;     /**< environment for builtin command (varlist from evalcommand()) */
    185187    int                 funcnest;       /**< depth of function calls */
    186188    int                 evalskip;       /**< set if we are skipping commands */
     
    354356    char              **t_wp;
    355357    struct t_op const  *t_wp_op;
    356 
    357358};
    358359
  • trunk/src/kash/shthread.h

    r2413 r3439  
    3333{
    3434    char b[64];
     35    KU64 au64[64/sizeof(KU64)];
     36    void *aptrs[64/sizeof(void *)];
    3537} shmtx;
    3638
Note: See TracChangeset for help on using the changeset viewer.