Changeset 1489


Ignore:
Timestamp:
Sep 11, 2004, 10:49:10 AM (21 years ago)
Author:
bird
Message:

Fixed fork and improoved a bit on spawn and spm.

Location:
trunk/src/emx/src/lib/sys
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/emx/src/lib/sys/__initdll.c

    • Property cvs2svn:cvs-rev changed from 1.12 to 1.13
    r1488 r1489  
    252252
    253253/**
    254  * Fork callback which updates the thread structure in the child.
     254 * Fork callback which updates the thread structure in the child
     255 * and the global pid & parent pid values.
    255256 *
    256257 * @returns 0 on success.
     
    270271                        (*__libc_gpTLS)->cDefLoggerDepth - 2);
    271272            (*__libc_gpTLS)->cDefLoggerDepth -= 2;
     273            _sys_pid = pForkHandle->pidChild;
     274            _sys_ppid = pForkHandle->pidParent;
    272275            rc = 0;
    273276            break;
  • trunk/src/emx/src/lib/sys/__spawnve.c

    • Property cvs2svn:cvs-rev changed from 1.9 to 1.10
    r1488 r1489  
    7878        { \
    7979          errno = ENOMEM; \
    80           return -1; \
     80          LIBCLOG_RETURN_INT(-1); \
    8181        } \
    8282      arg_ptr = arg_buf + arg_size; \
     
    8787int __spawnve (struct _new_proc *np)
    8888{
    89   LIBCLOG_ENTER("np=%p:{mode=%#x}\n", (void *)np, np->mode);
    90   int   rc;
    91   ULONG exec_flag, mode;
    92   RESULTCODES res;
    93   char obj[40], *arg_ptr, *arg_buf;
    94   char *pgm_name, *base;
    95   const char *src, *s;
    96   size_t arg_size, arg_alloc, len;
    97   int i, quote, bs, method;
    98   __LIBC_PSPMPROCESS    pEmbryo;
    99   FS_VAR();
    100 
    101   arg_buf = NULL; arg_alloc = 0; arg_size = 0; arg_ptr = NULL;
    102 
    103   mode = np->mode;
    104   switch (mode & 0xff)
    105     {
    106     case P_WAIT:
    107       exec_flag = EXEC_SYNC;
    108       break;
    109     case P_NOWAIT:
    110       exec_flag = EXEC_ASYNCRESULT;
    111       break;
    112     case P_OVERLAY:
    113       exec_flag = EXEC_ASYNC;
    114       break;
    115     default:
    116       errno = EINVAL;
    117       LIBCLOG_RETURN_INT(-1);
    118     }
    119   pgm_name = alloca (strlen ((const char *)np->fname_off) + 5);
    120   strcpy (pgm_name, (const char *)np->fname_off);
    121   _defext (pgm_name, "exe");
    122   base = _getname (pgm_name);
    123   method = 0;
    124   if (stricmp (base, "cmd.exe") == 0 || stricmp (base, "4os2.exe") == 0)
    125     method = 1;
    126   src = (const char *)np->arg_off;
    127   if (np->arg_count > 0)
    128     {
    129       ++src;                    /* skip flags byte */
    130       len = strlen (src) + 1;
    131       ADD (len);
    132       memcpy (arg_ptr, src, len);
    133       arg_ptr += len; src += len;
    134     }
    135   for (i = 1; i < np->arg_count; ++i)
    136     {
    137       if (i > 1)
    138         {
    139           ADD (1);
    140           *arg_ptr++ = ' ';
    141         }
    142       ++src;                    /* skip flags byte */
    143       quote = FALSE;
    144       if (*src == 0)
    145         quote = TRUE;
    146       else if (mode & P_QUOTE)
    147         {
    148           if (src[0] == '@' && src[1] != 0)
     89    LIBCLOG_ENTER("np=%p:{mode=%#x}\n", (void *)np, np->mode);
     90    __LIBC_PSPMPROCESS    pEmbryo;
     91    ULONG                 mode;
     92    char *arg_ptr, *arg_buf;
     93    char *pgm_name, *base;
     94    const char *src, *s;
     95    size_t arg_size, arg_alloc, len;
     96    int i, quote, bs, method;
     97    FS_VAR();
     98
     99    arg_buf = NULL; arg_alloc = 0; arg_size = 0; arg_ptr = NULL;
     100
     101    /*
     102     * Validate mode.
     103     */
     104    mode = np->mode;
     105    switch (mode & 0xff)
     106    {
     107        case P_WAIT:
     108        case P_NOWAIT:
     109        case P_OVERLAY:
     110            break;
     111        default:
     112            errno = EINVAL;
     113            LIBC_ASSERTM_FAILED("invalid mode 0x%08lx\n", mode);
     114            LIBCLOG_RETURN_INT(-1);
     115    }
     116
     117    /*
     118     * Allocate space for the program name and check if it's an OS/2 shell.
     119     */
     120    pgm_name = alloca (strlen ((const char *)np->fname_off) + 5);
     121    strcpy (pgm_name, (const char *)np->fname_off);
     122    _defext (pgm_name, "exe");
     123    base = _getname (pgm_name);
     124    method = 0;
     125    if (stricmp (base, "cmd.exe") == 0 || stricmp (base, "4os2.exe") == 0)
     126        method = 1;
     127
     128    /*
     129     * Process arguments.
     130     */
     131    src = (const char *)np->arg_off;
     132    if (np->arg_count > 0)
     133    {
     134        ++src;                    /* skip flags byte */
     135        len = strlen (src) + 1;
     136        ADD (len);
     137        memcpy (arg_ptr, src, len);
     138        arg_ptr += len; src += len;
     139    }
     140    for (i = 1; i < np->arg_count; ++i)
     141    {
     142        if (i > 1)
     143        {
     144            ADD (1);
     145            *arg_ptr++ = ' ';
     146        }
     147        ++src;                    /* skip flags byte */
     148        quote = FALSE;
     149        if (*src == 0)
    149150            quote = TRUE;
    150           else
     151        else if (mode & P_QUOTE)
     152        {
     153            if (src[0] == '@' && src[1] != 0)
     154                quote = TRUE;
     155            else
     156                for (s = src; *s != 0; ++s)
     157                    if (*s == '?' || *s == '*')
     158                    {
     159                        quote = TRUE;
     160                        break;
     161                    }
     162        }
     163        if (!quote)
    151164            for (s = src; *s != 0; ++s)
    152               if (*s == '?' || *s == '*')
     165                if (*s == ' ' || *s == '\t' || (*s == '"' && method == 1))
    153166                {
    154                   quote = TRUE;
    155                   break;
     167                    quote = TRUE;
     168                    break;
    156169                }
    157         }
    158       if (!quote)
    159         for (s = src; *s != 0; ++s)
    160           if (*s == ' ' || *s == '\t' || (*s == '"' && method == 1))
     170        if (quote)
     171        {
     172            ADD (1);
     173            *arg_ptr++ = '"';
     174        }
     175        bs = 0;
     176        while (*src != 0)
     177        {
     178            if (*src == '"' && method == 0)
    161179            {
    162               quote = TRUE;
    163               break;
     180                ++bs;
     181                ADD (bs);
     182                memset (arg_ptr, '\\', bs); arg_ptr += bs;
     183                bs = 0;
    164184            }
    165       if (quote)
    166         {
    167           ADD (1);
    168           *arg_ptr++ = '"';
    169         }
    170       bs = 0;
    171       while (*src != 0)
    172         {
    173           if (*src == '"' && method == 0)
     185            else if (*src == '\\' && method == 0)
     186                ++bs;
     187            else
     188                bs = 0;
     189            ADD (1);
     190            *arg_ptr++ = *src;
     191            ++src;
     192        }
     193        if (quote)
     194        {
     195            ADD (1+bs);
     196            memset (arg_ptr, '\\', bs); arg_ptr += bs;
     197            *arg_ptr++ = '"';
     198        }
     199        ++src;
     200    }
     201    /* The arguments are an array of zero terminated strings, ending with an empty string. */
     202    ADD (2);
     203    *arg_ptr++ = '\0';
     204    *arg_ptr++ = '\0';
     205
     206
     207    /*
     208     * Now create an embryo process.
     209     */
     210    _fmutex_request(&__libc_gmtxExec, 0);
     211    pEmbryo = __libc_spmCreateEmbryo(getpid());
     212    if (pEmbryo)
     213    {
     214        /*
     215         * Do inheritance stuff.
     216         */
     217        pEmbryo->pInherit = doInherit();
     218        if (pEmbryo->pInherit)
     219        {
     220            RESULTCODES resc;
     221            char        szObj[40];
     222            int         rc;
     223
     224            /*
     225             * Create the process.
     226             */
     227            FS_SAVE_LOAD();
     228            LIBCLOG_MSG("Calling DosExecPgm pgm: %s args: %s\\0%s\\0\\0\n", pgm_name, arg_buf, arg_buf + strlen(arg_buf) + 1);
     229            rc = DosExecPgm(szObj, sizeof(szObj), EXEC_ASYNCRESULT, (PCSZ)arg_buf, (PCSZ)np->env_off, &resc, (PCSZ)pgm_name);
     230            FS_RESTORE();
     231            if (!rc)
    174232            {
    175               ++bs;
    176               ADD (bs);
    177               memset (arg_ptr, '\\', bs); arg_ptr += bs;
    178               bs = 0;
     233                __atomic_cmpxchg32((volatile uint32_t *)(void *)&pEmbryo->pid, (uint32_t)resc.codeTerminate, 0);
     234                LIBCLOG_MSG("Spawned pid=%04lx (%ld)\n", resc.codeTerminate, resc.codeTerminate);
     235
     236                /* cleanup embryo and other stuff. */
     237                __libc_spmRelease(pEmbryo);
     238                doInheritDone();
     239                if (arg_buf != NULL)
     240                    _tfree (arg_buf);
     241                _fmutex_release(&__libc_gmtxExec);
     242
     243                /*
     244                 * Exit depends on the mode.
     245                 */
     246                switch (mode & 0xff)
     247                {
     248                    /*
     249                     * Return the pid.
     250                     */
     251                    case P_NOWAIT:
     252                        LIBCLOG_RETURN_INT((int)resc.codeTerminate);
     253
     254                        /*
     255                         * Wait for the child and return the result.
     256                         */
     257                    case P_WAIT:
     258                        /*
     259                         * Wait for the child and exit this process with the same result.
     260                         */
     261                    case P_OVERLAY:
     262                    {
     263                        PID pid = resc.codeTerminate;
     264                        PID pidEnded = 0;
     265                        FS_SAVE_LOAD();
     266                        LIBCLOG_MSG("Calling DosWaitChild(,,,,0x%04lx)\n", pid);
     267                        rc = DosWaitChild(DCWA_PROCESS, DCWW_WAIT, &resc, &pidEnded, pid);
     268                        if (!rc)
     269                        {
     270                            LIBCLOG_MSG("DosWaitChild(,,,,0x%04lx) returned pidEnded=0x%04lx resc.codeTerminate=%ld resc.codeResult=%ld\n",
     271                                        pid, pidEnded, resc.codeTerminate, resc.codeResult);
     272                            LIBC_ASSERTM(pidEnded == pid, "Expected pid 0x%04lx and got 0x%04lx!\n", pid, pidEnded);
     273
     274                            if (mode == P_OVERLAY)
     275                            {
     276                                LIBCLOG_MSG("Calling DosExit(,0)\n");
     277                                while (pid == pidEnded)
     278                                    DosExit(EXIT_PROCESS, resc.codeResult);
     279                            }
     280
     281                            LIBCLOG_RETURN_INT((int)resc.codeResult);
     282                        }
     283
     284                        LIBC_ASSERTM_FAILED("Calling DosWaitChild(,,,,0x%04lx) -> rc=%d\n", pid, rc);
     285                        _sys_set_errno(rc);
     286                        LIBCLOG_RETURN_INT(-1);
     287                    }
     288
     289                        /* this can _NEVER_ happen! */
     290                    default:
     291                        errno = EINVAL;
     292                        LIBCLOG_RETURN_INT(-1);
     293                }
     294                /* won't ever get here! */
    179295            }
    180           else if (*src == '\\' && method == 0)
    181             ++bs;
    182           else
    183             bs = 0;
    184           ADD (1);
    185           *arg_ptr++ = *src;
    186           ++src;
    187         }
    188       if (quote)
    189         {
    190           ADD (1+bs);
    191           memset (arg_ptr, '\\', bs); arg_ptr += bs;
    192           *arg_ptr++ = '"';
    193         }
    194       ++src;
    195     }
    196   /* The arguments are an array of zero terminated strings, ending with an empty string. */
    197   ADD (2);
    198   *arg_ptr++ = '\0';
    199   *arg_ptr++ = '\0';
    200 
    201   _fmutex_request(&__libc_gmtxExec, 0);
    202 
    203   /*
    204    * Now create an embryo process.
    205    */
    206   pEmbryo = __libc_spmCreateEmbryo(getpid());
    207   if (pEmbryo)
    208   {
    209       /*
    210        * Do inheritance stuff.
    211        */
    212       pEmbryo->pInherit = doInherit();
    213       if (pEmbryo->pInherit)
    214       {
    215           /*
    216            * Create the process.
    217            */
    218           FS_SAVE_LOAD();
    219           rc = DosExecPgm (obj, sizeof (obj), exec_flag, (PCSZ)arg_buf, (PCSZ)np->env_off, &res, (PCSZ)pgm_name);
    220           FS_RESTORE();
    221           if (!rc)
    222           {
    223               if (exec_flag == EXEC_ASYNCRESULT || exec_flag == EXEC_ASYNC)
    224               {
    225                   __atomic_cmpxchg32((volatile uint32_t *)(void *)&pEmbryo->pid, (uint32_t)res.codeTerminate, 0);
    226                   LIBCLOG_MSG("Spawned pid=%04lx (%ld)\n", res.codeTerminate, res.codeTerminate);
    227               }
    228 
    229               /* cleanup embryo and other stuff. */
    230               __libc_spmRelease(pEmbryo);
    231               doInheritDone();
    232               if (arg_buf != NULL)
    233                   _tfree (arg_buf);
    234               _fmutex_release(&__libc_gmtxExec);
    235 
    236               /* exit depends on the mode. */
    237               switch (mode & 0xff)
    238                 {
    239                 case P_WAIT:
    240                   LIBCLOG_RETURN_INT((int)res.codeResult);
    241                 case P_NOWAIT:
    242                   LIBCLOG_RETURN_INT((int)res.codeTerminate);
    243                 case P_OVERLAY:
    244                   FS_SAVE_LOAD();
    245                 #if 1 /* hack... */
    246                 {
    247                   PID pid = res.codeTerminate;
    248                   for (;;)
    249                   {
    250                       PID   pidEnded = 0;
    251                       LIBCLOG_MSG("Calling DosWaitChild(,,,,0x%04lx)\n", pid);
    252                       rc = DosWaitChild(DCWA_PROCESS, DCWW_WAIT, &res, &pidEnded, pid);
    253                       if (rc)
    254                       {
    255                           LIBCLOG_MSG("Calling DosWaitChild(,,,,0x%04lx) -> rc=%d\n", pid, rc);
    256                           break;
    257                       }
    258                       LIBCLOG_MSG("Calling DosWaitChild(,,,,0x%04lx) pidEnded=0x%04lx res.codeTerminate=%ld res.codeResult=%ld\n",
    259                                   pid, pidEnded, res.codeTerminate, res.codeResult);
    260                       while (pid == pidEnded)
    261                           DosExit(EXIT_PROCESS, res.codeResult);
    262                   }
    263                 }
    264                 #endif
    265                   LIBCLOG_MSG("Calling DosExit(,0)\n");
    266                   while (1)
    267                     DosExit (EXIT_PROCESS, 0);
    268                 default:
    269                   errno = EINVAL;
    270                   LIBCLOG_RETURN_INT(-1);
    271                 }
    272               /* won't ever get here! */
    273           }
    274           else
    275             _sys_set_errno (rc);
    276           doInheritDone();
    277       }
    278       /* cleanup embryo */
    279       __libc_spmRelease(pEmbryo);
    280   }
    281 
    282   if (arg_buf != NULL)
    283     _tfree (arg_buf);
    284   _fmutex_release(&__libc_gmtxExec);
    285   LIBCLOG_RETURN_INT(-1);
     296            else
     297                _sys_set_errno (rc);
     298            doInheritDone();
     299        }
     300        /* cleanup embryo */
     301        __libc_spmRelease(pEmbryo);
     302    }
     303
     304    if (arg_buf != NULL)
     305        _tfree (arg_buf);
     306    _fmutex_release(&__libc_gmtxExec);
     307    LIBCLOG_RETURN_INT(-1);
    286308}
  • trunk/src/emx/src/lib/sys/libcfork.c

    • Property cvs2svn:cvs-rev changed from 1.2 to 1.3
    r1488 r1489  
    187187        static char szMsg[] = "LIBC Error: Couldn't register process in shared memory!\r\n";
    188188        ULONG       ul;
    189         LIBC_ASSERTM_FAILED("couldn't find self process!\n");
     189        LIBC_ASSERTM_FAILED("couldn't register process!\n");
    190190
    191191        DosWrite(2, szMsg, sizeof(szMsg), &ul);
     
    212212        pProcess->pvModuleHead = pModule;
    213213    pProcess->ppvModuleTail = (void **)&pModule->pNext;
     214
     215
     216#if 0
     217    /*
     218     * Debug checks.
     219     */
     220    static char sz[] = "forking\0forking\0";
     221    PPIB pPib;
     222    PTIB pTib;
     223    DosGetInfoBlocks(&pTib, &pPib);
     224    if (!memcmp(pPib->pib_pchcmd, sz, sizeof(sz)))
     225    {
     226        LIBC_ASSERTM(pProcess->pvForkHandle, "fork arguments, no fork handle!!! process %p\n", pProcess);
     227        if (!pProcess->pvForkHandle)
     228            __libc_SpmCheck(0, 1);
     229    }
     230    else
     231    {
     232        LIBC_ASSERTM(!pProcess->pvForkHandle, "no fork arguments, fork handle!!! process %p handle %p\n", pProcess, pProcess->pvForkHandle);
     233        if (pProcess->pvForkHandle)
     234            __libc_SpmCheck(0, 1);
     235    }
     236#endif
    214237
    215238    /*
     
    745768        char        szErr[64];
    746769        RESULTCODES rsc = {0,0};
     770        #if 1
    747771        rc = DosExecPgm(szErr, sizeof(szErr), EXEC_ASYNCRESULT, (PCSZ)pPib->pib_pchcmd, NULL, &rsc, (PCSZ)&szPgm[0]);
     772        #else /* debugging checks */
     773        rc = DosExecPgm(szErr, sizeof(szErr), EXEC_ASYNCRESULT, (PCSZ)"forking\0forking\0", NULL, &rsc, (PCSZ)&szPgm[0]);
     774        #endif
    748775        if (!rc)
    749776        {
Note: See TracChangeset for help on using the changeset viewer.