Changeset 73


Ignore:
Timestamp:
Jul 9, 2009, 2:16:47 PM (16 years ago)
Author:
Dmitry A. Kuminov
Message:

corelib: OS/2: Implemented QProcess::startDetached().

File:
1 edited

Legend:

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

    r72 r73  
    243243}
    244244
    245 void QProcessPrivate::startProcess()
    246 {
    247     Q_Q(QProcess);
    248 
    249 #if defined (QPROCESS_DEBUG)
    250     qDebug("QProcessPrivate::startProcess()");
    251 #endif
    252 
    253     // Initialize pipes
    254     if (!createChannel(stdinChannel) ||
    255         !createChannel(stdoutChannel) ||
    256         !createChannel(stderrChannel))
    257         return;
    258 
    259     // Start the process (platform dependent)
    260     q->setProcessState(QProcess::Starting);
    261 
    262     // save & copy the stdin socket
    263     int stdin_copy = ::dup(fileno(stdin));
    264     ::dup2(stdinChannel.pipe[0], fileno(stdin));
    265 
    266     // save & copy the stdout and stderr if asked to
    267     int stdout_copy = -1, stderr_copy = -1;
    268     if (processChannelMode != QProcess::ForwardedChannels) {
    269         stdout_copy = ::dup(fileno(stdout));
    270         ::dup2(stdoutChannel.pipe[1], fileno(stdout));
    271 
    272         // merge stdout and stderr if asked to
    273         stderr_copy = ::dup(fileno(stderr));
    274         if (processChannelMode == QProcess::MergedChannels) {
    275             ::dup2(fileno(stdout), fileno(stderr));
    276         } else {
    277             ::dup2(stderrChannel.pipe[1], fileno(stderr));
    278         }
    279     }
     245static int qt_startProcess(const QString &program, const QStringList &arguments,
     246                           const QString &workingDirectory,
     247                           const QStringList *environment, bool detached = false)
     248{
     249    int mode = detached ? P_DETACH : P_NOWAIT;
    280250
    281251    // Create argument list with right number of elements, and set the final
     
    299269    int envc = 0;
    300270    char **envv;
    301     if (environment.count()) {
     271    if (environmentcount()) {
    302272        bool seenPATH = false;
    303273        bool seenCOMSPEC = false;
    304274
    305         envv = new char *[environment.count() + 1 + 2 /* may be PATH + COMSPEC */];
    306         for (; envc < environment.count(); ++envc) {
    307             QString item = environment.at(envc);
     275        envv = new char *[environmentcount() + 1 + 2 /* may be PATH + COMSPEC */];
     276        for (; envc < environmentcount(); ++envc) {
     277            QString item = environmentat(envc);
    308278            envv[envc] = qstrdup(item.toLocal8Bit().constData());
    309279            if (!seenPATH)
     
    340310
    341311    // start the program
    342     int pid = spawnvpe(P_NOWAIT | P_DEFAULT, encodedProgramName, argv, envv);
     312    int pid = spawnvpe( | P_DEFAULT, encodedProgramName, argv, envv);
    343313
    344314    // if spawnvpe() couldn't find the executable, try .CMD and .BAT
     
    368338    // restore the current directory
    369339    QDir::setCurrent(curDir);
     340
     341
     342
     343
     344
     345
     346
     347
     348
     349
     350
     351
     352
     353
     354
     355
     356
     357
     358
     359
     360
     361
     362
     363
     364
     365
     366
     367
     368
     369
     370
     371
     372
     373
     374
     375
     376
     377
     378
     379
     380
     381
    370382
    371383    // restore stdin/stdout/stderr
     
    776788/*! \internal
    777789 */
    778 bool QProcessPrivate::startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory, qint64 *pid)
    779 {
    780 // @todo later
    781 #if 0
    782     processManager()->start();
    783 
    784     QByteArray encodedWorkingDirectory = QFile::encodeName(workingDirectory);
    785 
    786     // To catch the startup of the child
    787     int startedPipe[2];
    788     ::pipe(startedPipe);
    789     // To communicate the pid of the child
    790     int pidPipe[2];
    791     ::pipe(pidPipe);
    792 
    793     pid_t childPid = qt_fork();
    794     if (childPid == 0) {
    795         struct sigaction noaction;
    796         memset(&noaction, 0, sizeof(noaction));
    797         noaction.sa_handler = SIG_IGN;
    798         qt_native_sigaction(SIGPIPE, &noaction, 0);
    799 
    800         ::setsid();
    801 
    802         qt_native_close(startedPipe[0]);
    803         qt_native_close(pidPipe[0]);
    804 
    805         pid_t doubleForkPid = qt_fork();
    806         if (doubleForkPid == 0) {
    807             ::fcntl(startedPipe[1], F_SETFD, FD_CLOEXEC);
    808             qt_native_close(pidPipe[1]);
    809 
    810             if (!encodedWorkingDirectory.isEmpty())
    811                 qt_native_chdir(encodedWorkingDirectory.constData());
    812 
    813             char **argv = new char *[arguments.size() + 2];
    814             for (int i = 0; i < arguments.size(); ++i) {
    815 #ifdef Q_OS_MAC
    816                 argv[i + 1] = ::strdup(arguments.at(i).toUtf8().constData());
    817 #else
    818                 argv[i + 1] = ::strdup(arguments.at(i).toLocal8Bit().constData());
    819 #endif
    820             }
    821             argv[arguments.size() + 1] = 0;
    822 
    823             if (!program.contains(QLatin1Char('/'))) {
    824                 const QString path = QString::fromLocal8Bit(::getenv("PATH"));
    825                 if (!path.isEmpty()) {
    826                     QStringList pathEntries = path.split(QLatin1Char(':'));
    827                     for (int k = 0; k < pathEntries.size(); ++k) {
    828                         QByteArray tmp = QFile::encodeName(pathEntries.at(k));
    829                         if (!tmp.endsWith('/')) tmp += '/';
    830                         tmp += QFile::encodeName(program);
    831                         argv[0] = tmp.data();
    832                         qt_native_execv(argv[0], argv);
    833                     }
    834                 }
    835             } else {
    836                 QByteArray tmp = QFile::encodeName(program);
    837                 argv[0] = tmp.data();
    838                 qt_native_execv(argv[0], argv);
    839             }
    840 
    841             struct sigaction noaction;
    842             memset(&noaction, 0, sizeof(noaction));
    843             noaction.sa_handler = SIG_IGN;
    844             qt_native_sigaction(SIGPIPE, &noaction, 0);
    845 
    846             // '\1' means execv failed
    847             char c = '\1';
    848             qt_native_write(startedPipe[1], &c, 1);
    849             qt_native_close(startedPipe[1]);
    850             ::_exit(1);
    851         } else if (doubleForkPid == -1) {
    852             struct sigaction noaction;
    853             memset(&noaction, 0, sizeof(noaction));
    854             noaction.sa_handler = SIG_IGN;
    855             qt_native_sigaction(SIGPIPE, &noaction, 0);
    856 
    857             // '\2' means internal error
    858             char c = '\2';
    859             qt_native_write(startedPipe[1], &c, 1);
    860         }
    861 
    862         qt_native_close(startedPipe[1]);
    863         qt_native_write(pidPipe[1], (const char *)&doubleForkPid, sizeof(pid_t));
    864         qt_native_chdir("/");
    865         ::_exit(1);
    866     }
    867 
    868     qt_native_close(startedPipe[1]);
    869     qt_native_close(pidPipe[1]);
    870 
    871     if (childPid == -1) {
    872         qt_native_close(startedPipe[0]);
    873         qt_native_close(pidPipe[0]);
     790bool QProcessPrivate::startDetached(const QString &program, const QStringList &arguments,
     791                                    const QString &workingDirectory, qint64 *pid)
     792{
     793    int startedPid = qt_startProcess(program, arguments, workingDirectory,
     794                                     NULL, true /* detached */);
     795
     796    if (startedPid == -1)
    874797        return false;
    875     }
    876 
    877     char reply = '\0';
    878     int startResult = qt_native_read(startedPipe[0], &reply, 1);
    879     int result;
    880     qt_native_close(startedPipe[0]);
    881     while (::waitpid(childPid, &result, 0) == -1 && errno == EINTR)
    882     { }
    883     bool success = (startResult != -1 && reply == '\0');
    884     if (success && pid) {
    885         pid_t actualPid = 0;
    886         if (qt_native_read(pidPipe[0], (char *)&actualPid, sizeof(pid_t)) == sizeof(pid_t)) {
    887             *pid = actualPid;
    888         } else {
    889             *pid = 0;
    890         }
    891     }
    892     qt_native_close(pidPipe[0]);
    893     return success;
    894 #endif
     798
     799    *pid = startedPid;
     800    return true;
    895801}
    896802
Note: See TracChangeset for help on using the changeset viewer.