10#include <qscopedvaluerollback.h>
15#include <qbytearray.h>
16#include <qdeadlinetimer.h>
17#include <qcoreapplication.h>
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
62QStringList QProcessEnvironmentPrivate::toList()
const
65 result.reserve(vars.size());
66 for (
auto it = vars.cbegin(), end = vars.cend(); it != end; ++it)
67 result << nameToString(it.key()) + u'=' + valueToString(it.value());
74 QStringList::ConstIterator it = list.constBegin(),
75 end = list.constEnd();
76 for ( ; it != end; ++it) {
77 const qsizetype pos = it->indexOf(u'=', 1);
81 QString value = it->mid(pos + 1);
84 env.insert(name, value);
92 result.reserve(vars.size());
93 auto it = vars.constBegin();
94 const auto end = vars.constEnd();
95 for ( ; it != end; ++it)
96 result << nameToString(it.key());
102 auto it = other.vars.constBegin();
103 const auto end = other.vars.constEnd();
104 for ( ; it != end; ++it)
105 vars.insert(it.key(), it.value());
108 const OrderedNameMapMutexLocker locker(
this, &other);
109 auto nit = other.nameMap.constBegin();
110 const auto nend = other.nameMap.constEnd();
111 for ( ; nit != nend; ++nit)
112 nameMap.insert(nit.key(), nit.value());
117
118
119
120
121
122
123
124
125
128
129
130
131
132
133QProcessEnvironment::QProcessEnvironment() : d(
new QProcessEnvironmentPrivate) { }
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153QProcessEnvironment::QProcessEnvironment(QProcessEnvironment::Initialization)
noexcept { }
156
157
158QProcessEnvironment::~QProcessEnvironment()
163
164
165QProcessEnvironment::QProcessEnvironment(
const QProcessEnvironment &other)
171
172
173
174QProcessEnvironment &QProcessEnvironment::operator=(
const QProcessEnvironment &other)
181
182
183
184
187
188
189
190
191
192
195
196
197
198
199
200
201
202
203
204
205bool comparesEqual(
const QProcessEnvironment &lhs,
const QProcessEnvironment &rhs)
210 return lhs.d && rhs.d && lhs.d->vars == rhs.d->vars;
214
215
216
217
218
219
220
221
222bool QProcessEnvironment::isEmpty()
const
225 return d ? d->vars.isEmpty() :
true;
229
230
231
232
233
234
235bool QProcessEnvironment::inheritsFromParent()
const
241
242
243
244
245
246
247
248
249void QProcessEnvironment::clear()
258
259
260
261
262
263
264bool QProcessEnvironment::contains(
const QString &name)
const
268 return d->vars.contains(d->prepareName(name));
272
273
274
275
276
277
278
279
280
281
282
283void QProcessEnvironment::insert(
const QString &name,
const QString &value)
287 d->vars.insert(d->prepareName(name), d->prepareValue(value));
291
292
293
294
295
296
297
298void QProcessEnvironment::remove(
const QString &name)
301 QProcessEnvironmentPrivate *p = d.data();
302 p->vars.remove(p->prepareName(name));
307
308
309
310
311
312
313QString QProcessEnvironment::value(
const QString &name,
const QString &defaultValue)
const
318 const auto it = d->vars.constFind(d->prepareName(name));
319 if (it == d->vars.constEnd())
322 return d->valueToString(it.value());
326
327
328
329
330
331
332
333
334
335
336
337
338QStringList QProcessEnvironment::toStringList()
const
341 return QStringList();
346
347
348
349
350
351
352
353
354QStringList QProcessEnvironment::keys()
const
357 return QStringList();
362
363
364
365
366
367
368void QProcessEnvironment::insert(
const QProcessEnvironment &e)
377#if QT_CONFIG(process)
379void QProcessPrivate::Channel::clear()
384 process->stdinChannel.type = Normal;
385 process->stdinChannel.process =
nullptr;
389 process->stdoutChannel.type = Normal;
390 process->stdoutChannel.process =
nullptr;
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
627
628
629
630
631
632
633
634
635
636
637
638
639
640
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
740
741
742
743
744
745
746
747
748
749
750
751
752
753
756
757
758
759
760
761
762
763
764
765
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
798
799
800
801
802
803
804
805
806
807
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
912
913
914
915
916
917
920
921
922
923
924
927
928
929
930
931
934
935
936
937
938
939
940
941
942
943
944
947
948
949
950
951
952
953
954
957
958
959
960
961
962
963
964
965
968
969
970QProcessPrivate::QProcessPrivate()
972 readBufferChunkSize = QRINGBUFFER_CHUNKSIZE;
974 writeBufferChunkSize = QRINGBUFFER_CHUNKSIZE;
979
980
981QProcessPrivate::~QProcessPrivate()
983 if (stdinChannel.process)
984 stdinChannel.process->stdoutChannel.clear();
985 if (stdoutChannel.process)
986 stdoutChannel.process->stdinChannel.clear();
990
991
992void QProcessPrivate::setError(QProcess::ProcessError error,
const QString &description)
994 processError = error;
995 if (description.isEmpty()) {
997 case QProcess::FailedToStart:
998 errorString = QProcess::tr(
"Process failed to start");
1000 case QProcess::Crashed:
1001 errorString = QProcess::tr(
"Process crashed");
1003 case QProcess::Timedout:
1004 errorString = QProcess::tr(
"Process operation timed out");
1006 case QProcess::ReadError:
1007 errorString = QProcess::tr(
"Error reading from process");
1009 case QProcess::WriteError:
1010 errorString = QProcess::tr(
"Error writing to process");
1012 case QProcess::UnknownError:
1013 errorString.clear();
1017 errorString = description;
1022
1023
1024void QProcessPrivate::setErrorAndEmit(QProcess::ProcessError error,
const QString &description)
1027 Q_ASSERT(error != QProcess::UnknownError);
1028 setError(error, description);
1029 emit q->errorOccurred(QProcess::ProcessError(processError));
1033
1034
1035bool QProcessPrivate::openChannels()
1038 if (inputChannelMode == QProcess::ForwardedInputChannel) {
1039 if (stdinChannel.type != Channel::Normal)
1040 qWarning(
"QProcess::openChannels: Inconsistent stdin channel configuration");
1041 }
else if (!openChannel(stdinChannel)) {
1046 if (processChannelMode == QProcess::ForwardedChannels
1047 || processChannelMode == QProcess::ForwardedOutputChannel) {
1048 if (stdoutChannel.type != Channel::Normal)
1049 qWarning(
"QProcess::openChannels: Inconsistent stdout channel configuration");
1050 }
else if (!openChannel(stdoutChannel)) {
1055 if (processChannelMode == QProcess::ForwardedChannels
1056 || processChannelMode == QProcess::ForwardedErrorChannel
1057 || processChannelMode == QProcess::MergedChannels) {
1058 if (stderrChannel.type != Channel::Normal)
1059 qWarning(
"QProcess::openChannels: Inconsistent stderr channel configuration");
1060 }
else if (!openChannel(stderrChannel)) {
1068
1069
1070void QProcessPrivate::closeChannels()
1072 closeChannel(&stdoutChannel);
1073 closeChannel(&stderrChannel);
1074 closeChannel(&stdinChannel);
1078
1079
1080bool QProcessPrivate::openChannelsForDetached()
1083 bool needToOpen = (stdinChannel.type == Channel::Redirect
1084 || stdinChannel.type == Channel::PipeSink);
1085 if (stdinChannel.type != Channel::Normal
1087 || inputChannelMode == QProcess::ForwardedInputChannel)) {
1088 qWarning(
"QProcess::openChannelsForDetached: Inconsistent stdin channel configuration");
1090 if (needToOpen && !openChannel(stdinChannel))
1094 needToOpen = (stdoutChannel.type == Channel::Redirect
1095 || stdoutChannel.type == Channel::PipeSource);
1096 if (stdoutChannel.type != Channel::Normal
1098 || processChannelMode == QProcess::ForwardedChannels
1099 || processChannelMode == QProcess::ForwardedOutputChannel)) {
1100 qWarning(
"QProcess::openChannelsForDetached: Inconsistent stdout channel configuration");
1102 if (needToOpen && !openChannel(stdoutChannel))
1106 needToOpen = (stderrChannel.type == Channel::Redirect);
1107 if (stderrChannel.type != Channel::Normal
1109 || processChannelMode == QProcess::ForwardedChannels
1110 || processChannelMode == QProcess::ForwardedErrorChannel
1111 || processChannelMode == QProcess::MergedChannels)) {
1112 qWarning(
"QProcess::openChannelsForDetached: Inconsistent stderr channel configuration");
1114 if (needToOpen && !openChannel(stderrChannel))
1121
1122
1123
1124bool QProcessPrivate::tryReadFromChannel(Channel *channel)
1127 if (channel->pipe[0] == INVALID_Q_PIPE)
1130 qint64 available = bytesAvailableInChannel(channel);
1134 QProcess::ProcessChannel channelIdx = (channel == &stdoutChannel
1135 ? QProcess::StandardOutput
1136 : QProcess::StandardError);
1137 Q_ASSERT(readBuffers.size() >
int(channelIdx));
1138 QRingBuffer &readBuffer = readBuffers[
int(channelIdx)];
1139 char *ptr = readBuffer.reserve(available);
1140 qint64 readBytes = readFromChannel(channel, ptr, available);
1142 readBuffer.chop(available);
1143 if (readBytes == -2) {
1147 if (readBytes == -1) {
1148 setErrorAndEmit(QProcess::ReadError);
1149#if defined QPROCESS_DEBUG
1150 qDebug(
"QProcessPrivate::tryReadFromChannel(%d), failed to read from the process",
1151 int(channel - &stdinChannel));
1155 if (readBytes == 0) {
1157 closeChannel(channel);
1158#if defined QPROCESS_DEBUG
1159 qDebug(
"QProcessPrivate::tryReadFromChannel(%d), 0 bytes available",
1160 int(channel - &stdinChannel));
1164#if defined QPROCESS_DEBUG
1165 qDebug(
"QProcessPrivate::tryReadFromChannel(%d), read %lld bytes from the process' output",
1166 int(channel - &stdinChannel), readBytes);
1169 if (channel->closed) {
1170 readBuffer.chop(readBytes);
1174 readBuffer.chop(available - readBytes);
1176 bool didRead =
false;
1177 if (currentReadChannel == channelIdx) {
1179 if (!emittedReadyRead) {
1180 QScopedValueRollback<
bool> guard(emittedReadyRead,
true);
1181 emit q->readyRead();
1184 emit q->channelReadyRead(
int(channelIdx));
1185 if (channelIdx == QProcess::StandardOutput)
1186 emit q->readyReadStandardOutput(QProcess::QPrivateSignal());
1188 emit q->readyReadStandardError(QProcess::QPrivateSignal());
1193
1194
1195bool QProcessPrivate::_q_canReadStandardOutput()
1197 return tryReadFromChannel(&stdoutChannel);
1201
1202
1203bool QProcessPrivate::_q_canReadStandardError()
1205 return tryReadFromChannel(&stderrChannel);
1209
1210
1211void QProcessPrivate::_q_processDied()
1213#if defined QPROCESS_DEBUG
1214 qDebug(
"QProcessPrivate::_q_processDied()");
1223 _q_canReadStandardOutput();
1224 _q_canReadStandardError();
1230 if (processState != QProcess::NotRunning)
1235
1236
1237void QProcessPrivate::processFinished()
1240#if defined QPROCESS_DEBUG
1241 qDebug(
"QProcessPrivate::processFinished()");
1252 if (exitStatus == QProcess::CrashExit)
1253 setErrorAndEmit(QProcess::Crashed);
1256 emit q->readChannelFinished();
1261 emit q->finished(exitCode, QProcess::ExitStatus(exitStatus));
1263#if defined QPROCESS_DEBUG
1264 qDebug(
"QProcessPrivate::processFinished(): process is dead");
1269
1270
1271bool QProcessPrivate::_q_startupNotification()
1274#if defined QPROCESS_DEBUG
1275 qDebug(
"QProcessPrivate::startupNotification()");
1278 QString errorMessage;
1279 if (processStarted(&errorMessage)) {
1280 q->setProcessState(QProcess::Running);
1281 emit q->started(QProcess::QPrivateSignal());
1285 q->setProcessState(QProcess::NotRunning);
1286 setErrorAndEmit(QProcess::FailedToStart, errorMessage);
1295
1296
1297void QProcessPrivate::closeWriteChannel()
1299#if defined QPROCESS_DEBUG
1300 qDebug(
"QProcessPrivate::closeWriteChannel()");
1303 closeChannel(&stdinChannel);
1307
1308
1309QProcess::QProcess(QObject *parent)
1310 : QIODevice(*
new QProcessPrivate, parent)
1312#if defined QPROCESS_DEBUG
1313 qDebug(
"QProcess::QProcess(%p)", parent);
1318
1319
1320
1321
1322
1323QProcess::~QProcess()
1326 if (d->processState != NotRunning) {
1327 qWarning().nospace()
1328 <<
"QProcess: Destroyed while process (" << QDir::toNativeSeparators(program()) <<
") is still running.";
1336
1337
1338
1339
1340
1341
1342
1343QProcess::ProcessChannelMode QProcess::processChannelMode()
const
1345 Q_D(
const QProcess);
1346 return ProcessChannelMode(d->processChannelMode);
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360void QProcess::setProcessChannelMode(ProcessChannelMode mode)
1363 d->processChannelMode = mode;
1367
1368
1369
1370
1371
1372
1373QProcess::InputChannelMode QProcess::inputChannelMode()
const
1375 Q_D(
const QProcess);
1376 return InputChannelMode(d->inputChannelMode);
1380
1381
1382
1383
1384
1385
1386
1387
1388void QProcess::setInputChannelMode(InputChannelMode mode)
1391 d->inputChannelMode = mode;
1395
1396
1397
1398
1399QProcess::ProcessChannel QProcess::readChannel()
const
1401 Q_D(
const QProcess);
1402 return ProcessChannel(d->currentReadChannel);
1406
1407
1408
1409
1410
1411
1412
1413void QProcess::setReadChannel(ProcessChannel channel)
1415 QIODevice::setCurrentReadChannel(
int(channel));
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428void QProcess::closeReadChannel(ProcessChannel channel)
1432 if (channel == StandardOutput)
1433 d->stdoutChannel.closed =
true;
1435 d->stderrChannel.closed =
true;
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456void QProcess::closeWriteChannel()
1459 d->stdinChannel.closed =
true;
1460 if (bytesToWrite() == 0)
1461 d->closeWriteChannel();
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485void QProcess::setStandardInputFile(
const QString &fileName)
1488 d->stdinChannel = fileName;
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520void QProcess::setStandardOutputFile(
const QString &fileName, OpenMode mode)
1522 Q_ASSERT(mode == Append || mode == Truncate);
1525 d->stdoutChannel = fileName;
1526 d->stdoutChannel.append = mode == Append;
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547void QProcess::setStandardErrorFile(
const QString &fileName, OpenMode mode)
1549 Q_ASSERT(mode == Append || mode == Truncate);
1552 d->stderrChannel = fileName;
1553 d->stderrChannel.append = mode == Append;
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568void QProcess::setStandardOutputProcess(QProcess *destination)
1570 QProcessPrivate *dfrom = d_func();
1571 QProcessPrivate *dto = destination->d_func();
1572 dfrom->stdoutChannel.pipeTo(dto);
1573 dto->stdinChannel.pipeFrom(dfrom);
1576#if defined(Q_OS_WIN) || defined(Q_QDOC)
1579
1580
1581
1582
1583
1584
1585
1586
1587QString QProcess::nativeArguments()
const
1589 Q_D(
const QProcess);
1590 return d->nativeArguments;
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610void QProcess::setNativeArguments(
const QString &arguments)
1613 d->nativeArguments = arguments;
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626QProcess::CreateProcessArgumentModifier QProcess::createProcessArgumentsModifier()
const
1628 Q_D(
const QProcess);
1629 return d->modifyCreateProcessArgs;
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643void QProcess::setCreateProcessArgumentsModifier(CreateProcessArgumentModifier modifier)
1646 d->modifyCreateProcessArgs = modifier;
1651#if defined(Q_OS_UNIX) || defined(Q_QDOC)
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662std::function<
void(
void)> QProcess::childProcessModifier()
const
1664 Q_D(
const QProcess);
1665 return d->unixExtras ? d->unixExtras->childProcessModifier : std::function<
void(
void)>();
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715void QProcess::setChildProcessModifier(
const std::function<
void(
void)> &modifier)
1719 d->unixExtras.reset(
new QProcessPrivate::UnixExtras);
1720 d->unixExtras->childProcessModifier = modifier;
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773auto QProcess::unixProcessParameters()
const noexcept -> UnixProcessParameters
1775 Q_D(
const QProcess);
1776 return d->unixExtras ? d->unixExtras->processParameters : UnixProcessParameters{};
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797void QProcess::setUnixProcessParameters(
const UnixProcessParameters ¶ms)
1801 d->unixExtras.reset(
new QProcessPrivate::UnixExtras);
1802 d->unixExtras->processParameters = params;
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816void QProcess::setUnixProcessParameters(UnixProcessFlags flagsOnly)
1820 d->unixExtras.reset(
new QProcessPrivate::UnixExtras);
1821 d->unixExtras->processParameters = { flagsOnly };
1826
1827
1828
1829
1830
1831
1832
1833
1834QString QProcess::workingDirectory()
const
1836 Q_D(
const QProcess);
1837 return d->workingDirectory;
1841
1842
1843
1844
1845
1846
1847void QProcess::setWorkingDirectory(
const QString &dir)
1850 d->workingDirectory = dir;
1854
1855
1856
1857
1858
1859qint64 QProcess::processId()
const
1861 Q_D(
const QProcess);
1863 return d->pid ? d->pid->dwProcessId : 0;
1870
1871
1872
1873
1874void QProcess::close()
1877 emit aboutToClose();
1878 while (waitForBytesWritten(-1))
1881 waitForFinished(-1);
1882 d->setWriteChannelCount(0);
1887
1888bool QProcess::isSequential()
const
1894
1895qint64 QProcess::bytesToWrite()
const
1898 return d_func()->pipeWriterBytesToWrite();
1900 return QIODevice::bytesToWrite();
1905
1906
1907
1908
1909QProcess::ProcessError QProcess::error()
const
1911 Q_D(
const QProcess);
1912 return ProcessError(d->processError);
1916
1917
1918
1919
1920QProcess::ProcessState QProcess::state()
const
1922 Q_D(
const QProcess);
1923 return ProcessState(d->processState);
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940void QProcess::setEnvironment(
const QStringList &environment)
1942 setProcessEnvironment(QProcessEnvironmentPrivate::fromList(environment));
1946
1947
1948
1949
1950
1951
1952
1953
1954QStringList QProcess::environment()
const
1956 Q_D(
const QProcess);
1957 return d->environment.toStringList();
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973void QProcess::setProcessEnvironment(
const QProcessEnvironment &environment)
1976 d->environment = environment;
1980
1981
1982
1983
1984
1985
1986
1987
1988QProcessEnvironment QProcess::processEnvironment()
const
1990 Q_D(
const QProcess);
1991 return d->environment;
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014bool QProcess::waitForStarted(
int msecs)
2017 if (d->processState == QProcess::Starting)
2018 return d->waitForStarted(QDeadlineTimer(msecs));
2020 return d->processState == QProcess::Running;
2024
2025bool QProcess::waitForReadyRead(
int msecs)
2029 if (d->processState == QProcess::NotRunning)
2031 if (d->currentReadChannel == QProcess::StandardOutput && d->stdoutChannel.closed)
2033 if (d->currentReadChannel == QProcess::StandardError && d->stderrChannel.closed)
2036 QDeadlineTimer deadline(msecs);
2037 if (d->processState == QProcess::Starting) {
2038 bool started = d->waitForStarted(deadline);
2043 return d->waitForReadyRead(deadline);
2047
2048bool QProcess::waitForBytesWritten(
int msecs)
2051 if (d->processState == QProcess::NotRunning)
2054 QDeadlineTimer deadline(msecs);
2055 if (d->processState == QProcess::Starting) {
2056 bool started = d->waitForStarted(deadline);
2061 return d->waitForBytesWritten(deadline);
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083bool QProcess::waitForFinished(
int msecs)
2086 if (d->processState == QProcess::NotRunning)
2089 QDeadlineTimer deadline(msecs);
2090 if (d->processState == QProcess::Starting) {
2091 bool started = d->waitForStarted(deadline);
2096 return d->waitForFinished(deadline);
2100
2101
2102
2103
2104void QProcess::setProcessState(ProcessState state)
2107 if (d->processState == state)
2109 d->processState = state;
2110 emit stateChanged(state, QPrivateSignal());
2113#if QT_VERSION < QT_VERSION_CHECK(7
,0
,0
)
2115
2116
2117auto QProcess::setupChildProcess() -> Use_setChildProcessModifier_Instead
2119 Q_UNREACHABLE_RETURN({});
2124
2125qint64 QProcess::readData(
char *data, qint64 maxlen)
2131 if (d->processState == QProcess::NotRunning)
2137
2138
2139
2140
2141
2142
2143QByteArray QProcess::readAllStandardOutput()
2145 ProcessChannel tmp = readChannel();
2146 setReadChannel(StandardOutput);
2147 QByteArray data = readAll();
2148 setReadChannel(tmp);
2153
2154
2155
2156
2157
2158
2159QByteArray QProcess::readAllStandardError()
2163 if (d->processChannelMode == MergedChannels) {
2164 qWarning(
"QProcess::readAllStandardError: Called with MergedChannels");
2166 ProcessChannel tmp = readChannel();
2167 setReadChannel(StandardError);
2169 setReadChannel(tmp);
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213void QProcess::start(
const QString &program,
const QStringList &arguments, OpenMode mode)
2216 if (d->processState != NotRunning) {
2217 qWarning(
"QProcess::start: Process is already running");
2220 if (program.isEmpty()) {
2221 d->setErrorAndEmit(QProcess::FailedToStart, tr(
"No program defined"));
2225 d->program = program;
2226 d->arguments = arguments;
2232
2233
2234
2235
2236
2237
2238
2239
2240void QProcess::start(OpenMode mode)
2243 if (d->processState != NotRunning) {
2244 qWarning(
"QProcess::start: Process is already running");
2247 if (d->program.isEmpty()) {
2248 d->setErrorAndEmit(QProcess::FailedToStart, tr(
"No program defined"));
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289void QProcess::startCommand(
const QString &command, OpenMode mode)
2291 QStringList args = splitCommand(command);
2292 if (args.isEmpty()) {
2293 qWarning(
"QProcess::startCommand: empty or whitespace-only command was provided");
2296 const QString program = args.takeFirst();
2297 start(program, args, mode);
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347bool QProcess::startDetached(qint64 *pid)
2350 if (d->processState != NotRunning) {
2351 qWarning(
"QProcess::startDetached: Process is already running");
2354 if (d->program.isEmpty()) {
2355 d->setErrorAndEmit(QProcess::FailedToStart, tr(
"No program defined"));
2358 return d->startDetached(pid);
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372bool QProcess::open(OpenMode mode)
2375 if (d->processState != NotRunning) {
2376 qWarning(
"QProcess::start: Process is already running");
2379 if (d->program.isEmpty()) {
2380 qWarning(
"QProcess::start: program not set");
2388void QProcessPrivate::start(QIODevice::OpenMode mode)
2391#if defined QPROCESS_DEBUG
2392 qDebug() <<
"QProcess::start(" << program <<
',' << arguments <<
',' << mode <<
')';
2395 if (stdinChannel.type != QProcessPrivate::Channel::Normal)
2396 mode &= ~QIODevice::WriteOnly;
2397 if (stdoutChannel.type != QProcessPrivate::Channel::Normal &&
2398 (stderrChannel.type != QProcessPrivate::Channel::Normal ||
2399 processChannelMode == QProcess::MergedChannels))
2400 mode &= ~QIODevice::ReadOnly;
2402 mode = QIODevice::Unbuffered;
2403 if ((mode & QIODevice::ReadOnly) == 0) {
2404 if (stdoutChannel.type == QProcessPrivate::Channel::Normal)
2405 q->setStandardOutputFile(q->nullDevice());
2406 if (stderrChannel.type == QProcessPrivate::Channel::Normal
2407 && processChannelMode != QProcess::MergedChannels)
2408 q->setStandardErrorFile(q->nullDevice());
2411 q->QIODevice::open(mode);
2413 if (q->isReadable() && processChannelMode != QProcess::MergedChannels)
2414 setReadChannelCount(2);
2416 stdinChannel.closed =
false;
2417 stdoutChannel.closed =
false;
2418 stderrChannel.closed =
false;
2421 exitStatus = QProcess::NormalExit;
2422 processError = QProcess::UnknownError;
2423 errorString.clear();
2429
2430
2431
2432
2433
2434
2435
2436
2442 bool inQuote =
false;
2447 for (
int i = 0; i < command.size(); ++i) {
2448 if (command.at(i) == u'"') {
2450 if (quoteCount == 3) {
2453 tmp += command.at(i);
2458 if (quoteCount == 1)
2462 if (!inQuote && command.at(i).isSpace()) {
2463 if (!tmp.isEmpty()) {
2468 tmp += command.at(i);
2477#if QT_CONFIG(process)
2479
2480
2481
2482
2483
2484
2485QString QProcess::program()
const
2487 Q_D(
const QProcess);
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504void QProcess::setProgram(
const QString &program)
2507 if (d->processState != NotRunning) {
2508 qWarning(
"QProcess::setProgram: Process is already running");
2511 d->program = program;
2515
2516
2517
2518
2519
2520
2521QStringList QProcess::arguments()
const
2523 Q_D(
const QProcess);
2524 return d->arguments;
2528
2529
2530
2531
2532
2533
2534
2535void QProcess::setArguments(
const QStringList &arguments)
2538 if (d->processState != NotRunning) {
2539 qWarning(
"QProcess::setProgram: Process is already running");
2542 d->arguments = arguments;
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561void QProcess::terminate()
2564 d->terminateProcess();
2568
2569
2570
2571
2572
2573
2574
2575void QProcess::kill()
2582
2583
2584
2585
2586int QProcess::exitCode()
const
2588 Q_D(
const QProcess);
2593
2594
2595
2596
2597
2598
2599
2600
2601QProcess::ExitStatus QProcess::exitStatus()
const
2603 Q_D(
const QProcess);
2604 return ExitStatus(d->exitStatus);
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624int QProcess::execute(
const QString &program,
const QStringList &arguments)
2627 process.setProcessChannelMode(ForwardedChannels);
2628 process.start(program, arguments);
2629 if (!process.waitForFinished(-1) || process.error() == FailedToStart)
2631 return process.exitStatus() == QProcess::NormalExit ? process.exitCode() : -1;
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653bool QProcess::startDetached(
const QString &program,
2654 const QStringList &arguments,
2655 const QString &workingDirectory,
2659 process.setProgram(program);
2660 process.setArguments(arguments);
2661 process.setWorkingDirectory(workingDirectory);
2662 return process.startDetached(pid);
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684QStringList QProcess::systemEnvironment()
2686 return QProcessEnvironment::systemEnvironment().toStringList();
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718QString QProcess::nullDevice()
2721 return QStringLiteral(
"\\\\.\\NUL");
2722#elif defined(_PATH_DEVNULL)
2723 return QStringLiteral(_PATH_DEVNULL);
2725 return QStringLiteral(
"/dev/null");
2733#if QT_CONFIG(process)
2734#include "moc_qprocess.cpp"
void insert(const QProcessEnvironmentPrivate &other)
bool comparesEqual(const QFileInfo &lhs, const QFileInfo &rhs)