Back to index

lightning-sunbird  0.9+nobinonly
Functions
os2misc.c File Reference
#include <string.h>
#include "primpl.h"
#include <sys/timeb.h>

Go to the source code of this file.

Functions

int _CRT_init (void)
void _CRT_term (void)
void __ctordtorInit (int flag)
void __ctordtorTerm (int flag)
char * _PR_MD_GET_ENV (const char *name)
PRIntn _PR_MD_PUT_ENV (const char *name)
 PR_Now (void)
static int assembleCmdLine (char *const *argv, char **cmdLine)
static int assembleEnvBlock (char **envp, char **envBlock)
static int compare (const void *arg1, const void *arg2)
PRProcess_PR_CreateOS2Process (const char *path, char *const *argv, char *const *envp, const PRProcessAttr *attr)
PRStatus _PR_DetachOS2Process (PRProcess *process)
PRStatus _PR_WaitOS2Process (PRProcess *process, PRInt32 *exitCode)
PRStatus _PR_KillOS2Process (PRProcess *process)
PRStatus _MD_OS2GetHostName (char *name, PRUint32 namelen)
void _PR_MD_WAKEUP_CPUS (void)
PRStatus _MD_CreateFileMap (PRFileMap *fmap, PRInt64 size)
PRInt32 _MD_GetMemMapAlignment (void)
void_MD_MemMap (PRFileMap *fmap, PROffset64 offset, PRUint32 len)
PRStatus _MD_MemUnmap (void *addr, PRUint32 len)
PRStatus _MD_CloseFileMap (PRFileMap *fmap)

Function Documentation

void __ctordtorInit ( int  flag)
void __ctordtorTerm ( int  flag)

Definition at line 561 of file os2misc.c.

{
    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
    return PR_FAILURE;
}
PRStatus _MD_CreateFileMap ( PRFileMap fmap,
PRInt64  size 
)

Definition at line 534 of file os2misc.c.

{
    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
    return PR_FAILURE;
}

Definition at line 540 of file os2misc.c.

{
    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
    return -1;
}
void* _MD_MemMap ( PRFileMap fmap,
PROffset64  offset,
PRUint32  len 
)

Definition at line 546 of file os2misc.c.

{
    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
    return NULL;
}
PRStatus _MD_MemUnmap ( void addr,
PRUint32  len 
)

Definition at line 555 of file os2misc.c.

{
    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
    return PR_FAILURE;
}
PRStatus _MD_OS2GetHostName ( char *  name,
PRUint32  namelen 
)

Definition at line 507 of file os2misc.c.

{
    PRIntn rv;

    rv = gethostname(name, (PRInt32) namelen);
    if (0 == rv) {
        return PR_SUCCESS;
    }
       _PR_MD_MAP_GETHOSTNAME_ERROR(sock_errno());
    return PR_FAILURE;
}

Here is the call graph for this function:

PRProcess* _PR_CreateOS2Process ( const char *  path,
char *const argv,
char *const envp,
const PRProcessAttr attr 
)

Definition at line 237 of file os2misc.c.

{
    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;

    /*
     * Variables for DosExecPgm
     */
    char szFailed[CCHMAXPATH];
    char *pszCmdLine = NULL;
    RESULTCODES procInfo;
    HFILE hStdIn  = 0,
          hStdOut = 0,
          hStdErr = 0;
    HFILE hStdInSave  = -1,
          hStdOutSave = -1,
          hStdErrSave = -1;

    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;
    }
  
    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;
 
    if (attr) {
        /* On OS/2, there is really no way to pass file handles for stdin,
         * stdout, and stderr to a new process.  Instead, we can make it
         * a child process and make the given file handles a copy of our
         * stdin, stdout, and stderr.  The child process then inherits
         * ours, and we set ours back.  Twisted and gross I know. If you
         * know a better way, please use it.
         */
        if (attr->stdinFd) {
            hStdIn = 0;
            DosDupHandle(hStdIn, &hStdInSave);
            DosDupHandle((HFILE) attr->stdinFd->secret->md.osfd, &hStdIn);
        }

        if (attr->stdoutFd) {
            hStdOut = 1;
            DosDupHandle(hStdOut, &hStdOutSave);
            DosDupHandle((HFILE) attr->stdoutFd->secret->md.osfd, &hStdOut);
        }

        if (attr->stderrFd) {
            hStdErr = 2;
            DosDupHandle(hStdErr, &hStdErrSave);
            DosDupHandle((HFILE) attr->stderrFd->secret->md.osfd, &hStdErr);
        }
        /*
         * Build up the Command Line for DosExecPgm
         */
        pszCmdLine = PR_MALLOC(strlen(pszEXEName) +
                               strlen(startData.PgmInputs) + 3);
        sprintf(pszCmdLine, "%s%c%s%c", pszEXEName, '\0',
                startData.PgmInputs, '\0');
        rc = DosExecPgm(szFailed,
                        CCHMAXPATH,
                        EXEC_ASYNCRESULT,
                        pszCmdLine,
                        envBlock,
                        &procInfo,
                        pszEXEName);
        PR_DELETE(pszCmdLine);

        /* Restore our old values.  Hope this works */
        if (hStdInSave != -1) {
            DosDupHandle(hStdInSave, &hStdIn);
            DosClose(hStdInSave);
        }

        if (hStdOutSave != -1) {
            DosDupHandle(hStdOutSave, &hStdOut);
            DosClose(hStdOutSave);
        }

        if (hStdErrSave != -1) {
            DosDupHandle(hStdErrSave, &hStdErr);
            DosClose(hStdErrSave);
        }

        if (rc != NO_ERROR) {
            /* XXX what error code? */
            PR_SetError(PR_UNKNOWN_ERROR, rc);
            goto errorExit;
        }

        proc->md.pid = procInfo.codeTerminate;
    } else {  
        /*
         * If no STDIN/STDOUT redirection is not needed, use DosStartSession
         * to create a new, independent session
         */
        rc = DosStartSession(&startData, &ulAppType, &pid);

        if ((rc != NO_ERROR) && (rc != ERROR_SMG_START_IN_BACKGROUND)) {
            PR_SetError(PR_UNKNOWN_ERROR, rc);
            goto errorExit;
        }
 
        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 */

Here is the call graph for this function:

Definition at line 465 of file os2misc.c.

{
    /* On OS/2, a process is either created as a child or not. 
     * You can't 'detach' it later on.
     */
    PR_DELETE(process);
    return PR_SUCCESS;
}

Definition at line 497 of file os2misc.c.

{
   ULONG ulRetVal;
    if ((ulRetVal = DosKillProcess(DKP_PROCESS, process->md.pid)) == NO_ERROR) {
       return PR_SUCCESS;
    }
    PR_SetError(PR_UNKNOWN_ERROR, ulRetVal);
    return PR_FAILURE;
}
char* _PR_MD_GET_ENV ( const char *  name)

Definition at line 52 of file os2misc.c.

{
    return getenv(name);
}
PRIntn _PR_MD_PUT_ENV ( const char *  name)

Definition at line 58 of file os2misc.c.

{
    return putenv(name);
}

Definition at line 520 of file os2misc.c.

{
    return;
}    
PRStatus _PR_WaitOS2Process ( PRProcess process,
PRInt32 exitCode 
)

Definition at line 477 of file os2misc.c.

{
    ULONG ulRetVal;
    RESULTCODES results;
    PID pidEnded = 0;

    ulRetVal = DosWaitChild(DCWA_PROCESS, DCWW_WAIT, 
                            &results,
                            &pidEnded, process->md.pid);

    if (ulRetVal != NO_ERROR) {
       printf("\nDosWaitChild rc = %lu\n", ulRetVal);
        PR_SetError(PR_UNKNOWN_ERROR, ulRetVal);
        return PR_FAILURE;
    }
    PR_DELETE(process);
    return PR_SUCCESS;
}
static int assembleCmdLine ( char *const argv,
char **  cmdLine 
) [static]

Definition at line 122 of file os2misc.c.

{
    char *const *arg;
    int cmdLineSize;

    /*
     * Find out how large the command line buffer should be.
     */
    cmdLineSize = 1; /* final null */
    for (arg = argv+1; *arg; arg++) {
        cmdLineSize += strlen(*arg) + 1; /* space in between */
    }
    *cmdLine = PR_MALLOC(cmdLineSize);
    if (*cmdLine == NULL) {
        return -1;
    }

    (*cmdLine)[0] = '\0';

    for (arg = argv+1; *arg; arg++) {
        if (arg > argv +1) {
            strcat(*cmdLine, " ");
        }
        strcat(*cmdLine, *arg);
    } 
    return 0;
}

Here is the caller graph for this function:

static int assembleEnvBlock ( char **  envp,
char **  envBlock 
) [static]

Definition at line 159 of file os2misc.c.

{
    char *p;
    char *q;
    char **env;
    char *curEnv;
    char *cwdStart, *cwdEnd;
    int envBlockSize;

    PPIB ppib = NULL;
    PTIB ptib = NULL;

    if (envp == NULL) {
        *envBlock = NULL;
        return 0;
    }

    if(DosGetInfoBlocks(&ptib, &ppib) != NO_ERROR)
       return -1;

    curEnv = ppib->pib_pchenv;

    cwdStart = curEnv;
    while (*cwdStart) {
        if (cwdStart[0] == '=' && cwdStart[1] != '\0'
                && cwdStart[2] == ':' && cwdStart[3] == '=') {
            break;
        }
        cwdStart += strlen(cwdStart) + 1;
    }
    cwdEnd = cwdStart;
    if (*cwdEnd) {
        cwdEnd += strlen(cwdEnd) + 1;
        while (*cwdEnd) {
            if (cwdEnd[0] != '=' || cwdEnd[1] == '\0'
                    || cwdEnd[2] != ':' || cwdEnd[3] != '=') {
                break;
            }
            cwdEnd += strlen(cwdEnd) + 1;
        }
    }
    envBlockSize = cwdEnd - cwdStart;

    for (env = envp; *env; env++) {
        envBlockSize += strlen(*env) + 1;
    }
    envBlockSize++;

    p = *envBlock = PR_MALLOC(envBlockSize);
    if (p == NULL) {
        return -1;
    }

    q = cwdStart;
    while (q < cwdEnd) {
        *p++ = *q++;
    }

    for (env = envp; *env; env++) {
        q = *env;
        while (*q) {
            *p++ = *q++;
        }
        *p++ = '\0';
    }
    *p = '\0';
    return 0;
}

Here is the caller graph for this function:

static int compare ( const void arg1,
const void arg2 
) [static]

Definition at line 232 of file os2misc.c.

{
    return stricmp(* (char**)arg1, * (char**)arg2);
}

Here is the caller graph for this function:

PR_Now ( void  )

Definition at line 90 of file os2misc.c.

{
    PRInt64 s, ms, ms2us, s2us;
    struct timeb b;

    ftime(&b);
    LL_I2L(ms2us, PR_USEC_PER_MSEC);
    LL_I2L(s2us, PR_USEC_PER_SEC);
    LL_I2L(s, b.time);
    LL_I2L(ms, b.millitm);
    LL_MUL(ms, ms, ms2us);
    LL_MUL(s, s, s2us);
    LL_ADD(s, s, ms);
    return s;       
}

Here is the call graph for this function: