Ignore:
Timestamp:
Mar 1, 2009, 8:25:29 AM (16 years ago)
Author:
bird
Message:

kash: new execve implementation for windows. more file ops.

File:
1 edited

Legend:

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

    r2302 r2303  
    10551055int sh_execve(shinstance *psh, const char *exe, const char * const *argv, const char * const *envp)
    10561056{
    1057 #ifdef _MSC_VER
    1058     intptr_t rc;
    1059 #else
    10601057    int rc;
    1061 #endif
    10621058
    10631059#ifdef DEBUG
     
    10711067        envp = sh_environ(psh);
    10721068
    1073 #if defined(SH_FORKED_MODE)
     1069#if defined(SH_FORKED_MODE) && K_OS != K_OS_WINDOWS
     1070# ifdef _MSC_VER
    10741071    errno = 0;
    1075 # ifdef _MSC_VER
    1076     errno = 0;
    1077     rc = _spawnve(_P_WAIT, exe, (char **)argv, (char **)envp);
    1078     if (rc != -1)
    1079     {
    1080         TRACE2((psh, "sh_execve: child exited, rc=%d. (errno=%d)\n", rc, errno));
    1081         exit((int)rc);
    1082     }
     1072    {
     1073        intptr_t rc2 = _spawnve(_P_WAIT, exe, (char **)argv, (char **)envp);
     1074        if (rc2 != -1)
     1075        {
     1076            TRACE2((psh, "sh_execve: child exited, rc=%d. (errno=%d)\n", rc, errno));
     1077            rc = (int)rc2;
     1078            if (!rc && rc2)
     1079                rc = 16;
     1080            exit(rc);
     1081        }
     1082    }
     1083    rc = -1;
    10831084# else
    10841085    rc = execve(exe, (char **)argv, (char **)envp);
     
    10861087
    10871088#else
     1089# if K_OS == K_OS_WINDOWS
     1090    {
     1091        /*
     1092         * This ain't quite straight forward on Windows...
     1093         */
     1094        PROCESS_INFORMATION ProcInfo;
     1095        STARTUPINFO StrtInfo;
     1096        intptr_t hndls[3];
     1097        char *cwd = shfile_getcwd(&psh->fdtab, NULL, 0);
     1098        char *cmdline;
     1099        size_t cmdline_size;
     1100        char *envblock;
     1101        size_t env_size;
     1102        char *p;
     1103        int i;
     1104
     1105        /* Create the environment block. */
     1106        if (!envp)
     1107            envp = sh_environ(psh);
     1108        env_size = 2;
     1109        for (i = 0; envp[i]; i++)
     1110            env_size += strlen(envp[i]) + 1;
     1111        envblock = p = sh_malloc(psh, env_size);
     1112        for (i = 0; envp[i]; i++)
     1113        {
     1114            size_t len = strlen(envp[i]) + 1;
     1115            memcpy(p, envp[i], len);
     1116            p += len;
     1117        }
     1118        *p = '\0';
     1119
     1120        /* Create the command line. */
     1121        cmdline_size = 2;
     1122        for (i = 0; argv[i]; i++)
     1123            cmdline_size += strlen(argv[i]) + 3;
     1124        cmdline = p = sh_malloc(psh, env_size);
     1125        for (i = 0; argv[i]; i++)
     1126        {
     1127            size_t len = strlen(argv[i]);
     1128            int quoted = !!strpbrk(argv[i], " \t"); /** @todo Do this quoting business right. */
     1129            if (i != 0)
     1130                *(p++) = ' ';
     1131            if (quoted)
     1132                *(p++) = '"';
     1133            memcpy(p, argv[i], len);
     1134            p += len;
     1135            if (quoted)
     1136                *(p++) = '"';
     1137        }
     1138        p[0] = p[1] = '\0';
     1139
     1140        /* Init the info structure */
     1141        memset(&StrtInfo, '\0', sizeof(StrtInfo));
     1142        StrtInfo.cb = sizeof(StrtInfo);
     1143
     1144        /* File handles. */
     1145        StrtInfo.lpReserved2 = shfile_exec_win(&psh->fdtab, 1 /* prepare */, &StrtInfo.cbReserved2, hndls);
     1146        StrtInfo.hStdInput  = (HANDLE)hndls[0];
     1147        StrtInfo.hStdOutput = (HANDLE)hndls[1];
     1148        StrtInfo.hStdError  = (HANDLE)hndls[2];
     1149
     1150        /* Get going... */
     1151        if (CreateProcess(exe,
     1152                          cmdline,
     1153                          NULL,         /* pProcessAttributes */
     1154                          NULL,         /* pThreadAttributes */
     1155                          TRUE,         /* bInheritHandles */
     1156                          0,            /* dwCreationFlags */
     1157                          envblock,
     1158                          cwd,
     1159                          &StrtInfo,
     1160                          &ProcInfo))
     1161        {
     1162            DWORD dwErr;
     1163            DWORD dwExitCode;
     1164
     1165            CloseHandle(ProcInfo.hThread);
     1166            dwErr = WaitForSingleObject(ProcInfo.hProcess, INFINITE);
     1167            assert(dwErr == WAIT_OBJECT_0);
     1168
     1169            if (GetExitCodeProcess(ProcInfo.hProcess, &dwExitCode))
     1170            {
     1171                CloseHandle(ProcInfo.hProcess);
     1172                _exit(dwExitCode);
     1173            }
     1174            errno = EINVAL;
     1175        }
     1176
     1177        shfile_exec_win(&psh->fdtab, 0 /* done */, NULL, NULL);
     1178    }
     1179    rc = -1;
     1180
     1181# else
     1182    errno = ENOSYS;
     1183    rc = -1;
     1184# endif
    10881185#endif
    10891186
Note: See TracChangeset for help on using the changeset viewer.