- Timestamp:
- Jan 6, 2007, 7:38:01 PM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel/qprocess_pm.cpp
r159 r168 48 48 #include "qintdict.h" 49 49 #include "qmutex.h" 50 #include "qfile.h" 50 51 #include "private/qinternal_p.h" 51 52 #include "qt_os2.h" 52 53 54 // When QT_QPROCESS_USE_DOSEXECPGM is not defined, we use spawnvpe() instead of 55 // DosExecPgm() to let LIBC file (pipe, socket) descriptors be properly 56 // inherited if the child uses the same LIBC version. 57 //#define QT_QPROCESS_USE_DOSEXECPGM 58 53 59 #include <string.h> 60 61 #if !defined(QT_QPROCESS_USE_DOSEXECPGM) 62 #include <process.h> 63 #include <sys/wait.h> 64 #endif 54 65 55 66 //#define QT_QPROCESS_DEBUG … … 754 765 if ( _arguments.isEmpty() ) 755 766 return FALSE; 767 768 #if defined(QT_QPROCESS_USE_DOSEXECPGM) 756 769 757 770 // construct the arguments for DosExecPgm() … … 979 992 appNameFull.data(), buf.data(), buf.data() + strlen( buf.data() ) + 1 ); 980 993 #endif 981 994 995 #else // QT_QPROCESS_USE_DOSEXECPGM 996 997 // construct the arguments for spawnvpe() 998 999 QCString appName; 1000 QStrList appArgs; 1001 1002 for ( QStringList::ConstIterator it = _arguments.begin(); 1003 it != _arguments.end(); ++ it 1004 ) { 1005 if ( it == _arguments.begin() ) { 1006 appName = QFile::encodeName( *it ); 1007 } else { 1008 appArgs.append( QFile::encodeName( *it ) ); 1009 } 1010 } 1011 1012 #if defined(QT_QPROCESS_DEBUG) 1013 qDebug( "QProcess::start(): [%s]", 1014 QFile::encodeName( _arguments.join( "] [" ) ).data() ); 1015 #endif 1016 1017 // prepare the environment 1018 1019 QStrList envList; 1020 if ( env != 0 ) { 1021 // add the user environment 1022 bool seenPATH = FALSE; 1023 bool seenCOMSPEC = FALSE; 1024 for ( QStringList::ConstIterator it = env->begin(); 1025 it != env->end(); ++ it 1026 ) { 1027 envList.append( QFile::encodeName( *it ) ); 1028 if ( !seenPATH ) 1029 seenPATH = !strncmp( envList.current(), "PATH=", 4 ); 1030 if ( !seenCOMSPEC ) 1031 seenCOMSPEC = !strncmp( envList.current(), "COMSPEC=", 8 ); 1032 } 1033 if ( !seenPATH ) { 1034 // inherit PATH if missing (for convenience) 1035 // (note that BEGINLIBPATH and ENDLIBPATH, if any, are automatically 1036 // inherited, while LIBPATH is always a global setting) 1037 const char *path = getenv( "PATH" ); 1038 QCString str( 5 /* PATH= */ + strlen( path ) + 1 /* \0 */ ); 1039 strcpy( str.data(), "PATH=" ); 1040 strcat( str.data() + 5, path ); 1041 envList.append( str ); 1042 } 1043 // inherit COMSPEC if missing (to let the child start .cmd and .bat) 1044 if ( !seenCOMSPEC ) { 1045 const char *comspec = getenv( "COMSPEC" ); 1046 QCString str( 8 /* COMSPEC= */ + strlen( comspec ) + 1 /* \0 */ ); 1047 strcpy( str.data(), "COMSPEC=" ); 1048 strcat( str.data() + 5, comspec ); 1049 envList.append( str ); 1050 } 1051 } 1052 1053 APIRET rc = 0; 1054 char pathBuf[ CCHMAXPATH ]; 1055 1056 #endif // QT_QPROCESS_USE_DOSEXECPGM 1057 982 1058 // create STDIN/OUT/ERR redirection pipes 983 1059 … … 1206 1282 #endif 1207 1283 1284 #if defined(QT_QPROCESS_USE_DOSEXECPGM) 1285 1208 1286 // DosExecPgm() 1209 1287 … … 1213 1291 buf.data(), envlist.data(), &resc, appNameFull.data() ); 1214 1292 1293 #else // defined(QT_QPROCESS_USE_DOSEXECPGM) 1294 1295 // start the application 1296 1297 int i = 0; 1298 1299 char **argv = new char *[ appArgs.count() + 2 ]; 1300 argv[ i++ ] = appName.data(); 1301 for ( appArgs.first(); appArgs.current(); appArgs.next() ) 1302 argv[ i++ ] = appArgs.current(); 1303 argv[ i ] = NULL; 1304 1305 char **envv = NULL; 1306 if ( envList.count() ) { 1307 i = 0; 1308 envv = new char *[ envList.count() + 1 ]; 1309 for ( envList.first(); envList.current(); envList.next() ) 1310 envv[ i++ ] = envList.current(); 1311 envv[ i ] = NULL; 1312 } else { 1313 envv = environ; 1314 } 1315 1316 int pid = spawnvpe( P_NOWAIT | P_DEFAULT, appName.data(), argv, envv ); 1317 1318 // if spawnvpe() couldn't find the executable, try .CMD and .BAT 1319 // extensions (in order of CMD.EXE precedence); spawnvpe() knows how to 1320 // locate and run them (i.e. using CMD.EXE /c) 1321 if ( pid == -1 && errno == ENOENT ) { 1322 appName += ".cmd"; 1323 pid = spawnvpe( P_NOWAIT | P_DEFAULT, appName.data(), argv, envv ); 1324 if ( pid == -1 && errno == ENOENT ) { 1325 strcpy( appName.data() + appName.length() - 4, ".bat" ); 1326 pid = spawnvpe( P_NOWAIT | P_DEFAULT, appName.data(), argv, envv ); 1327 } 1328 } 1329 1330 if ( envv != environ ) 1331 delete[] envv; 1332 delete[] argv; 1333 1334 #endif // defined(QT_QPROCESS_USE_DOSEXECPGM) 1335 1215 1336 // restore the current directory 1216 1337 QDir::setCurrent( curDir ); … … 1232 1353 UninstallQtMsgHandler(); 1233 1354 1355 #if defined(QT_QPROCESS_USE_DOSEXECPGM) 1356 1234 1357 if ( rc != NO_ERROR ) { 1235 1358 #if defined(QT_CHECK_STATE) || defined(QT_QPROCESS_DEBUG) … … 1248 1371 // memporize PID of the started process 1249 1372 d->pid = resc.codeTerminate; 1373 1374 #else // defined(QT_QPROCESS_USE_DOSEXECPGM) 1375 1376 if ( pid == -1 ) { 1377 #if defined(QT_CHECK_STATE) || defined(QT_QPROCESS_DEBUG) 1378 qWarning( "Failed to start a new process [%s]\n" 1379 "errno=%d (%s)", 1380 QFile::encodeName( _arguments.join( "] [" ) ).data(), 1381 errno, strerror( errno ) ); 1382 #endif 1383 processMonitor->removeProcess( d ); 1384 d->closeHandles(); 1385 return FALSE; 1386 } 1387 1388 // memporize PID of the started process 1389 d->pid = pid; 1390 1391 #endif // defined(QT_QPROCESS_USE_DOSEXECPGM) 1392 1393 #if defined(QT_QPROCESS_DEBUG) 1394 qDebug( "QProcess::start(): started PID %lu (0x%08lX)", d->pid, d->pid ); 1395 #endif 1250 1396 1251 1397 // timer is not necessary for ioRedirection (we use the monitor thread) … … 1297 1443 return FALSE; 1298 1444 1445 #if defined(QT_QPROCESS_USE_DOSEXECPGM) 1446 1299 1447 PID pidEnded = PID_NULL; 1300 1448 RESULTCODES resc = { 0 }; … … 1305 1453 return TRUE; 1306 1454 1455 #else // defined(QT_QPROCESS_USE_DOSEXECPGM) 1456 1457 int stat = 0; 1458 int pid = waitpid( d->pid, &stat, WNOHANG ); 1459 if ( (pid == 0) || 1460 ((PID) pid == d->pid && 1461 !WIFEXITED( stat ) && !WIFSIGNALED( stat ) && !WIFSTOPPED( stat ) ) ) 1462 return TRUE; 1463 1464 if ( pid == -1 ) { 1465 #if defined(QT_CHECK_STATE) || defined(QT_QPROCESS_DEBUG) 1466 qWarning( "Failed to wait for a child process\n" 1467 "errno=%d (%s)", errno, strerror( errno ) ); 1468 #endif 1469 } 1470 1471 #endif // defined(QT_QPROCESS_USE_DOSEXECPGM) 1472 1307 1473 QProcess *that = (QProcess *) this; 1308 1474 … … 1318 1484 // compute the exit values 1319 1485 if ( !d->exitValuesCalculated ) { 1486 #if defined(QT_QPROCESS_USE_DOSEXECPGM) 1320 1487 that->exitNormal = resc.codeTerminate == TC_EXIT; 1321 1488 that->exitStat = resc.codeResult; 1489 #else // defined(QT_QPROCESS_USE_DOSEXECPGM) 1490 that->exitNormal = pid != -1 && WIFEXITED( stat ); 1491 that->exitStat = WEXITSTATUS( stat ); 1492 #endif // defined(QT_QPROCESS_USE_DOSEXECPGM) 1322 1493 d->exitValuesCalculated = TRUE; 1323 1494 }
Note:
See TracChangeset
for help on using the changeset viewer.