Changeset 73
- Timestamp:
- Jul 9, 2009, 2:16:47 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/corelib/io/qprocess_os2.cpp
r72 r73 243 243 } 244 244 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 } 245 static 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; 280 250 281 251 // Create argument list with right number of elements, and set the final … … 299 269 int envc = 0; 300 270 char **envv; 301 if (environment .count()) {271 if (environmentcount()) { 302 272 bool seenPATH = false; 303 273 bool seenCOMSPEC = false; 304 274 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); 308 278 envv[envc] = qstrdup(item.toLocal8Bit().constData()); 309 279 if (!seenPATH) … … 340 310 341 311 // start the program 342 int pid = spawnvpe( P_NOWAIT| P_DEFAULT, encodedProgramName, argv, envv);312 int pid = spawnvpe( | P_DEFAULT, encodedProgramName, argv, envv); 343 313 344 314 // if spawnvpe() couldn't find the executable, try .CMD and .BAT … … 368 338 // restore the current directory 369 339 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 370 382 371 383 // restore stdin/stdout/stderr … … 776 788 /*! \internal 777 789 */ 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]); 790 bool 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) 874 797 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; 895 801 } 896 802
Note:
See TracChangeset
for help on using the changeset viewer.