1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Copyright (C) 2016 Intel Corporation.
5** Contact: https://www.qt.io/licensing/
6**
7** This file is part of the QtCore module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial License Usage
11** Licensees holding valid commercial Qt licenses may use this file in
12** accordance with the commercial license agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and The Qt Company. For licensing terms
15** and conditions see https://www.qt.io/terms-conditions. For further
16** information use the contact form at https://www.qt.io/contact-us.
17**
18** GNU Lesser General Public License Usage
19** Alternatively, this file may be used under the terms of the GNU Lesser
20** General Public License version 3 as published by the Free Software
21** Foundation and appearing in the file LICENSE.LGPL3 included in the
22** packaging of this file. Please review the following information to
23** ensure the GNU Lesser General Public License version 3 requirements
24** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25**
26** GNU General Public License Usage
27** Alternatively, this file may be used under the terms of the GNU
28** General Public License version 2.0 or (at your option) the GNU General
29** Public license version 3 or any later version approved by the KDE Free
30** Qt Foundation. The licenses are as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32** included in the packaging of this file. Please review the following
33** information to ensure the GNU General Public License requirements will
34** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35** https://www.gnu.org/licenses/gpl-3.0.html.
36**
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41//#define QPROCESS_DEBUG
42#include "qdebug.h"
43
44#if QT_CONFIG(process) && defined(QPROCESS_DEBUG)
45#include "private/qtools_p.h"
46#include <ctype.h>
47
48/*
49 Returns a human readable representation of the first \a len
50 characters in \a data.
51*/
52QT_BEGIN_NAMESPACE
53static QByteArray qt_prettyDebug(const char *data, int len, int maxSize)
54{
55 if (!data) return "(null)";
56 QByteArray out;
57 for (int i = 0; i < len; ++i) {
58 char c = data[i];
59 if (isprint(c)) {
60 out += c;
61 } else switch (c) {
62 case '\n': out += "\\n"; break;
63 case '\r': out += "\\r"; break;
64 case '\t': out += "\\t"; break;
65 default: {
66 const char buf[] = {
67 '\\',
68 QtMiscUtils::toOct(uchar(c) / 64),
69 QtMiscUtils::toOct(uchar(c) % 64 / 8),
70 QtMiscUtils::toOct(uchar(c) % 8),
71 0
72 };
73 out += buf;
74 }
75 }
76 }
77
78 if (len < maxSize)
79 out += "...";
80
81 return out;
82}
83QT_END_NAMESPACE
84#endif
85
86#include "qplatformdefs.h"
87
88#include "qprocess.h"
89#include "qprocess_p.h"
90#include "qstandardpaths.h"
91#include "private/qcore_unix_p.h"
92
93#ifdef Q_OS_MAC
94#include <private/qcore_mac_p.h>
95#endif
96
97#include <private/qcoreapplication_p.h>
98#include <private/qthread_p.h>
99#include <qfile.h>
100#include <qfileinfo.h>
101#include <qdir.h>
102#include <qlist.h>
103#include <qmutex.h>
104#include <qsocketnotifier.h>
105#include <qthread.h>
106#include <qelapsedtimer.h>
107
108#ifdef Q_OS_QNX
109# include <sys/neutrino.h>
110#endif
111
112#include <errno.h>
113#include <stdlib.h>
114#include <string.h>
115
116#if QT_CONFIG(process)
117#include <forkfd.h>
118#endif
119
120QT_BEGIN_NAMESPACE
121
122#if !defined(Q_OS_DARWIN)
123
124QT_BEGIN_INCLUDE_NAMESPACE
125extern char **environ;
126QT_END_INCLUDE_NAMESPACE
127
128QProcessEnvironment QProcessEnvironment::systemEnvironment()
129{
130 QProcessEnvironment env;
131 const char *entry;
132 for (int count = 0; (entry = environ[count]); ++count) {
133 const char *equal = strchr(entry, '=');
134 if (!equal)
135 continue;
136
137 QByteArray name(entry, equal - entry);
138 QByteArray value(equal + 1);
139 env.d->vars.insert(QProcessEnvironmentPrivate::Key(name),
140 QProcessEnvironmentPrivate::Value(value));
141 }
142 return env;
143}
144
145#endif // !defined(Q_OS_DARWIN)
146
147#if QT_CONFIG(process)
148
149namespace {
150struct QProcessPoller
151{
152 QProcessPoller(const QProcessPrivate &proc);
153
154 int poll(int timeout);
155
156 pollfd &stdinPipe() { return pfds[0]; }
157 pollfd &stdoutPipe() { return pfds[1]; }
158 pollfd &stderrPipe() { return pfds[2]; }
159 pollfd &forkfd() { return pfds[3]; }
160 pollfd &childStartedPipe() { return pfds[4]; }
161
162 enum { n_pfds = 5 };
163 pollfd pfds[n_pfds];
164};
165
166QProcessPoller::QProcessPoller(const QProcessPrivate &proc)
167{
168 for (int i = 0; i < n_pfds; i++)
169 pfds[i] = qt_make_pollfd(-1, POLLIN);
170
171 stdoutPipe().fd = proc.stdoutChannel.pipe[0];
172 stderrPipe().fd = proc.stderrChannel.pipe[0];
173
174 if (!proc.writeBuffer.isEmpty()) {
175 stdinPipe().fd = proc.stdinChannel.pipe[1];
176 stdinPipe().events = POLLOUT;
177 }
178
179 forkfd().fd = proc.forkfd;
180
181 if (proc.processState == QProcess::Starting)
182 childStartedPipe().fd = proc.childStartedPipe[0];
183}
184
185int QProcessPoller::poll(int timeout)
186{
187 const nfds_t nfds = (childStartedPipe().fd == -1) ? 4 : 5;
188 return qt_poll_msecs(pfds, nfds, timeout);
189}
190} // anonymous namespace
191
192static bool qt_pollfd_check(const pollfd &pfd, short revents)
193{
194 return pfd.fd >= 0 && (pfd.revents & (revents | POLLHUP | POLLERR | POLLNVAL)) != 0;
195}
196
197static int qt_create_pipe(int *pipe)
198{
199 if (pipe[0] != -1)
200 qt_safe_close(pipe[0]);
201 if (pipe[1] != -1)
202 qt_safe_close(pipe[1]);
203 int pipe_ret = qt_safe_pipe(pipe);
204 if (pipe_ret != 0) {
205 qErrnoWarning("QProcessPrivate::createPipe: Cannot create pipe %p", pipe);
206 }
207 return pipe_ret;
208}
209
210void QProcessPrivate::destroyPipe(int *pipe)
211{
212 if (pipe[1] != -1) {
213 qt_safe_close(pipe[1]);
214 pipe[1] = -1;
215 }
216 if (pipe[0] != -1) {
217 qt_safe_close(pipe[0]);
218 pipe[0] = -1;
219 }
220}
221
222void QProcessPrivate::closeChannel(Channel *channel)
223{
224 destroyPipe(channel->pipe);
225}
226
227/*
228 Create the pipes to a QProcessPrivate::Channel.
229
230 This function must be called in order: stdin, stdout, stderr
231*/
232bool QProcessPrivate::openChannel(Channel &channel)
233{
234 Q_Q(QProcess);
235
236 if (&channel == &stderrChannel && processChannelMode == QProcess::MergedChannels) {
237 channel.pipe[0] = -1;
238 channel.pipe[1] = -1;
239 return true;
240 }
241
242 if (channel.type == Channel::Normal) {
243 // we're piping this channel to our own process
244 if (qt_create_pipe(channel.pipe) != 0)
245 return false;
246
247 // create the socket notifiers
248 if (threadData->hasEventDispatcher()) {
249 if (&channel == &stdinChannel) {
250 channel.notifier = new QSocketNotifier(channel.pipe[1],
251 QSocketNotifier::Write, q);
252 channel.notifier->setEnabled(false);
253 QObject::connect(channel.notifier, SIGNAL(activated(int)),
254 q, SLOT(_q_canWrite()));
255 } else {
256 channel.notifier = new QSocketNotifier(channel.pipe[0],
257 QSocketNotifier::Read, q);
258 const char *receiver;
259 if (&channel == &stdoutChannel)
260 receiver = SLOT(_q_canReadStandardOutput());
261 else
262 receiver = SLOT(_q_canReadStandardError());
263 QObject::connect(channel.notifier, SIGNAL(activated(int)),
264 q, receiver);
265 }
266 }
267
268 return true;
269 } else if (channel.type == Channel::Redirect) {
270 // we're redirecting the channel to/from a file
271 QByteArray fname = QFile::encodeName(channel.file);
272
273 if (&channel == &stdinChannel) {
274 // try to open in read-only mode
275 channel.pipe[1] = -1;
276 if ( (channel.pipe[0] = qt_safe_open(fname, O_RDONLY)) != -1)
277 return true; // success
278 setErrorAndEmit(QProcess::FailedToStart,
279 QProcess::tr("Could not open input redirection for reading"));
280 } else {
281 int mode = O_WRONLY | O_CREAT;
282 if (channel.append)
283 mode |= O_APPEND;
284 else
285 mode |= O_TRUNC;
286
287 channel.pipe[0] = -1;
288 if ( (channel.pipe[1] = qt_safe_open(fname, mode, 0666)) != -1)
289 return true; // success
290
291 setErrorAndEmit(QProcess::FailedToStart,
292 QProcess::tr("Could not open input redirection for reading"));
293 }
294 cleanup();
295 return false;
296 } else {
297 Q_ASSERT_X(channel.process, "QProcess::start", "Internal error");
298
299 Channel *source;
300 Channel *sink;
301
302 if (channel.type == Channel::PipeSource) {
303 // we are the source
304 source = &channel;
305 sink = &channel.process->stdinChannel;
306
307 Q_ASSERT(source == &stdoutChannel);
308 Q_ASSERT(sink->process == this && sink->type == Channel::PipeSink);
309 } else {
310 // we are the sink;
311 source = &channel.process->stdoutChannel;
312 sink = &channel;
313
314 Q_ASSERT(sink == &stdinChannel);
315 Q_ASSERT(source->process == this && source->type == Channel::PipeSource);
316 }
317
318 if (source->pipe[1] != INVALID_Q_PIPE || sink->pipe[0] != INVALID_Q_PIPE) {
319 // already created, do nothing
320 return true;
321 } else {
322 Q_ASSERT(source->pipe[0] == INVALID_Q_PIPE && source->pipe[1] == INVALID_Q_PIPE);
323 Q_ASSERT(sink->pipe[0] == INVALID_Q_PIPE && sink->pipe[1] == INVALID_Q_PIPE);
324
325 Q_PIPE pipe[2] = { -1, -1 };
326 if (qt_create_pipe(pipe) != 0)
327 return false;
328 sink->pipe[0] = pipe[0];
329 source->pipe[1] = pipe[1];
330
331 return true;
332 }
333 }
334}
335
336static char **_q_dupEnvironment(const QProcessEnvironmentPrivate::Map &environment, int *envc)
337{
338 *envc = 0;
339 if (environment.isEmpty())
340 return 0;
341
342 char **envp = new char *[environment.count() + 2];
343 envp[environment.count()] = 0;
344 envp[environment.count() + 1] = 0;
345
346 auto it = environment.constBegin();
347 const auto end = environment.constEnd();
348 for ( ; it != end; ++it) {
349 QByteArray key = it.key();
350 QByteArray value = it.value().bytes();
351 key.reserve(key.length() + 1 + value.length());
352 key.append('=');
353 key.append(value);
354
355 envp[(*envc)++] = ::strdup(key.constData());
356 }
357
358 return envp;
359}
360
361void QProcessPrivate::startProcess()
362{
363 Q_Q(QProcess);
364
365#if defined (QPROCESS_DEBUG)
366 qDebug("QProcessPrivate::startProcess()");
367#endif
368
369 // Initialize pipes
370 if (!openChannel(stdinChannel) ||
371 !openChannel(stdoutChannel) ||
372 !openChannel(stderrChannel) ||
373 qt_create_pipe(childStartedPipe) != 0) {
374 setErrorAndEmit(QProcess::FailedToStart, qt_error_string(errno));
375 cleanup();
376 return;
377 }
378
379 if (threadData->hasEventDispatcher()) {
380 startupSocketNotifier = new QSocketNotifier(childStartedPipe[0],
381 QSocketNotifier::Read, q);
382 QObject::connect(startupSocketNotifier, SIGNAL(activated(int)),
383 q, SLOT(_q_startupNotification()));
384 }
385
386 // Start the process (platform dependent)
387 q->setProcessState(QProcess::Starting);
388
389 // Create argument list with right number of elements, and set the final
390 // one to 0.
391 char **argv = new char *[arguments.count() + 2];
392 argv[arguments.count() + 1] = 0;
393
394 // Encode the program name.
395 QByteArray encodedProgramName = QFile::encodeName(program);
396#ifdef Q_OS_MAC
397 // allow invoking of .app bundles on the Mac.
398 QFileInfo fileInfo(program);
399 if (encodedProgramName.endsWith(".app") && fileInfo.isDir()) {
400 QCFType<CFURLRef> url = CFURLCreateWithFileSystemPath(0,
401 QCFString(fileInfo.absoluteFilePath()),
402 kCFURLPOSIXPathStyle, true);
403 {
404 // CFBundle is not reentrant, since CFBundleCreate might return a reference
405 // to a cached bundle object. Protect the bundle calls with a mutex lock.
406 static QBasicMutex cfbundleMutex;
407 QMutexLocker lock(&cfbundleMutex);
408 QCFType<CFBundleRef> bundle = CFBundleCreate(0, url);
409 // 'executableURL' can be either relative or absolute ...
410 QCFType<CFURLRef> executableURL = CFBundleCopyExecutableURL(bundle);
411 // not to depend on caching - make sure it's always absolute.
412 url = CFURLCopyAbsoluteURL(executableURL);
413 }
414 if (url) {
415 const QCFString str = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
416 encodedProgramName += (QDir::separator() + QDir(program).relativeFilePath(QString::fromCFString(str))).toUtf8();
417 }
418 }
419#endif
420
421 // Add the program name to the argument list.
422 argv[0] = nullptr;
423 if (!program.contains(QLatin1Char('/'))) {
424 const QString &exeFilePath = QStandardPaths::findExecutable(program);
425 if (!exeFilePath.isEmpty()) {
426 const QByteArray &tmp = QFile::encodeName(exeFilePath);
427 argv[0] = ::strdup(tmp.constData());
428 }
429 }
430 if (!argv[0])
431 argv[0] = ::strdup(encodedProgramName.constData());
432
433 // Add every argument to the list
434 for (int i = 0; i < arguments.count(); ++i)
435 argv[i + 1] = ::strdup(QFile::encodeName(arguments.at(i)).constData());
436
437 // Duplicate the environment.
438 int envc = 0;
439 char **envp = 0;
440 if (environment.d.constData()) {
441 envp = _q_dupEnvironment(environment.d.constData()->vars, &envc);
442 }
443
444 // Encode the working directory if it's non-empty, otherwise just pass 0.
445 const char *workingDirPtr = 0;
446 QByteArray encodedWorkingDirectory;
447 if (!workingDirectory.isEmpty()) {
448 encodedWorkingDirectory = QFile::encodeName(workingDirectory);
449 workingDirPtr = encodedWorkingDirectory.constData();
450 }
451
452 // Start the process manager, and fork off the child process.
453 pid_t childPid;
454 forkfd = ::forkfd(FFD_CLOEXEC, &childPid);
455 int lastForkErrno = errno;
456 if (forkfd != FFD_CHILD_PROCESS) {
457 // Parent process.
458 // Clean up duplicated memory.
459 for (int i = 0; i <= arguments.count(); ++i)
460 free(argv[i]);
461 for (int i = 0; i < envc; ++i)
462 free(envp[i]);
463 delete [] argv;
464 delete [] envp;
465 }
466
467 // On QNX, if spawnChild failed, childPid will be -1 but forkfd is still 0.
468 // This is intentional because we only want to handle failure to fork()
469 // here, which is a rare occurrence. Handling of the failure to start is
470 // done elsewhere.
471 if (forkfd == -1) {
472 // Cleanup, report error and return
473#if defined (QPROCESS_DEBUG)
474 qDebug("fork failed: %ls", qUtf16Printable(qt_error_string(lastForkErrno)));
475#endif
476 q->setProcessState(QProcess::NotRunning);
477 setErrorAndEmit(QProcess::FailedToStart,
478 QProcess::tr("Resource error (fork failure): %1").arg(qt_error_string(lastForkErrno)));
479 cleanup();
480 return;
481 }
482
483 // Start the child.
484 if (forkfd == FFD_CHILD_PROCESS) {
485 execChild(workingDirPtr, argv, envp);
486 ::_exit(-1);
487 }
488
489 pid = Q_PID(childPid);
490
491 // parent
492 // close the ends we don't use and make all pipes non-blocking
493 qt_safe_close(childStartedPipe[1]);
494 childStartedPipe[1] = -1;
495
496 if (stdinChannel.pipe[0] != -1) {
497 qt_safe_close(stdinChannel.pipe[0]);
498 stdinChannel.pipe[0] = -1;
499 }
500
501 if (stdinChannel.pipe[1] != -1)
502 ::fcntl(stdinChannel.pipe[1], F_SETFL, ::fcntl(stdinChannel.pipe[1], F_GETFL) | O_NONBLOCK);
503
504 if (stdoutChannel.pipe[1] != -1) {
505 qt_safe_close(stdoutChannel.pipe[1]);
506 stdoutChannel.pipe[1] = -1;
507 }
508
509 if (stdoutChannel.pipe[0] != -1)
510 ::fcntl(stdoutChannel.pipe[0], F_SETFL, ::fcntl(stdoutChannel.pipe[0], F_GETFL) | O_NONBLOCK);
511
512 if (stderrChannel.pipe[1] != -1) {
513 qt_safe_close(stderrChannel.pipe[1]);
514 stderrChannel.pipe[1] = -1;
515 }
516 if (stderrChannel.pipe[0] != -1)
517 ::fcntl(stderrChannel.pipe[0], F_SETFL, ::fcntl(stderrChannel.pipe[0], F_GETFL) | O_NONBLOCK);
518
519 if (threadData->eventDispatcher.loadAcquire()) {
520 deathNotifier = new QSocketNotifier(forkfd, QSocketNotifier::Read, q);
521 QObject::connect(deathNotifier, SIGNAL(activated(int)),
522 q, SLOT(_q_processDied()));
523 }
524}
525
526struct ChildError
527{
528 int code;
529 char function[8];
530};
531
532void QProcessPrivate::execChild(const char *workingDir, char **argv, char **envp)
533{
534 ::signal(SIGPIPE, SIG_DFL); // reset the signal that we ignored
535
536 Q_Q(QProcess);
537 ChildError error = { 0, {} }; // force zeroing of function[8]
538
539 // copy the stdin socket if asked to (without closing on exec)
540 if (inputChannelMode != QProcess::ForwardedInputChannel)
541 qt_safe_dup2(stdinChannel.pipe[0], STDIN_FILENO, 0);
542
543 // copy the stdout and stderr if asked to
544 if (processChannelMode != QProcess::ForwardedChannels) {
545 if (processChannelMode != QProcess::ForwardedOutputChannel)
546 qt_safe_dup2(stdoutChannel.pipe[1], STDOUT_FILENO, 0);
547
548 // merge stdout and stderr if asked to
549 if (processChannelMode == QProcess::MergedChannels) {
550 qt_safe_dup2(STDOUT_FILENO, STDERR_FILENO, 0);
551 } else if (processChannelMode != QProcess::ForwardedErrorChannel) {
552 qt_safe_dup2(stderrChannel.pipe[1], STDERR_FILENO, 0);
553 }
554 }
555
556 // make sure this fd is closed if execv() succeeds
557 qt_safe_close(childStartedPipe[0]);
558
559 // enter the working directory
560 if (workingDir && QT_CHDIR(workingDir) == -1) {
561 // failed, stop the process
562 strcpy(error.function, "chdir");
563 goto report_errno;
564 }
565
566 // this is a virtual call, and it base behavior is to do nothing.
567 q->setupChildProcess();
568
569 // execute the process
570 if (!envp) {
571 qt_safe_execv(argv[0], argv);
572 strcpy(error.function, "execvp");
573 } else {
574#if defined (QPROCESS_DEBUG)
575 fprintf(stderr, "QProcessPrivate::execChild() starting %s\n", argv[0]);
576#endif
577 qt_safe_execve(argv[0], argv, envp);
578 strcpy(error.function, "execve");
579 }
580
581 // notify failure
582 // don't use strerror or any other routines that may allocate memory, since
583 // some buggy libc versions can deadlock on locked mutexes.
584report_errno:
585 error.code = errno;
586 qt_safe_write(childStartedPipe[1], &error, sizeof(error));
587 childStartedPipe[1] = -1;
588}
589
590bool QProcessPrivate::processStarted(QString *errorMessage)
591{
592 ChildError buf;
593 int ret = qt_safe_read(childStartedPipe[0], &buf, sizeof(buf));
594
595 if (startupSocketNotifier) {
596 startupSocketNotifier->setEnabled(false);
597 startupSocketNotifier->deleteLater();
598 startupSocketNotifier = 0;
599 }
600 qt_safe_close(childStartedPipe[0]);
601 childStartedPipe[0] = -1;
602
603#if defined (QPROCESS_DEBUG)
604 qDebug("QProcessPrivate::processStarted() == %s", i <= 0 ? "true" : "false");
605#endif
606
607 // did we read an error message?
608 if (ret > 0 && errorMessage)
609 *errorMessage = QLatin1String(buf.function) + QLatin1String(": ") + qt_error_string(buf.code);
610
611 return ret <= 0;
612}
613
614qint64 QProcessPrivate::bytesAvailableInChannel(const Channel *channel) const
615{
616 Q_ASSERT(channel->pipe[0] != INVALID_Q_PIPE);
617 int nbytes = 0;
618 qint64 available = 0;
619 if (::ioctl(channel->pipe[0], FIONREAD, (char *) &nbytes) >= 0)
620 available = (qint64) nbytes;
621#if defined (QPROCESS_DEBUG)
622 qDebug("QProcessPrivate::bytesAvailableInChannel(%d) == %lld", int(channel - &stdinChannel), available);
623#endif
624 return available;
625}
626
627qint64 QProcessPrivate::readFromChannel(const Channel *channel, char *data, qint64 maxlen)
628{
629 Q_ASSERT(channel->pipe[0] != INVALID_Q_PIPE);
630 qint64 bytesRead = qt_safe_read(channel->pipe[0], data, maxlen);
631#if defined QPROCESS_DEBUG
632 int save_errno = errno;
633 qDebug("QProcessPrivate::readFromChannel(%d, %p \"%s\", %lld) == %lld",
634 int(channel - &stdinChannel),
635 data, qt_prettyDebug(data, bytesRead, 16).constData(), maxlen, bytesRead);
636 errno = save_errno;
637#endif
638 if (bytesRead == -1 && errno == EWOULDBLOCK)
639 return -2;
640 return bytesRead;
641}
642
643bool QProcessPrivate::writeToStdin()
644{
645 const char *data = writeBuffer.readPointer();
646 const qint64 bytesToWrite = writeBuffer.nextDataBlockSize();
647
648 qint64 written = qt_safe_write_nosignal(stdinChannel.pipe[1], data, bytesToWrite);
649#if defined QPROCESS_DEBUG
650 qDebug("QProcessPrivate::writeToStdin(), write(%p \"%s\", %lld) == %lld",
651 data, qt_prettyDebug(data, bytesToWrite, 16).constData(), bytesToWrite, written);
652 if (written == -1)
653 qDebug("QProcessPrivate::writeToStdin(), failed to write (%ls)", qUtf16Printable(qt_error_string(errno)));
654#endif
655 if (written == -1) {
656 // If the O_NONBLOCK flag is set and If some data can be written without blocking
657 // the process, write() will transfer what it can and return the number of bytes written.
658 // Otherwise, it will return -1 and set errno to EAGAIN
659 if (errno == EAGAIN)
660 return true;
661
662 closeChannel(&stdinChannel);
663 setErrorAndEmit(QProcess::WriteError);
664 return false;
665 }
666 writeBuffer.free(written);
667 if (!emittedBytesWritten && written != 0) {
668 emittedBytesWritten = true;
669 emit q_func()->bytesWritten(written);
670 emittedBytesWritten = false;
671 }
672 return true;
673}
674
675void QProcessPrivate::terminateProcess()
676{
677#if defined (QPROCESS_DEBUG)
678 qDebug("QProcessPrivate::terminateProcess()");
679#endif
680 if (pid)
681 ::kill(pid_t(pid), SIGTERM);
682}
683
684void QProcessPrivate::killProcess()
685{
686#if defined (QPROCESS_DEBUG)
687 qDebug("QProcessPrivate::killProcess()");
688#endif
689 if (pid)
690 ::kill(pid_t(pid), SIGKILL);
691}
692
693bool QProcessPrivate::waitForStarted(int msecs)
694{
695#if defined (QPROCESS_DEBUG)
696 qDebug("QProcessPrivate::waitForStarted(%d) waiting for child to start (fd = %d)", msecs,
697 childStartedPipe[0]);
698#endif
699
700 pollfd pfd = qt_make_pollfd(childStartedPipe[0], POLLIN);
701
702 if (qt_poll_msecs(&pfd, 1, msecs) == 0) {
703 setError(QProcess::Timedout);
704#if defined (QPROCESS_DEBUG)
705 qDebug("QProcessPrivate::waitForStarted(%d) == false (timed out)", msecs);
706#endif
707 return false;
708 }
709
710 bool startedEmitted = _q_startupNotification();
711#if defined (QPROCESS_DEBUG)
712 qDebug("QProcessPrivate::waitForStarted() == %s", startedEmitted ? "true" : "false");
713#endif
714 return startedEmitted;
715}
716
717bool QProcessPrivate::waitForReadyRead(int msecs)
718{
719#if defined (QPROCESS_DEBUG)
720 qDebug("QProcessPrivate::waitForReadyRead(%d)", msecs);
721#endif
722
723 QElapsedTimer stopWatch;
724 stopWatch.start();
725
726 forever {
727 QProcessPoller poller(*this);
728
729 int timeout = qt_subtract_from_timeout(msecs, stopWatch.elapsed());
730 int ret = poller.poll(timeout);
731
732 if (ret < 0) {
733 break;
734 }
735 if (ret == 0) {
736 setError(QProcess::Timedout);
737 return false;
738 }
739
740 if (qt_pollfd_check(poller.childStartedPipe(), POLLIN)) {
741 if (!_q_startupNotification())
742 return false;
743 }
744
745 bool readyReadEmitted = false;
746 if (qt_pollfd_check(poller.stdoutPipe(), POLLIN)) {
747 bool canRead = _q_canReadStandardOutput();
748 if (currentReadChannel == QProcess::StandardOutput && canRead)
749 readyReadEmitted = true;
750 }
751 if (qt_pollfd_check(poller.stderrPipe(), POLLIN)) {
752 bool canRead = _q_canReadStandardError();
753 if (currentReadChannel == QProcess::StandardError && canRead)
754 readyReadEmitted = true;
755 }
756 if (readyReadEmitted)
757 return true;
758
759 if (qt_pollfd_check(poller.stdinPipe(), POLLOUT))
760 _q_canWrite();
761
762 // Signals triggered by I/O may have stopped this process:
763 if (processState == QProcess::NotRunning)
764 return false;
765
766 if (qt_pollfd_check(poller.forkfd(), POLLIN)) {
767 if (_q_processDied())
768 return false;
769 }
770 }
771 return false;
772}
773
774bool QProcessPrivate::waitForBytesWritten(int msecs)
775{
776#if defined (QPROCESS_DEBUG)
777 qDebug("QProcessPrivate::waitForBytesWritten(%d)", msecs);
778#endif
779
780 QElapsedTimer stopWatch;
781 stopWatch.start();
782
783 while (!writeBuffer.isEmpty()) {
784 QProcessPoller poller(*this);
785
786 int timeout = qt_subtract_from_timeout(msecs, stopWatch.elapsed());
787 int ret = poller.poll(timeout);
788
789 if (ret < 0) {
790 break;
791 }
792
793 if (ret == 0) {
794 setError(QProcess::Timedout);
795 return false;
796 }
797
798 if (qt_pollfd_check(poller.childStartedPipe(), POLLIN)) {
799 if (!_q_startupNotification())
800 return false;
801 }
802
803 if (qt_pollfd_check(poller.stdinPipe(), POLLOUT))
804 return _q_canWrite();
805
806 if (qt_pollfd_check(poller.stdoutPipe(), POLLIN))
807 _q_canReadStandardOutput();
808
809 if (qt_pollfd_check(poller.stderrPipe(), POLLIN))
810 _q_canReadStandardError();
811
812 // Signals triggered by I/O may have stopped this process:
813 if (processState == QProcess::NotRunning)
814 return false;
815
816 if (qt_pollfd_check(poller.forkfd(), POLLIN)) {
817 if (_q_processDied())
818 return false;
819 }
820 }
821
822 return false;
823}
824
825bool QProcessPrivate::waitForFinished(int msecs)
826{
827#if defined (QPROCESS_DEBUG)
828 qDebug("QProcessPrivate::waitForFinished(%d)", msecs);
829#endif
830
831 QElapsedTimer stopWatch;
832 stopWatch.start();
833
834 forever {
835 QProcessPoller poller(*this);
836
837 int timeout = qt_subtract_from_timeout(msecs, stopWatch.elapsed());
838 int ret = poller.poll(timeout);
839
840 if (ret < 0) {
841 break;
842 }
843 if (ret == 0) {
844 setError(QProcess::Timedout);
845 return false;
846 }
847
848 if (qt_pollfd_check(poller.childStartedPipe(), POLLIN)) {
849 if (!_q_startupNotification())
850 return false;
851 }
852 if (qt_pollfd_check(poller.stdinPipe(), POLLOUT))
853 _q_canWrite();
854
855 if (qt_pollfd_check(poller.stdoutPipe(), POLLIN))
856 _q_canReadStandardOutput();
857
858 if (qt_pollfd_check(poller.stderrPipe(), POLLIN))
859 _q_canReadStandardError();
860
861 // Signals triggered by I/O may have stopped this process:
862 if (processState == QProcess::NotRunning)
863 return true;
864
865 if (qt_pollfd_check(poller.forkfd(), POLLIN)) {
866 if (_q_processDied())
867 return true;
868 }
869 }
870 return false;
871}
872
873void QProcessPrivate::findExitCode()
874{
875}
876
877bool QProcessPrivate::waitForDeadChild()
878{
879 if (forkfd == -1)
880 return true; // child has already exited
881
882 // read the process information from our fd
883 forkfd_info info;
884 int ret;
885 EINTR_LOOP(ret, forkfd_wait(forkfd, &info, nullptr));
886
887 exitCode = info.status;
888 crashed = info.code != CLD_EXITED;
889
890 delete deathNotifier;
891 deathNotifier = 0;
892
893 EINTR_LOOP(ret, forkfd_close(forkfd));
894 forkfd = -1; // Child is dead, don't try to kill it anymore
895
896#if defined QPROCESS_DEBUG
897 qDebug() << "QProcessPrivate::waitForDeadChild() dead with exitCode"
898 << exitCode << ", crashed?" << crashed;
899#endif
900 return true;
901}
902
903bool QProcessPrivate::startDetached(qint64 *pid)
904{
905 QByteArray encodedWorkingDirectory = QFile::encodeName(workingDirectory);
906
907 // To catch the startup of the child
908 int startedPipe[2];
909 if (qt_safe_pipe(startedPipe) != 0)
910 return false;
911 // To communicate the pid of the child
912 int pidPipe[2];
913 if (qt_safe_pipe(pidPipe) != 0) {
914 qt_safe_close(startedPipe[0]);
915 qt_safe_close(startedPipe[1]);
916 return false;
917 }
918
919 if ((stdinChannel.type == Channel::Redirect && !openChannel(stdinChannel))
920 || (stdoutChannel.type == Channel::Redirect && !openChannel(stdoutChannel))
921 || (stderrChannel.type == Channel::Redirect && !openChannel(stderrChannel))) {
922 closeChannel(&stdinChannel);
923 closeChannel(&stdoutChannel);
924 closeChannel(&stderrChannel);
925 qt_safe_close(pidPipe[0]);
926 qt_safe_close(pidPipe[1]);
927 qt_safe_close(startedPipe[0]);
928 qt_safe_close(startedPipe[1]);
929 return false;
930 }
931
932 pid_t childPid = fork();
933 if (childPid == 0) {
934 struct sigaction noaction;
935 memset(&noaction, 0, sizeof(noaction));
936 noaction.sa_handler = SIG_IGN;
937 ::sigaction(SIGPIPE, &noaction, 0);
938
939 ::setsid();
940
941 qt_safe_close(startedPipe[0]);
942 qt_safe_close(pidPipe[0]);
943
944 pid_t doubleForkPid = fork();
945 if (doubleForkPid == 0) {
946 qt_safe_close(pidPipe[1]);
947
948 // copy the stdin socket if asked to (without closing on exec)
949 if (stdinChannel.type == Channel::Redirect)
950 qt_safe_dup2(stdinChannel.pipe[0], STDIN_FILENO, 0);
951
952 // copy the stdout and stderr if asked to
953 if (stdoutChannel.type == Channel::Redirect)
954 qt_safe_dup2(stdoutChannel.pipe[1], STDOUT_FILENO, 0);
955 if (stderrChannel.type == Channel::Redirect)
956 qt_safe_dup2(stderrChannel.pipe[1], STDERR_FILENO, 0);
957
958 if (!encodedWorkingDirectory.isEmpty()) {
959 if (QT_CHDIR(encodedWorkingDirectory.constData()) == -1)
960 qWarning("QProcessPrivate::startDetached: failed to chdir to %s", encodedWorkingDirectory.constData());
961 }
962
963 char **argv = new char *[arguments.size() + 2];
964 for (int i = 0; i < arguments.size(); ++i)
965 argv[i + 1] = ::strdup(QFile::encodeName(arguments.at(i)).constData());
966 argv[arguments.size() + 1] = 0;
967
968 // Duplicate the environment.
969 int envc = 0;
970 char **envp = nullptr;
971 if (environment.d.constData()) {
972 envp = _q_dupEnvironment(environment.d.constData()->vars, &envc);
973 }
974
975 QByteArray tmp;
976 if (!program.contains(QLatin1Char('/'))) {
977 const QString &exeFilePath = QStandardPaths::findExecutable(program);
978 if (!exeFilePath.isEmpty())
979 tmp = QFile::encodeName(exeFilePath);
980 }
981 if (tmp.isEmpty())
982 tmp = QFile::encodeName(program);
983 argv[0] = tmp.data();
984
985 if (envp)
986 qt_safe_execve(argv[0], argv, envp);
987 else
988 qt_safe_execv(argv[0], argv);
989
990 struct sigaction noaction;
991 memset(&noaction, 0, sizeof(noaction));
992 noaction.sa_handler = SIG_IGN;
993 ::sigaction(SIGPIPE, &noaction, 0);
994
995 // '\1' means execv failed
996 char c = '\1';
997 qt_safe_write(startedPipe[1], &c, 1);
998 qt_safe_close(startedPipe[1]);
999 ::_exit(1);
1000 } else if (doubleForkPid == -1) {
1001 struct sigaction noaction;
1002 memset(&noaction, 0, sizeof(noaction));
1003 noaction.sa_handler = SIG_IGN;
1004 ::sigaction(SIGPIPE, &noaction, 0);
1005
1006 // '\2' means internal error
1007 char c = '\2';
1008 qt_safe_write(startedPipe[1], &c, 1);
1009 }
1010
1011 qt_safe_close(startedPipe[1]);
1012 qt_safe_write(pidPipe[1], (const char *)&doubleForkPid, sizeof(pid_t));
1013 if (QT_CHDIR("/") == -1)
1014 qWarning("QProcessPrivate::startDetached: failed to chdir to /");
1015 ::_exit(1);
1016 }
1017
1018 closeChannel(&stdinChannel);
1019 closeChannel(&stdoutChannel);
1020 closeChannel(&stderrChannel);
1021 qt_safe_close(startedPipe[1]);
1022 qt_safe_close(pidPipe[1]);
1023
1024 if (childPid == -1) {
1025 qt_safe_close(startedPipe[0]);
1026 qt_safe_close(pidPipe[0]);
1027 return false;
1028 }
1029
1030 char reply = '\0';
1031 int startResult = qt_safe_read(startedPipe[0], &reply, 1);
1032 int result;
1033 qt_safe_close(startedPipe[0]);
1034 qt_safe_waitpid(childPid, &result, 0);
1035 bool success = (startResult != -1 && reply == '\0');
1036 if (success && pid) {
1037 pid_t actualPid = 0;
1038 if (qt_safe_read(pidPipe[0], (char *)&actualPid, sizeof(pid_t)) == sizeof(pid_t)) {
1039 *pid = actualPid;
1040 } else {
1041 *pid = 0;
1042 }
1043 }
1044 qt_safe_close(pidPipe[0]);
1045 return success;
1046}
1047
1048#endif // QT_CONFIG(process)
1049
1050QT_END_NAMESPACE
1051