if (attr) { PR_ASSERT(!"Not implemented"); }
PRProcess * _PR_CreateOS2Process(    const char *path,    char *const *argv,    char *const *envp,    const PRProcessAttr *attr){    PRProcess *proc = NULL;    char *cmdLine = NULL;    char **newEnvp = NULL;    char *envBlock = NULL;       STARTDATA startData = {0};    APIRET    rc;    ULONG     ulAppType = 0;    PID       pid = 0;    char     *pEnvWPS = NULL;    char     *pszComSpec;    char      pszEXEName[CCHMAXPATH] = "";    char      pszFormatString[CCHMAXPATH];    char      pszObjectBuffer[CCHMAXPATH];    char     *pszFormatResult = NULL;    proc = PR_NEW(PRProcess);    if (!proc) {        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);        goto errorExit;    }       if (assembleCmdLine(argv, &cmdLine) == -1) {        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);        goto errorExit;    }       if (envp == NULL) {        newEnvp = NULL;    } else {        int i;        int numEnv = 0;        while (envp[numEnv]) {            numEnv++;        }        newEnvp = (char **) PR_MALLOC((numEnv+1) * sizeof(char *));        for (i = 0; i <= numEnv; i++) {            newEnvp[i] = envp[i];        }        qsort((void *) newEnvp, (size_t) numEnv, sizeof(char *), compare);    }    if (assembleEnvBlock(newEnvp, &envBlock) == -1) {        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);        goto errorExit;    }      if (attr) {       PR_ASSERT(!"Not implemented");    }    rc = DosQueryAppType(path, &ulAppType);    if (rc != NO_ERROR) {       char *pszDot = strrchr(path, '.');       if (pszDot) {          /* If it is a CMD file, launch the users command processor */          if (!stricmp(pszDot, ".cmd")) {             rc = DosScanEnv("COMSPEC", &pszComSpec);             if (!rc) {                strcpy(pszFormatString, "/C %s %s");                strcpy(pszEXEName, pszComSpec);                ulAppType = FAPPTYP_WINDOWCOMPAT;             }          }       }    }    if (ulAppType == 0) {       PR_SetError(PR_UNKNOWN_ERROR, 0);       goto errorExit;    }     if ((ulAppType & FAPPTYP_WINDOWAPI) == FAPPTYP_WINDOWAPI) {        startData.SessionType = SSF_TYPE_PM;    }    else if (ulAppType & FAPPTYP_WINDOWCOMPAT) {        startData.SessionType = SSF_TYPE_WINDOWABLEVIO;    }    else {        startData.SessionType = SSF_TYPE_DEFAULT;    }     if (ulAppType & (FAPPTYP_WINDOWSPROT31 | FAPPTYP_WINDOWSPROT | FAPPTYP_WINDOWSREAL))    {        strcpy(pszEXEName, "WINOS2.COM");        startData.SessionType = PROG_31_STDSEAMLESSVDM;        strcpy(pszFormatString, "/3 %s %s");    }     startData.InheritOpt = SSF_INHERTOPT_SHELL;     if (pszEXEName[0]) {        pszFormatResult = PR_MALLOC(strlen(pszFormatString)+strlen(path)+strlen(cmdLine));        sprintf(pszFormatResult, pszFormatString, path, cmdLine);        startData.PgmInputs = pszFormatResult;    } else {        strcpy(pszEXEName, path);        startData.PgmInputs = cmdLine;    }    startData.PgmName = pszEXEName;     startData.Length = sizeof(startData);    startData.Related = SSF_RELATED_INDEPENDENT;    startData.ObjectBuffer = pszObjectBuffer;    startData.ObjectBuffLen = CCHMAXPATH;    startData.Environment = envBlock;     rc = DosStartSession(&startData, &ulAppType, &pid);    if ((rc != NO_ERROR) && (rc != ERROR_SMG_START_IN_BACKGROUND)) {        PR_SetError(PR_UNKNOWN_ERROR, 0);    }     proc->md.pid = pid;    if (pszFormatResult) {        PR_DELETE(pszFormatResult);    }     PR_DELETE(cmdLine);    if (newEnvp) {        PR_DELETE(newEnvp);    }    if (envBlock) {        PR_DELETE(envBlock);    }    return proc;errorExit:    if (cmdLine) {        PR_DELETE(cmdLine);    }    if (newEnvp) {        PR_DELETE(newEnvp);    }    if (envBlock) {        PR_DELETE(envBlock);    }    if (proc) {        PR_DELETE(proc);    }    return NULL;}  /* _PR_CreateOS2Process */