Changeset 213 for trunk/src


Ignore:
Timestamp:
Oct 7, 2009, 7:12:31 PM (16 years ago)
Author:
Dmitry A. Kuminov
Message:

corelib: QProcess: Search for executable ourselves before passing it to spawnvpe(). This in particular ensures that the current working directory is always searched first before anything in PATH (to match the expected and also CMD.EXE behavior).

File:
1 edited

Legend:

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

    r212 r213  
    753753
    754754    // Encode the program name.
    755     QByteArray encodedProgramName = QFile::encodeName(program);
     755    QByteArray rogramName = QFile::encodeName(program);
    756756
    757757    // Add the program name to the argument list.
    758     argv[0] = encodedProgramName.data();
     758    argv[0] = rogramName.data();
    759759
    760760    // Add every argument to the list
     
    807807    }
    808808
    809     // start the program
    810 #ifdef QPROCESS_DEBUG
    811     qDebug("Trying spawnvpe(%d, \"%s\")",
    812            mode, encodedProgramName.constData());
    813 #endif
    814     int pid = spawnvpe(mode, encodedProgramName, argv, envv);
    815 
    816     // if spawnvpe() couldn't find the executable, try .CMD and .BAT
    817     // extensions (in order of CMD.EXE precedence); spawnvpe() knows how to
    818     // locate and run them (i.e. using CMD.EXE /c)
    819     if (pid == -1 && errno == ENOENT) {
    820         encodedProgramName += ".cmd";
    821         argv[0] = encodedProgramName.data();
    822 #ifdef QPROCESS_DEBUG
    823             qDebug("Trying spawnvpe(%d, \"%s\")",
    824                    mode, encodedProgramName.constData());
    825 #endif
    826         pid = spawnvpe(mode, encodedProgramName, argv, envv);
    827         if ( pid == -1 && errno == ENOENT ) {
    828             qstrcpy(encodedProgramName.data() + encodedProgramName.length() - 4, ".bat");
    829             argv[0] = encodedProgramName.data();
    830 #ifdef QPROCESS_DEBUG
    831             qDebug("Trying spawnvpe(%d, \"%s\")",
    832                    mode, encodedProgramName.constData());
    833 #endif
    834             pid = spawnvpe(mode, encodedProgramName, argv, envv);
    835         }
     809#if defined(QPROCESS_DEBUG)
     810    qDebug("qt_startProcess: workdir is \"%s\"", qPrintable(QDir::currentPath()));
     811#endif
     812
     813    // try to find the executable
     814    QByteArray fullProgramName;
     815
     816    // don't go further if we got an empty program name: a file with such a name
     817    // cannot exist on OS/2 and many QFileInfo funcs are undefined for this case
     818    if (!programName.isEmpty()) {
     819        APIRET arc;
     820        char pathBuf[CCHMAXPATH];
     821        QFileInfo programInfo(program);
     822        QStringList knownExts;
     823        knownExts << "exe" << "cmd" << "bat"; // in order of CMD.EXE's precedence
     824        QByteArray path = QFile::encodeName(programInfo.path());
     825        // run through all known exe extensions (+ no extension case)
     826        for (int i = 0; i <= knownExts.size(); ++i) {
     827            QByteArray name;
     828            if (i == 0) {
     829                // no extension case, only if a known extension is already there
     830                if (knownExts.contains(programInfo.suffix(), Qt::CaseInsensitive))
     831                    name = programName;
     832                else
     833                    continue;
     834            } else {
     835                name = QFile::encodeName(program + QLatin1String(".") + knownExts[i-1]);
     836            }
     837            if (!path.isEmpty()) {
     838                arc = DosSearchPath(0, path, name, pathBuf, sizeof(pathBuf));
     839            } else {
     840                arc = DosSearchPath(SEARCH_IGNORENETERRS | SEARCH_ENVIRONMENT |
     841                                    SEARCH_CUR_DIRECTORY, "PATH",
     842                                    name, pathBuf, sizeof(pathBuf));
     843            }
     844
     845            if (arc == NO_ERROR) {
     846                fullProgramName = pathBuf;
     847                break;
     848            }
     849            if (arc != ERROR_FILE_NOT_FOUND && arc != ERROR_PATH_NOT_FOUND) {
     850                qWarning("qt_startProcess: DosSearchPath(%s) returned %lu",
     851                         qPrintable(QFile::decodeName(name)), arc);
     852                break;
     853            }
     854        }
     855    }
     856
     857#if defined(QPROCESS_DEBUG)
     858    qDebug("qt_startProcess: found \"%s\" for \"%s\"",
     859           qPrintable(QFile::decodeName(fullProgramName)),
     860           qPrintable(QFile::decodeName(programName)));
     861#endif
     862
     863    int pid = -1;
     864    if (fullProgramName.isEmpty()) {
     865        // return "No such file or directory"
     866        errno = ENOENT;
     867    } else {
     868        pid = spawnvpe(mode, fullProgramName, argv, envv);
    836869    }
    837870
    838871    // Clean up duplicated memory.
    839     for (int i = 1 /* 0 is encodedProgramName */; i <= arguments.count(); ++i)
     872    for (int i = 1 /* 0 is rogramName */; i <= arguments.count(); ++i)
    840873        delete [] argv[i];
    841874    delete [] argv;
     
    857890
    858891#if defined (QPROCESS_DEBUG)
    859     qDebug("QProcessPrivate::startProcess()");
     892    qDebug("QProcessPrivate::startProcess");
    860893#endif
    861894
Note: See TracChangeset for help on using the changeset viewer.