Changeset 217 for trunk/src


Ignore:
Timestamp:
Oct 9, 2009, 11:24:19 PM (16 years ago)
Author:
Dmitry A. Kuminov
Message:

corelib: QProcess: Implemented workarounds for starting applications of different types (#72) and for startDetached() (#71).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/corelib/io/qprocess_os2.cpp

    r216 r217  
    107107QT_BEGIN_NAMESPACE
    108108
     109extern QString qAppFileName();
     110
    109111enum
    110112{
     
    744746                           const QStringList *environment, bool detached = false)
    745747{
    746     // @todo P_DETACH isn't supported by kLIBC atm, do something else
    747748    int mode = detached ? P_DETACH : P_NOWAIT;
    748749
    749     // Create argument list with right number of elements, and set the final
    750     // one to 0.
    751     char **argv = new char *[arguments.count() + 2];
     750    // Create argument list with right number of elements (one extra is for
     751    // the program name and one for the terminating 0). We also reserve 3
     752    // elements in front of the array for a posssible command processor call
     753    // insertion.
     754    char **argvBase = new char *[arguments.count() + 2 + 3];
     755
     756    // Don't use leading elements by default
     757    char **argv = argvBase + 3;
     758    // Set the final argument to 0
    752759    argv[arguments.count() + 1] = 0;
    753760
     
    902909        }
    903910
     911        char *programReal = fullProgramName.data();
     912        char **argvReal = argv;
     913
     914        if (mode == P_DETACH) {
     915            // @todo P_DETACH isn't supported by kLIBC atm, prepend the program
     916            // to start with "cmd.exe /c detach" as a temporary solution
     917            mode = P_NOWAIT;
     918            programReal = getenv("COMSPEC"); // returns static!
     919            if (programReal == 0)
     920                programReal = "cmd.exe";
     921            argvReal = argvBase;
     922            argvReal[0] = programReal;
     923            argvReal[1] = "/c";
     924            argvReal[2] = "detach";
     925            argv[0] = fullProgramName.data();
     926        } else {
     927            // get the application type of our program (note that we cannot use
     928            // DosGetInfoBlocks/PIB because it could be overwritten there by e.g.
     929            // morphing from VIO to PM which doesn't cancel the fact that we
     930            // are VIO from the OS/2 loader's POV.
     931            ULONG flags;
     932            arc = DosQueryAppType(QFile::encodeName(qAppFileName()), &flags);
     933            if (arc == NO_ERROR && (flags & 0x7) != FAPPTYP_WINDOWAPI) {
     934                // we are originally not the PM application and thus DosExecPgm()
     935                // won't be able to start PM applications directly (note that the
     936                // other way around it works athough undocumented). Check what
     937                // the target program is.
     938                arc = DosQueryAppType(fullProgramName, &flags);
     939                if (arc == NO_ERROR && (flags & 0x7) == FAPPTYP_WINDOWAPI) {
     940                    // its PM, we need a proxy
     941                    // @todo use P_SESSION once it's implemented in kLIBC!
     942                    // @todo check if FS VIO apps need a proxy
     943                    programReal = getenv("COMSPEC"); // returns static!
     944                    if (programReal == 0)
     945                        programReal = "cmd.exe";
     946                    argvReal = argvBase + 1;
     947                    argvReal[0] = programReal;
     948                    argvReal[1] = "/c";
     949                    argv[0] = fullProgramName.data();
     950                }
     951            }
     952        }
     953
     954#if defined(QPROCESS_DEBUG)
     955        qDebug("qt_startProcess: executable \"%s\"",
     956               qPrintable(QFile::decodeName(programReal)));
     957        for (int i = 0; argvReal[i]; ++i) {
     958            qDebug("qt_startProcess:  arg[%d] \"%s\"",
     959                   i, qPrintable(QFile::decodeName(argvReal[i])));
     960        }
     961#endif
     962
    904963        // finally, start the thing
    905         pid = spawnve(mode, fullProgramName, argv, envv);
     964        pid = spawnve(mode, programReal, argvReal, envv);
     965
     966#if defined(QPROCESS_DEBUG)
     967        qDebug("qt_startProcess: pid %d", pid);
     968#endif
    906969
    907970        if (prependedLibPath) {
     
    914977    for (int i = 1 /* 0 is programName */; i <= arguments.count(); ++i)
    915978        delete [] argv[i];
    916     delete [] argv;
     979    delete [] argvBase;
    917980    if (envv != environ) {
    918981        for (int i = 0; i < envc; ++i)
Note: See TracChangeset for help on using the changeset viewer.