/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Copyright (C) 2016 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

//#define QPROCESS_DEBUG

#include <qdebug.h>
#include <qdir.h>
#include <qscopedvaluerollback.h>
#if defined(Q_OS_WIN)
#include <qtimer.h>
#endif
#if defined QPROCESS_DEBUG
#include <qstring.h>
#include <ctype.h>

QT_BEGIN_NAMESPACE
/*
    Returns a human readable representation of the first \a len
    characters in \a data.
*/
static QByteArray qt_prettyDebug(const char *data, int len, int maxSize)
{
    if (!data) return "(null)";
    QByteArray out;
    for (int i = 0; i < len && i < maxSize; ++i) {
        char c = data[i];
        if (isprint(c)) {
            out += c;
        } else switch (c) {
        case '\n': out += "\\n"; break;
        case '\r': out += "\\r"; break;
        case '\t': out += "\\t"; break;
        default:
            char buf[5];
            qsnprintf(buf, sizeof(buf), "\\%3o", c);
            buf[4] = '\0';
            out += QByteArray(buf);
        }
    }

    if (len < maxSize)
        out += "...";

    return out;
}

QT_END_NAMESPACE

#endif

#include "qprocess.h"
#include "qprocess_p.h"

#include <qbytearray.h>
#include <qelapsedtimer.h>
#include <qcoreapplication.h>
#include <qsocketnotifier.h>
#include <qtimer.h>

#ifdef Q_OS_WIN
#include <qwineventnotifier.h>
#else
#include <private/qcore_unix_p.h>
#endif

#if __has_include(<paths.h>)
#include <paths.h>
#endif

QT_BEGIN_NAMESPACE

/*!
    \since 5.6

    \macro QT_NO_PROCESS_COMBINED_ARGUMENT_START
    \relates QProcess

    Disables the
    \l {QProcess::start(const QString &, QIODevice::OpenMode)}
    {QProcess::start}() overload taking a single string.
    In most cases where it is used, the user intends for the first argument
    to be treated atomically as per the other overload.

    \sa QProcess::start(const QString &command, QIODevice::OpenMode mode)
*/

/*!
    \class QProcessEnvironment
    \inmodule QtCore

    \brief The QProcessEnvironment class holds the environment variables that
    can be passed to a program.

    \ingroup io
    \ingroup misc
    \ingroup shared
    \reentrant
    \since 4.6

    A process's environment is composed of a set of key=value pairs known as
    environment variables. The QProcessEnvironment class wraps that concept
    and allows easy manipulation of those variables. It's meant to be used
    along with QProcess, to set the environment for child processes. It
    cannot be used to change the current process's environment.

    The environment of the calling process can be obtained using
    QProcessEnvironment::systemEnvironment().

    On Unix systems, the variable names are case-sensitive. Note that the
    Unix environment allows both variable names and contents to contain arbitrary
    binary data (except for the NUL character). QProcessEnvironment will preserve
    such variables, but does not support manipulating variables whose names or
    values cannot be encoded by the current locale settings (see
    QTextCodec::codecForLocale).

    On Windows, the variable names are case-insensitive, but case-preserving.
    QProcessEnvironment behaves accordingly.

    \sa QProcess, QProcess::systemEnvironment(), QProcess::setProcessEnvironment()
*/

QStringList QProcessEnvironmentPrivate::toList() const
{
    QStringList result;
    result.reserve(vars.size());
    for (auto it = vars.cbegin(), end = vars.cend(); it != end; ++it)
        result << nameToString(it.key()) + QLatin1Char('=') + valueToString(it.value());
    return result;
}

QProcessEnvironment QProcessEnvironmentPrivate::fromList(const QStringList &list)
{
    QProcessEnvironment env;
    QStringList::ConstIterator it = list.constBegin(),
                              end = list.constEnd();
    for ( ; it != end; ++it) {
        int pos = it->indexOf(QLatin1Char('='), 1);
        if (pos < 1)
            continue;

        QString value = it->mid(pos + 1);
        QString name = *it;
        name.truncate(pos);
        env.insert(name, value);
    }
    return env;
}

QStringList QProcessEnvironmentPrivate::keys() const
{
    QStringList result;
    result.reserve(vars.size());
    auto it = vars.constBegin();
    const auto end = vars.constEnd();
    for ( ; it != end; ++it)
        result << nameToString(it.key());
    return result;
}

void QProcessEnvironmentPrivate::insert(const QProcessEnvironmentPrivate &other)
{
    auto it = other.vars.constBegin();
    const auto end = other.vars.constEnd();
    for ( ; it != end; ++it)
        vars.insert(it.key(), it.value());

#ifdef Q_OS_UNIX
    const OrderedNameMapMutexLocker locker(this, &other);
    auto nit = other.nameMap.constBegin();
    const auto nend = other.nameMap.constEnd();
    for ( ; nit != nend; ++nit)
        nameMap.insert(nit.key(), nit.value());
#endif
}

/*!
    Creates a new QProcessEnvironment object. This constructor creates an
    empty environment. If set on a QProcess, this will cause the current
    environment variables to be removed.
*/
QProcessEnvironment::QProcessEnvironment()
    : d(0)
{
}

/*!
    Frees the resources associated with this QProcessEnvironment object.
*/
QProcessEnvironment::~QProcessEnvironment()
{
}

/*!
    Creates a QProcessEnvironment object that is a copy of \a other.
*/
QProcessEnvironment::QProcessEnvironment(const QProcessEnvironment &other)
    : d(other.d)
{
}

/*!
    Copies the contents of the \a other QProcessEnvironment object into this
    one.
*/
QProcessEnvironment &QProcessEnvironment::operator=(const QProcessEnvironment &other)
{
    d = other.d;
    return *this;
}

/*!
    \fn void QProcessEnvironment::swap(QProcessEnvironment &other)
    \since 5.0

    Swaps this process environment instance with \a other. This
    function is very fast and never fails.
*/

/*!
    \fn bool QProcessEnvironment::operator !=(const QProcessEnvironment &other) const

    Returns \c true if this and the \a other QProcessEnvironment objects are different.

    \sa operator==()
*/

/*!
    Returns \c true if this and the \a other QProcessEnvironment objects are equal.

    Two QProcessEnvironment objects are considered equal if they have the same
    set of key=value pairs. The comparison of keys is done case-sensitive on
    platforms where the environment is case-sensitive.

    \sa operator!=(), contains()
*/
bool QProcessEnvironment::operator==(const QProcessEnvironment &other) const
{
    if (d == other.d)
        return true;
    if (d) {
        if (other.d) {
            return d->vars == other.d->vars;
        } else {
            return isEmpty();
        }
    } else {
        return other.isEmpty();
    }
}

/*!
    Returns \c true if this QProcessEnvironment object is empty: that is
    there are no key=value pairs set.

    \sa clear(), systemEnvironment(), insert()
*/
bool QProcessEnvironment::isEmpty() const
{
    // Needs no locking, as no hash nodes are accessed
    return d ? d->vars.isEmpty() : true;
}

/*!
    Removes all key=value pairs from this QProcessEnvironment object, making
    it empty.

    \sa isEmpty(), systemEnvironment()
*/
void QProcessEnvironment::clear()
{
    if (d)
        d->vars.clear();
    // Unix: Don't clear d->nameMap, as the environment is likely to be
    // re-populated with the same keys again.
}

/*!
    Returns \c true if the environment variable of name \a name is found in
    this QProcessEnvironment object.


    \sa insert(), value()
*/
bool QProcessEnvironment::contains(const QString &name) const
{
    if (!d)
        return false;
    return d->vars.contains(d->prepareName(name));
}

/*!
    Inserts the environment variable of name \a name and contents \a value
    into this QProcessEnvironment object. If that variable already existed,
    it is replaced by the new value.

    On most systems, inserting a variable with no contents will have the
    same effect for applications as if the variable had not been set at all.
    However, to guarantee that there are no incompatibilities, to remove a
    variable, please use the remove() function.

    \sa contains(), remove(), value()
*/
void QProcessEnvironment::insert(const QString &name, const QString &value)
{
    // our re-impl of detach() detaches from null
    d.detach(); // detach before prepareName()
    d->vars.insert(d->prepareName(name), d->prepareValue(value));
}

/*!
    Removes the environment variable identified by \a name from this
    QProcessEnvironment object. If that variable did not exist before,
    nothing happens.


    \sa contains(), insert(), value()
*/
void QProcessEnvironment::remove(const QString &name)
{
    if (d) {
        d.detach(); // detach before prepareName()
        d->vars.remove(d->prepareName(name));
    }
}

/*!
    Searches this QProcessEnvironment object for a variable identified by
    \a name and returns its value. If the variable is not found in this object,
    then \a defaultValue is returned instead.

    \sa contains(), insert(), remove()
*/
QString QProcessEnvironment::value(const QString &name, const QString &defaultValue) const
{
    if (!d)
        return defaultValue;

    const auto it = d->vars.constFind(d->prepareName(name));
    if (it == d->vars.constEnd())
        return defaultValue;

    return d->valueToString(it.value());
}

/*!
    Converts this QProcessEnvironment object into a list of strings, one for
    each environment variable that is set. The environment variable's name
    and its value are separated by an equal character ('=').

    The QStringList contents returned by this function are suitable for
    presentation.
    Use with the QProcess::setEnvironment function is not recommended due to
    potential encoding problems under Unix, and worse performance.

    \sa systemEnvironment(), QProcess::systemEnvironment(),
        QProcess::setProcessEnvironment()
*/
QStringList QProcessEnvironment::toStringList() const
{
    if (!d)
        return QStringList();
    return d->toList();
}

/*!
    \since 4.8

    Returns a list containing all the variable names in this QProcessEnvironment
    object.
*/
QStringList QProcessEnvironment::keys() const
{
    if (!d)
        return QStringList();
    return d->keys();
}

/*!
    \overload
    \since 4.8

    Inserts the contents of \a e in this QProcessEnvironment object. Variables in
    this object that also exist in \a e will be overwritten.
*/
void QProcessEnvironment::insert(const QProcessEnvironment &e)
{
    if (!e.d)
        return;

    // our re-impl of detach() detaches from null
    d->insert(*e.d);
}

#if QT_CONFIG(process)

void QProcessPrivate::Channel::clear()
{
    switch (type) {
    case PipeSource:
        Q_ASSERT(process);
        process->stdinChannel.type = Normal;
        process->stdinChannel.process = 0;
        break;
    case PipeSink:
        Q_ASSERT(process);
        process->stdoutChannel.type = Normal;
        process->stdoutChannel.process = 0;
        break;
    }

    type = Normal;
    file.clear();
    process = 0;
}

/*!
    \class QProcess
    \inmodule QtCore

    \brief The QProcess class is used to start external programs and
    to communicate with them.

    \ingroup io

    \reentrant

    \section1 Running a Process

    To start a process, pass the name and command line arguments of
    the program you want to run as arguments to start(). Arguments
    are supplied as individual strings in a QStringList.

    Alternatively, you can set the program to run with setProgram()
    and setArguments(), and then call start() or open().

    For example, the following code snippet runs the analog clock
    example in the Fusion style on X11 platforms by passing strings
    containing "-style" and "fusion" as two items in the list of
    arguments:

    \snippet qprocess/qprocess-simpleexecution.cpp 0
    \dots
    \snippet qprocess/qprocess-simpleexecution.cpp 1
    \snippet qprocess/qprocess-simpleexecution.cpp 2

    QProcess then enters the \l Starting state, and when the program
    has started, QProcess enters the \l Running state and emits
    started().

    QProcess allows you to treat a process as a sequential I/O
    device. You can write to and read from the process just as you
    would access a network connection using QTcpSocket. You can then
    write to the process's standard input by calling write(), and
    read the standard output by calling read(), readLine(), and
    getChar(). Because it inherits QIODevice, QProcess can also be
    used as an input source for QXmlReader, or for generating data to
    be uploaded using QNetworkAccessManager.

    When the process exits, QProcess reenters the \l NotRunning state
    (the initial state), and emits finished().

    The finished() signal provides the exit code and exit status of
    the process as arguments, and you can also call exitCode() to
    obtain the exit code of the last process that finished, and
    exitStatus() to obtain its exit status. If an error occurs at
    any point in time, QProcess will emit the errorOccurred() signal.
    You can also call error() to find the type of error that occurred
    last, and state() to find the current process state.

    \note QProcess is not supported on VxWorks, iOS, tvOS, watchOS,
    or the Universal Windows Platform.

    \section1 Communicating via Channels

    Processes have two predefined output channels: The standard
    output channel (\c stdout) supplies regular console output, and
    the standard error channel (\c stderr) usually supplies the
    errors that are printed by the process. These channels represent
    two separate streams of data. You can toggle between them by
    calling setReadChannel(). QProcess emits readyRead() when data is
    available on the current read channel. It also emits
    readyReadStandardOutput() when new standard output data is
    available, and when new standard error data is available,
    readyReadStandardError() is emitted. Instead of calling read(),
    readLine(), or getChar(), you can explicitly read all data from
    either of the two channels by calling readAllStandardOutput() or
    readAllStandardError().

    The terminology for the channels can be misleading. Be aware that
    the process's output channels correspond to QProcess's
    \e read channels, whereas the process's input channels correspond
    to QProcess's \e write channels. This is because what we read
    using QProcess is the process's output, and what we write becomes
    the process's input.

    QProcess can merge the two output channels, so that standard
    output and standard error data from the running process both use
    the standard output channel. Call setProcessChannelMode() with
    MergedChannels before starting the process to activate
    this feature. You also have the option of forwarding the output of
    the running process to the calling, main process, by passing
    ForwardedChannels as the argument. It is also possible to forward
    only one of the output channels - typically one would use
    ForwardedErrorChannel, but ForwardedOutputChannel also exists.
    Note that using channel forwarding is typically a bad idea in GUI
    applications - you should present errors graphically instead.

    Certain processes need special environment settings in order to
    operate. You can set environment variables for your process by
    calling setProcessEnvironment(). To set a working directory, call
    setWorkingDirectory(). By default, processes are run in the
    current working directory of the calling process.

    The positioning and the screen Z-order of windows belonging to
    GUI applications started with QProcess are controlled by
    the underlying windowing system. For Qt 5 applications, the
    positioning can be specified using the \c{-qwindowgeometry}
    command line option; X11 applications generally accept a
    \c{-geometry} command line option.

    \note On QNX, setting the working directory may cause all
    application threads, with the exception of the QProcess caller
    thread, to temporarily freeze during the spawning process,
    owing to a limitation in the operating system.

    \section1 Synchronous Process API

    QProcess provides a set of functions which allow it to be used
    without an event loop, by suspending the calling thread until
    certain signals are emitted:

    \list
    \li waitForStarted() blocks until the process has started.

    \li waitForReadyRead() blocks until new data is
    available for reading on the current read channel.

    \li waitForBytesWritten() blocks until one payload of
    data has been written to the process.

    \li waitForFinished() blocks until the process has finished.
    \endlist

    Calling these functions from the main thread (the thread that
    calls QApplication::exec()) may cause your user interface to
    freeze.

    The following example runs \c gzip to compress the string "Qt
    rocks!", without an event loop:

    \snippet process/process.cpp 0

    \section1 Notes for Windows Users

    Some Windows commands (for example, \c dir) are not provided by
    separate applications, but by the command interpreter itself.
    If you attempt to use QProcess to execute these commands directly,
    it won't work. One possible solution is to execute the command
    interpreter itself (\c{cmd.exe} on some Windows systems), and ask
    the interpreter to execute the desired command.

    \sa QBuffer, QFile, QTcpSocket
*/

/*!
    \enum QProcess::ProcessChannel

    This enum describes the process channels used by the running process.
    Pass one of these values to setReadChannel() to set the
    current read channel of QProcess.

    \value StandardOutput The standard output (stdout) of the running
           process.

    \value StandardError The standard error (stderr) of the running
           process.

    \sa setReadChannel()
*/

/*!
    \enum QProcess::ProcessChannelMode

    This enum describes the process output channel modes of QProcess.
    Pass one of these values to setProcessChannelMode() to set the
    current read channel mode.

    \value SeparateChannels QProcess manages the output of the
    running process, keeping standard output and standard error data
    in separate internal buffers. You can select the QProcess's
    current read channel by calling setReadChannel(). This is the
    default channel mode of QProcess.

    \value MergedChannels QProcess merges the output of the running
    process into the standard output channel (\c stdout). The
    standard error channel (\c stderr) will not receive any data. The
    standard output and standard error data of the running process
    are interleaved.

    \value ForwardedChannels QProcess forwards the output of the
    running process onto the main process. Anything the child process
    writes to its standard output and standard error will be written
    to the standard output and standard error of the main process.

    \value ForwardedErrorChannel QProcess manages the standard output
    of the running process, but forwards its standard error onto the
    main process. This reflects the typical use of command line tools
    as filters, where the standard output is redirected to another
    process or a file, while standard error is printed to the console
    for diagnostic purposes.
    (This value was introduced in Qt 5.2.)

    \value ForwardedOutputChannel Complementary to ForwardedErrorChannel.
    (This value was introduced in Qt 5.2.)

    \note Windows intentionally suppresses output from GUI-only
    applications to inherited consoles.
    This does \e not apply to output redirected to files or pipes.
    To forward the output of GUI-only applications on the console
    nonetheless, you must use SeparateChannels and do the forwarding
    yourself by reading the output and writing it to the appropriate
    output channels.

    \sa setProcessChannelMode()
*/

/*!
    \enum QProcess::InputChannelMode
    \since 5.2

    This enum describes the process input channel modes of QProcess.
    Pass one of these values to setInputChannelMode() to set the
    current write channel mode.

    \value ManagedInputChannel QProcess manages the input of the running
    process. This is the default input channel mode of QProcess.

    \value ForwardedInputChannel QProcess forwards the input of the main
    process onto the running process. The child process reads its standard
    input from the same source as the main process.
    Note that the main process must not try to read its standard input
    while the child process is running.

    \sa setInputChannelMode()
*/

/*!
    \enum QProcess::ProcessError

    This enum describes the different types of errors that are
    reported by QProcess.

    \value FailedToStart The process failed to start. Either the
    invoked program is missing, or you may have insufficient
    permissions to invoke the program.

    \value Crashed The process crashed some time after starting
    successfully.

    \value Timedout The last waitFor...() function timed out. The
    state of QProcess is unchanged, and you can try calling
    waitFor...() again.

    \value WriteError An error occurred when attempting to write to the
    process. For example, the process may not be running, or it may
    have closed its input channel.

    \value ReadError An error occurred when attempting to read from
    the process. For example, the process may not be running.

    \value UnknownError An unknown error occurred. This is the default
    return value of error().

    \sa error()
*/

/*!
    \enum QProcess::ProcessState

    This enum describes the different states of QProcess.

    \value NotRunning The process is not running.

    \value Starting The process is starting, but the program has not
    yet been invoked.

    \value Running The process is running and is ready for reading and
    writing.

    \sa state()
*/

/*!
    \enum QProcess::ExitStatus

    This enum describes the different exit statuses of QProcess.

    \value NormalExit The process exited normally.

    \value CrashExit The process crashed.

    \sa exitStatus()
*/

/*!
    \typedef QProcess::CreateProcessArgumentModifier
    \note This typedef is only available on desktop Windows.

    On Windows, QProcess uses the Win32 API function \c CreateProcess to
    start child processes. While QProcess provides a comfortable way to start
    processes without worrying about platform
    details, it is in some cases desirable to fine-tune the parameters that are
    passed to \c CreateProcess. This is done by defining a
    \c CreateProcessArgumentModifier function and passing it to
    \c setCreateProcessArgumentsModifier.

    A \c CreateProcessArgumentModifier function takes one parameter: a pointer
    to a \c CreateProcessArguments struct. The members of this struct will be
    passed to \c CreateProcess after the \c CreateProcessArgumentModifier
    function is called.

    The following example demonstrates how to pass custom flags to
    \c CreateProcess.
    When starting a console process B from a console process A, QProcess will
    reuse the console window of process A for process B by default. In this
    example, a new console window with a custom color scheme is created for the
    child process B instead.

    \snippet qprocess/qprocess-createprocessargumentsmodifier.cpp 0

    \sa QProcess::CreateProcessArguments
    \sa setCreateProcessArgumentsModifier()
*/

/*!
    \class QProcess::CreateProcessArguments
    \inmodule QtCore
    \note This struct is only available on the Windows platform.

    This struct is a representation of all parameters of the Windows API
    function \c CreateProcess. It is used as parameter for
    \c CreateProcessArgumentModifier functions.

    \sa QProcess::CreateProcessArgumentModifier
*/

/*!
    \fn void QProcess::error(QProcess::ProcessError error)
    \obsolete

    Use errorOccurred() instead.
*/

/*!
    \fn void QProcess::errorOccurred(QProcess::ProcessError error)
    \since 5.6

    This signal is emitted when an error occurs with the process. The
    specified \a error describes the type of error that occurred.
*/

/*!
    \fn void QProcess::started()

    This signal is emitted by QProcess when the process has started,
    and state() returns \l Running.
*/

/*!
    \fn void QProcess::stateChanged(QProcess::ProcessState newState)

    This signal is emitted whenever the state of QProcess changes. The
    \a newState argument is the state QProcess changed to.
*/

#if QT_DEPRECATED_SINCE(5, 13)
/*!
    \fn void QProcess::finished(int exitCode)
    \obsolete
    \overload

    Use finished(int exitCode, QProcess::ExitStatus status) instead.
*/
#endif

/*!
    \fn void QProcess::finished(int exitCode, QProcess::ExitStatus exitStatus)

    This signal is emitted when the process finishes. \a exitCode is the exit
    code of the process (only valid for normal exits), and \a exitStatus is
    the exit status.
    After the process has finished, the buffers in QProcess are still intact.
    You can still read any data that the process may have written before it
    finished.

    \sa exitStatus()
*/

/*!
    \fn void QProcess::readyReadStandardOutput()

    This signal is emitted when the process has made new data
    available through its standard output channel (\c stdout). It is
    emitted regardless of the current \l{readChannel()}{read channel}.

    \sa readAllStandardOutput(), readChannel()
*/

/*!
    \fn void QProcess::readyReadStandardError()

    This signal is emitted when the process has made new data
    available through its standard error channel (\c stderr). It is
    emitted regardless of the current \l{readChannel()}{read
    channel}.

    \sa readAllStandardError(), readChannel()
*/

/*!
    \internal
*/
QProcessPrivate::QProcessPrivate()
{
    readBufferChunkSize = QRINGBUFFER_CHUNKSIZE;
    writeBufferChunkSize = QRINGBUFFER_CHUNKSIZE;
    processChannelMode = QProcess::SeparateChannels;
    inputChannelMode = QProcess::ManagedInputChannel;
    processError = QProcess::UnknownError;
    processState = QProcess::NotRunning;
    pid = 0;
    sequenceNumber = 0;
    exitCode = 0;
    exitStatus = QProcess::NormalExit;
    startupSocketNotifier = 0;
    deathNotifier = 0;
    childStartedPipe[0] = INVALID_Q_PIPE;
    childStartedPipe[1] = INVALID_Q_PIPE;
    forkfd = -1;
    crashed = false;
    dying = false;
    emittedReadyRead = false;
    emittedBytesWritten = false;
#ifdef Q_OS_WIN
    stdinWriteTrigger = 0;
    processFinishedNotifier = 0;
#endif // Q_OS_WIN
}

/*!
    \internal
*/
QProcessPrivate::~QProcessPrivate()
{
    if (stdinChannel.process)
        stdinChannel.process->stdoutChannel.clear();
    if (stdoutChannel.process)
        stdoutChannel.process->stdinChannel.clear();
}

/*!
    \internal
*/
void QProcessPrivate::cleanup()
{
    q_func()->setProcessState(QProcess::NotRunning);
#ifdef Q_OS_WIN
    if (pid) {
        CloseHandle(pid->hThread);
        CloseHandle(pid->hProcess);
        delete pid;
        pid = 0;
    }
    if (stdinWriteTrigger) {
        delete stdinWriteTrigger;
        stdinWriteTrigger = 0;
    }
    if (processFinishedNotifier) {
        delete processFinishedNotifier;
        processFinishedNotifier = 0;
    }

#endif
    pid = 0;
    sequenceNumber = 0;
    dying = false;

    if (stdoutChannel.notifier) {
        delete stdoutChannel.notifier;
        stdoutChannel.notifier = 0;
    }
    if (stderrChannel.notifier) {
        delete stderrChannel.notifier;
        stderrChannel.notifier = 0;
    }
    if (stdinChannel.notifier) {
        delete stdinChannel.notifier;
        stdinChannel.notifier = 0;
    }
    if (startupSocketNotifier) {
        delete startupSocketNotifier;
        startupSocketNotifier = 0;
    }
    if (deathNotifier) {
        delete deathNotifier;
        deathNotifier = 0;
    }
    closeChannel(&stdoutChannel);
    closeChannel(&stderrChannel);
    closeChannel(&stdinChannel);
    destroyPipe(childStartedPipe);
#ifdef Q_OS_UNIX
    if (forkfd != -1)
        qt_safe_close(forkfd);
    forkfd = -1;
#endif
}

/*!
    \internal
*/
void QProcessPrivate::setError(QProcess::ProcessError error, const QString &description)
{
    processError = error;
    if (description.isEmpty()) {
        switch (error) {
        case QProcess::FailedToStart:
            errorString = QProcess::tr("Process failed to start");
            break;
        case QProcess::Crashed:
            errorString = QProcess::tr("Process crashed");
            break;
        case QProcess::Timedout:
            errorString = QProcess::tr("Process operation timed out");
            break;
        case QProcess::ReadError:
            errorString = QProcess::tr("Error reading from process");
            break;
        case QProcess::WriteError:
            errorString = QProcess::tr("Error writing to process");
            break;
        case QProcess::UnknownError:
            errorString.clear();
            break;
        }
    } else {
        errorString = description;
    }
}

/*!
    \internal
*/
void QProcessPrivate::setErrorAndEmit(QProcess::ProcessError error, const QString &description)
{
    Q_Q(QProcess);
    Q_ASSERT(error != QProcess::UnknownError);
    setError(error, description);
    emit q->errorOccurred(processError);
#if QT_DEPRECATED_SINCE(5, 6)
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
    emit q->error(processError);
QT_WARNING_POP
#endif
}

/*!
    \internal
    Returns \c true if we emitted readyRead().
*/
bool QProcessPrivate::tryReadFromChannel(Channel *channel)
{
    Q_Q(QProcess);
    if (channel->pipe[0] == INVALID_Q_PIPE)
        return false;

    qint64 available = bytesAvailableInChannel(channel);
    if (available == 0)
        available = 1;      // always try to read at least one byte

    QProcess::ProcessChannel channelIdx = (channel == &stdoutChannel
                                           ? QProcess::StandardOutput
                                           : QProcess::StandardError);
    Q_ASSERT(readBuffers.size() > int(channelIdx));
    QRingBuffer &readBuffer = readBuffers[int(channelIdx)];
    char *ptr = readBuffer.reserve(available);
    qint64 readBytes = readFromChannel(channel, ptr, available);
    if (readBytes <= 0)
        readBuffer.chop(available);
    if (readBytes == -2) {
        // EWOULDBLOCK
        return false;
    }
    if (readBytes == -1) {
        setErrorAndEmit(QProcess::ReadError);
#if defined QPROCESS_DEBUG
        qDebug("QProcessPrivate::tryReadFromChannel(%d), failed to read from the process",
               int(channel - &stdinChannel));
#endif
        return false;
    }
    if (readBytes == 0) {
        // EOF
        if (channel->notifier)
            channel->notifier->setEnabled(false);
        closeChannel(channel);
#if defined QPROCESS_DEBUG
        qDebug("QProcessPrivate::tryReadFromChannel(%d), 0 bytes available",
               int(channel - &stdinChannel));
#endif
        return false;
    }
#if defined QPROCESS_DEBUG
    qDebug("QProcessPrivate::tryReadFromChannel(%d), read %d bytes from the process' output",
           int(channel - &stdinChannel), int(readBytes));
#endif

    if (channel->closed) {
        readBuffer.chop(readBytes);
        return false;
    }

    readBuffer.chop(available - readBytes);

    bool didRead = false;
    if (currentReadChannel == channelIdx) {
        didRead = true;
        if (!emittedReadyRead) {
            QScopedValueRollback<bool> guard(emittedReadyRead, true);
            emit q->readyRead();
        }
    }
    emit q->channelReadyRead(int(channelIdx));
    if (channelIdx == QProcess::StandardOutput)
        emit q->readyReadStandardOutput(QProcess::QPrivateSignal());
    else
        emit q->readyReadStandardError(QProcess::QPrivateSignal());
    return didRead;
}

/*!
    \internal
*/
bool QProcessPrivate::_q_canReadStandardOutput()
{
    return tryReadFromChannel(&stdoutChannel);
}

/*!
    \internal
*/
bool QProcessPrivate::_q_canReadStandardError()
{
    return tryReadFromChannel(&stderrChannel);
}

/*!
    \internal
*/
bool QProcessPrivate::_q_canWrite()
{
    if (writeBuffer.isEmpty()) {
        if (stdinChannel.notifier)
            stdinChannel.notifier->setEnabled(false);
#if defined QPROCESS_DEBUG
        qDebug("QProcessPrivate::canWrite(), not writing anything (empty write buffer).");
#endif
        return false;
    }

    const bool writeSucceeded = writeToStdin();

    if (writeBuffer.isEmpty() && stdinChannel.closed)
        closeWriteChannel();
    else if (stdinChannel.notifier)
        stdinChannel.notifier->setEnabled(!writeBuffer.isEmpty());
    return writeSucceeded;
}

/*!
    \internal
*/
bool QProcessPrivate::_q_processDied()
{
    Q_Q(QProcess);
#if defined QPROCESS_DEBUG
    qDebug("QProcessPrivate::_q_processDied()");
#endif
#ifdef Q_OS_UNIX
    if (!waitForDeadChild())
        return false;
#endif
#ifdef Q_OS_WIN
    if (processFinishedNotifier)
        processFinishedNotifier->setEnabled(false);
    drainOutputPipes();
#endif

    // the process may have died before it got a chance to report that it was
    // either running or stopped, so we will call _q_startupNotification() and
    // give it a chance to emit started() or errorOccurred(FailedToStart).
    if (processState == QProcess::Starting) {
        if (!_q_startupNotification())
            return true;
    }

    if (dying) {
        // at this point we know the process is dead. prevent
        // reentering this slot recursively by calling waitForFinished()
        // or opening a dialog inside slots connected to the readyRead
        // signals emitted below.
        return true;
    }
    dying = true;

    // in case there is data in the pipe line and this slot by chance
    // got called before the read notifications, call these two slots
    // so the data is made available before the process dies.
    _q_canReadStandardOutput();
    _q_canReadStandardError();

    findExitCode();

    if (crashed) {
        exitStatus = QProcess::CrashExit;
        setErrorAndEmit(QProcess::Crashed);
    }

    bool wasRunning = (processState == QProcess::Running);

    cleanup();

    if (wasRunning) {
        // we received EOF now:
        emit q->readChannelFinished();
        // in the future:
        //emit q->standardOutputClosed();
        //emit q->standardErrorClosed();

#if QT_DEPRECATED_SINCE(5, 13)
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
        emit q->finished(exitCode);
QT_WARNING_POP
#endif
        emit q->finished(exitCode, exitStatus);
    }
#if defined QPROCESS_DEBUG
    qDebug("QProcessPrivate::_q_processDied() process is dead");
#endif
    return true;
}

/*!
    \internal
*/
bool QProcessPrivate::_q_startupNotification()
{
    Q_Q(QProcess);
#if defined QPROCESS_DEBUG
    qDebug("QProcessPrivate::startupNotification()");
#endif

    if (startupSocketNotifier)
        startupSocketNotifier->setEnabled(false);
    QString errorMessage;
    if (processStarted(&errorMessage)) {
        q->setProcessState(QProcess::Running);
        emit q->started(QProcess::QPrivateSignal());
        return true;
    }

    q->setProcessState(QProcess::NotRunning);
    setErrorAndEmit(QProcess::FailedToStart, errorMessage);
#ifdef Q_OS_UNIX
    // make sure the process manager removes this entry
    waitForDeadChild();
    findExitCode();
#endif
    cleanup();
    return false;
}

/*!
    \internal
*/
void QProcessPrivate::closeWriteChannel()
{
#if defined QPROCESS_DEBUG
    qDebug("QProcessPrivate::closeWriteChannel()");
#endif
    if (stdinChannel.notifier) {
        delete stdinChannel.notifier;
        stdinChannel.notifier = 0;
    }
#ifdef Q_OS_WIN
    // ### Find a better fix, feeding the process little by little
    // instead.
    flushPipeWriter();
#endif
    closeChannel(&stdinChannel);
}

/*!
    Constructs a QProcess object with the given \a parent.
*/
QProcess::QProcess(QObject *parent)
    : QIODevice(*new QProcessPrivate, parent)
{
#if defined QPROCESS_DEBUG
    qDebug("QProcess::QProcess(%p)", parent);
#endif
}

/*!
    Destructs the QProcess object, i.e., killing the process.

    Note that this function will not return until the process is
    terminated.
*/
QProcess::~QProcess()
{
    Q_D(QProcess);
    if (d->processState != NotRunning) {
        qWarning().nospace()
            << "QProcess: Destroyed while process (" << QDir::toNativeSeparators(program()) << ") is still running.";
        kill();
        waitForFinished();
    }
#ifdef Q_OS_UNIX
    // make sure the process manager removes this entry
    d->findExitCode();
#endif
    d->cleanup();
}

#if QT_DEPRECATED_SINCE(5, 13)
/*!
    \obsolete
    Returns the read channel mode of the QProcess. This function is
    equivalent to processChannelMode()

    \sa processChannelMode()
*/
QProcess::ProcessChannelMode QProcess::readChannelMode() const
{
    return processChannelMode();
}

/*!
    \obsolete

    Use setProcessChannelMode(\a mode) instead.

    \sa setProcessChannelMode()
*/
void QProcess::setReadChannelMode(ProcessChannelMode mode)
{
    setProcessChannelMode(mode);
}
#endif

/*!
    \since 4.2

    Returns the channel mode of the QProcess standard output and
    standard error channels.

    \sa setProcessChannelMode(), ProcessChannelMode, setReadChannel()
*/
QProcess::ProcessChannelMode QProcess::processChannelMode() const
{
    Q_D(const QProcess);
    return d->processChannelMode;
}

/*!
    \since 4.2

    Sets the channel mode of the QProcess standard output and standard
    error channels to the \a mode specified.
    This mode will be used the next time start() is called. For example:

    \snippet code/src_corelib_io_qprocess.cpp 0

    \sa processChannelMode(), ProcessChannelMode, setReadChannel()
*/
void QProcess::setProcessChannelMode(ProcessChannelMode mode)
{
    Q_D(QProcess);
    d->processChannelMode = mode;
}

/*!
    \since 5.2

    Returns the channel mode of the QProcess standard input channel.

    \sa setInputChannelMode(), InputChannelMode
*/
QProcess::InputChannelMode QProcess::inputChannelMode() const
{
    Q_D(const QProcess);
    return d->inputChannelMode;
}

/*!
    \since 5.2

    Sets the channel mode of the QProcess standard input
    channel to the \a mode specified.
    This mode will be used the next time start() is called.

    \sa inputChannelMode(), InputChannelMode
*/
void QProcess::setInputChannelMode(InputChannelMode mode)
{
    Q_D(QProcess);
    d->inputChannelMode = mode;
}

/*!
    Returns the current read channel of the QProcess.

    \sa setReadChannel()
*/
QProcess::ProcessChannel QProcess::readChannel() const
{
    Q_D(const QProcess);
    return ProcessChannel(d->currentReadChannel);
}

/*!
    Sets the current read channel of the QProcess to the given \a
    channel. The current input channel is used by the functions
    read(), readAll(), readLine(), and getChar(). It also determines
    which channel triggers QProcess to emit readyRead().

    \sa readChannel()
*/
void QProcess::setReadChannel(ProcessChannel channel)
{
    QIODevice::setCurrentReadChannel(int(channel));
}

/*!
    Closes the read channel \a channel. After calling this function,
    QProcess will no longer receive data on the channel. Any data that
    has already been received is still available for reading.

    Call this function to save memory, if you are not interested in
    the output of the process.

    \sa closeWriteChannel(), setReadChannel()
*/
void QProcess::closeReadChannel(ProcessChannel channel)
{
    Q_D(QProcess);

    if (channel == StandardOutput)
        d->stdoutChannel.closed = true;
    else
        d->stderrChannel.closed = true;
}

/*!
    Schedules the write channel of QProcess to be closed. The channel
    will close once all data has been written to the process. After
    calling this function, any attempts to write to the process will
    fail.

    Closing the write channel is necessary for programs that read
    input data until the channel has been closed. For example, the
    program "more" is used to display text data in a console on both
    Unix and Windows. But it will not display the text data until
    QProcess's write channel has been closed. Example:

    \snippet code/src_corelib_io_qprocess.cpp 1

    The write channel is implicitly opened when start() is called.

    \sa closeReadChannel()
*/
void QProcess::closeWriteChannel()
{
    Q_D(QProcess);
    d->stdinChannel.closed = true; // closing
    if (d->writeBuffer.isEmpty())
        d->closeWriteChannel();
}

/*!
    \since 4.2

    Redirects the process' standard input to the file indicated by \a
    fileName. When an input redirection is in place, the QProcess
    object will be in read-only mode (calling write() will result in
    error).

    To make the process read EOF right away, pass nullDevice() here.
    This is cleaner than using closeWriteChannel() before writing any
    data, because it can be set up prior to starting the process.

    If the file \a fileName does not exist at the moment start() is
    called or is not readable, starting the process will fail.

    Calling setStandardInputFile() after the process has started has no
    effect.

    \sa setStandardOutputFile(), setStandardErrorFile(),
        setStandardOutputProcess()
*/
void QProcess::setStandardInputFile(const QString &fileName)
{
    Q_D(QProcess);
    d->stdinChannel = fileName;
}

/*!
    \since 4.2

    Redirects the process' standard output to the file \a
    fileName. When the redirection is in place, the standard output
    read channel is closed: reading from it using read() will always
    fail, as will readAllStandardOutput().

    To discard all standard output from the process, pass nullDevice()
    here. This is more efficient than simply never reading the standard
    output, as no QProcess buffers are filled.

    If the file \a fileName doesn't exist at the moment start() is
    called, it will be created. If it cannot be created, the starting
    will fail.

    If the file exists and \a mode is QIODevice::Truncate, the file
    will be truncated. Otherwise (if \a mode is QIODevice::Append),
    the file will be appended to.

    Calling setStandardOutputFile() after the process has started has
    no effect.

    \sa setStandardInputFile(), setStandardErrorFile(),
        setStandardOutputProcess()
*/
void QProcess::setStandardOutputFile(const QString &fileName, OpenMode mode)
{
    Q_ASSERT(mode == Append || mode == Truncate);
    Q_D(QProcess);

    d->stdoutChannel = fileName;
    d->stdoutChannel.append = mode == Append;
}

/*!
    \since 4.2

    Redirects the process' standard error to the file \a
    fileName. When the redirection is in place, the standard error
    read channel is closed: reading from it using read() will always
    fail, as will readAllStandardError(). The file will be appended to
    if \a mode is Append, otherwise, it will be truncated.

    See setStandardOutputFile() for more information on how the file
    is opened.

    Note: if setProcessChannelMode() was called with an argument of
    QProcess::MergedChannels, this function has no effect.

    \sa setStandardInputFile(), setStandardOutputFile(),
        setStandardOutputProcess()
*/
void QProcess::setStandardErrorFile(const QString &fileName, OpenMode mode)
{
    Q_ASSERT(mode == Append || mode == Truncate);
    Q_D(QProcess);

    d->stderrChannel = fileName;
    d->stderrChannel.append = mode == Append;
}

/*!
    \since 4.2

    Pipes the standard output stream of this process to the \a
    destination process' standard input.

    The following shell command:
    \snippet code/src_corelib_io_qprocess.cpp 2

    Can be accomplished with QProcess with the following code:
    \snippet code/src_corelib_io_qprocess.cpp 3
*/
void QProcess::setStandardOutputProcess(QProcess *destination)
{
    QProcessPrivate *dfrom = d_func();
    QProcessPrivate *dto = destination->d_func();
    dfrom->stdoutChannel.pipeTo(dto);
    dto->stdinChannel.pipeFrom(dfrom);
}

#if defined(Q_OS_WIN) || defined(Q_CLANG_QDOC)

/*!
    \since 4.7

    Returns the additional native command line arguments for the program.

    \note This function is available only on the Windows platform.

    \sa setNativeArguments()
*/
QString QProcess::nativeArguments() const
{
    Q_D(const QProcess);
    return d->nativeArguments;
}

/*!
    \since 4.7
    \overload

    Sets additional native command line \a arguments for the program.

    On operating systems where the system API for passing command line
    \a arguments to a subprocess natively uses a single string, one can
    conceive command lines which cannot be passed via QProcess's portable
    list-based API. In such cases this function must be used to set a
    string which is \e appended to the string composed from the usual
    argument list, with a delimiting space.

    \note This function is available only on the Windows platform.

    \sa nativeArguments()
*/
void QProcess::setNativeArguments(const QString &arguments)
{
    Q_D(QProcess);
    d->nativeArguments = arguments;
}

/*!
    \since 5.7

    Returns a previously set \c CreateProcess modifier function.

    \note This function is available only on the Windows platform.

    \sa setCreateProcessArgumentsModifier()
    \sa QProcess::CreateProcessArgumentModifier
*/
QProcess::CreateProcessArgumentModifier QProcess::createProcessArgumentsModifier() const
{
    Q_D(const QProcess);
    return d->modifyCreateProcessArgs;
}

/*!
    \since 5.7

    Sets the \a modifier for the \c CreateProcess Win32 API call.
    Pass \c QProcess::CreateProcessArgumentModifier() to remove a previously set one.

    \note This function is available only on the Windows platform and requires
    C++11.

    \sa QProcess::CreateProcessArgumentModifier
*/
void QProcess::setCreateProcessArgumentsModifier(CreateProcessArgumentModifier modifier)
{
    Q_D(QProcess);
    d->modifyCreateProcessArgs = modifier;
}

#endif

/*!
    If QProcess has been assigned a working directory, this function returns
    the working directory that the QProcess will enter before the program has
    started. Otherwise, (i.e., no directory has been assigned,) an empty
    string is returned, and QProcess will use the application's current
    working directory instead.

    \sa setWorkingDirectory()
*/
QString QProcess::workingDirectory() const
{
    Q_D(const QProcess);
    return d->workingDirectory;
}

/*!
    Sets the working directory to \a dir. QProcess will start the
    process in this directory. The default behavior is to start the
    process in the working directory of the calling process.

    \note On QNX, this may cause all application threads to
    temporarily freeze.

    \sa workingDirectory(), start()
*/
void QProcess::setWorkingDirectory(const QString &dir)
{
    Q_D(QProcess);
    d->workingDirectory = dir;
}


/*!
    \deprecated
    Use processId() instead.

    Returns the native process identifier for the running process, if
    available.  If no process is currently running, \c 0 is returned.

    \note Unlike \l processId(), pid() returns an integer on Unix and a pointer on Windows.

    \sa Q_PID, processId()
*/
Q_PID QProcess::pid() const // ### Qt 6 remove or rename this method to processInformation()
{
    Q_D(const QProcess);
    return d->pid;
}

/*!
    \since 5.3

    Returns the native process identifier for the running process, if
    available. If no process is currently running, \c 0 is returned.
 */
qint64 QProcess::processId() const
{
    Q_D(const QProcess);
#ifdef Q_OS_WIN
    return d->pid ? d->pid->dwProcessId : 0;
#else
    return d->pid;
#endif
}

/*! \reimp

    This function operates on the current read channel.

    \sa readChannel(), setReadChannel()
*/
bool QProcess::canReadLine() const
{
    return QIODevice::canReadLine();
}

/*!
    Closes all communication with the process and kills it. After calling this
    function, QProcess will no longer emit readyRead(), and data can no
    longer be read or written.
*/
void QProcess::close()
{
    Q_D(QProcess);
    emit aboutToClose();
    while (waitForBytesWritten(-1))
        ;
    kill();
    waitForFinished(-1);
    d->setWriteChannelCount(0);
    QIODevice::close();
}

/*! \reimp

   Returns \c true if the process is not running, and no more data is available
   for reading; otherwise returns \c false.
*/
bool QProcess::atEnd() const
{
    return QIODevice::atEnd();
}

/*! \reimp
*/
bool QProcess::isSequential() const
{
    return true;
}

/*! \reimp
*/
qint64 QProcess::bytesAvailable() const
{
    return QIODevice::bytesAvailable();
}

/*! \reimp
*/
qint64 QProcess::bytesToWrite() const
{
    qint64 size = QIODevice::bytesToWrite();
#ifdef Q_OS_WIN
    size += d_func()->pipeWriterBytesToWrite();
#endif
    return size;
}

/*!
    Returns the type of error that occurred last.

    \sa state()
*/
QProcess::ProcessError QProcess::error() const
{
    Q_D(const QProcess);
    return d->processError;
}

/*!
    Returns the current state of the process.

    \sa stateChanged(), error()
*/
QProcess::ProcessState QProcess::state() const
{
    Q_D(const QProcess);
    return d->processState;
}

/*!
    \deprecated
    Sets the environment that QProcess will pass to the child process.
    The parameter \a environment is a list of key=value pairs.

    For example, the following code adds the environment variable \c{TMPDIR}:

    \snippet qprocess-environment/main.cpp 0

    \note This function is less efficient than the setProcessEnvironment()
    function.

    \sa environment(), setProcessEnvironment(), systemEnvironment()
*/
void QProcess::setEnvironment(const QStringList &environment)
{
    setProcessEnvironment(QProcessEnvironmentPrivate::fromList(environment));
}

/*!
    \deprecated
    Returns the environment that QProcess will pass to its child
    process, or an empty QStringList if no environment has been set
    using setEnvironment(). If no environment has been set, the
    environment of the calling process will be used.

    \sa processEnvironment(), setEnvironment(), systemEnvironment()
*/
QStringList QProcess::environment() const
{
    Q_D(const QProcess);
    return d->environment.toStringList();
}

/*!
    \since 4.6
    Sets the \a environment that QProcess will pass to the child process.

    For example, the following code adds the environment variable \c{TMPDIR}:

    \snippet qprocess-environment/main.cpp 1

    Note how, on Windows, environment variable names are case-insensitive.

    \sa processEnvironment(), QProcessEnvironment::systemEnvironment(), setEnvironment()
*/
void QProcess::setProcessEnvironment(const QProcessEnvironment &environment)
{
    Q_D(QProcess);
    d->environment = environment;
}

/*!
    \since 4.6
    Returns the environment that QProcess will pass to its child
    process, or an empty object if no environment has been set using
    setEnvironment() or setProcessEnvironment(). If no environment has
    been set, the environment of the calling process will be used.

    \sa setProcessEnvironment(), setEnvironment(), QProcessEnvironment::isEmpty()
*/
QProcessEnvironment QProcess::processEnvironment() const
{
    Q_D(const QProcess);
    return d->environment;
}

/*!
    Blocks until the process has started and the started() signal has
    been emitted, or until \a msecs milliseconds have passed.

    Returns \c true if the process was started successfully; otherwise
    returns \c false (if the operation timed out or if an error
    occurred).

    This function can operate without an event loop. It is
    useful when writing non-GUI applications and when performing
    I/O operations in a non-GUI thread.

    \warning Calling this function from the main (GUI) thread
    might cause your user interface to freeze.

    If msecs is -1, this function will not time out.

    \note On some UNIX operating systems, this function may return true but
    the process may later report a QProcess::FailedToStart error.

    \sa started(), waitForReadyRead(), waitForBytesWritten(), waitForFinished()
*/
bool QProcess::waitForStarted(int msecs)
{
    Q_D(QProcess);
    if (d->processState == QProcess::Starting)
        return d->waitForStarted(msecs);

    return d->processState == QProcess::Running;
}

/*! \reimp
*/
bool QProcess::waitForReadyRead(int msecs)
{
    Q_D(QProcess);

    if (d->processState == QProcess::NotRunning)
        return false;
    if (d->currentReadChannel == QProcess::StandardOutput && d->stdoutChannel.closed)
        return false;
    if (d->currentReadChannel == QProcess::StandardError && d->stderrChannel.closed)
        return false;
    return d->waitForReadyRead(msecs);
}

/*! \reimp
*/
bool QProcess::waitForBytesWritten(int msecs)
{
    Q_D(QProcess);
    if (d->processState == QProcess::NotRunning)
        return false;
    if (d->processState == QProcess::Starting) {
        QElapsedTimer stopWatch;
        stopWatch.start();
        bool started = waitForStarted(msecs);
        if (!started)
            return false;
        msecs = qt_subtract_from_timeout(msecs, stopWatch.elapsed());
    }

    return d->waitForBytesWritten(msecs);
}

/*!
    Blocks until the process has finished and the finished() signal
    has been emitted, or until \a msecs milliseconds have passed.

    Returns \c true if the process finished; otherwise returns \c false (if
    the operation timed out, if an error occurred, or if this QProcess
    is already finished).

    This function can operate without an event loop. It is
    useful when writing non-GUI applications and when performing
    I/O operations in a non-GUI thread.

    \warning Calling this function from the main (GUI) thread
    might cause your user interface to freeze.

    If msecs is -1, this function will not time out.

    \sa finished(), waitForStarted(), waitForReadyRead(), waitForBytesWritten()
*/
bool QProcess::waitForFinished(int msecs)
{
    Q_D(QProcess);
    if (d->processState == QProcess::NotRunning)
        return false;
    if (d->processState == QProcess::Starting) {
        QElapsedTimer stopWatch;
        stopWatch.start();
        bool started = waitForStarted(msecs);
        if (!started)
            return false;
        msecs = qt_subtract_from_timeout(msecs, stopWatch.elapsed());
    }

    return d->waitForFinished(msecs);
}

/*!
    Sets the current state of the QProcess to the \a state specified.

    \sa state()
*/
void QProcess::setProcessState(ProcessState state)
{
    Q_D(QProcess);
    if (d->processState == state)
        return;
    d->processState = state;
    emit stateChanged(state, QPrivateSignal());
}

/*!
  This function is called in the child process context just before the
    program is executed on Unix or \macos (i.e., after \c fork(), but before
    \c execve()). Reimplement this function to do last minute initialization
    of the child process. Example:

    \snippet code/src_corelib_io_qprocess.cpp 4

    You cannot exit the process (by calling exit(), for instance) from
    this function. If you need to stop the program before it starts
    execution, your workaround is to emit finished() and then call
    exit().

    \warning This function is called by QProcess on Unix and \macos
    only. On Windows and QNX, it is not called.
*/
void QProcess::setupChildProcess()
{
}

/*! \reimp
*/
qint64 QProcess::readData(char *data, qint64 maxlen)
{
    Q_D(QProcess);
    Q_UNUSED(data);
    if (!maxlen)
        return 0;
    if (d->processState == QProcess::NotRunning)
        return -1;              // EOF
    return 0;
}

/*! \reimp
*/
qint64 QProcess::writeData(const char *data, qint64 len)
{
    Q_D(QProcess);

    if (d->stdinChannel.closed) {
#if defined QPROCESS_DEBUG
    qDebug("QProcess::writeData(%p \"%s\", %lld) == 0 (write channel closing)",
           data, qt_prettyDebug(data, len, 16).constData(), len);
#endif
        return 0;
    }

#if defined(Q_OS_WIN)
    if (!d->stdinWriteTrigger) {
        d->stdinWriteTrigger = new QTimer;
        d->stdinWriteTrigger->setSingleShot(true);
        QObjectPrivate::connect(d->stdinWriteTrigger, &QTimer::timeout,
                                d, &QProcessPrivate::_q_canWrite);
    }
#endif

    d->writeBuffer.append(data, len);
#ifdef Q_OS_WIN
    if (!d->stdinWriteTrigger->isActive())
        d->stdinWriteTrigger->start();
#else
    if (d->stdinChannel.notifier)
        d->stdinChannel.notifier->setEnabled(true);
#endif
#if defined QPROCESS_DEBUG
    qDebug("QProcess::writeData(%p \"%s\", %lld) == %lld (written to buffer)",
           data, qt_prettyDebug(data, len, 16).constData(), len, len);
#endif
    return len;
}

/*!
    Regardless of the current read channel, this function returns all
    data available from the standard output of the process as a
    QByteArray.

    \sa readyReadStandardOutput(), readAllStandardError(), readChannel(), setReadChannel()
*/
QByteArray QProcess::readAllStandardOutput()
{
    ProcessChannel tmp = readChannel();
    setReadChannel(StandardOutput);
    QByteArray data = readAll();
    setReadChannel(tmp);
    return data;
}

/*!
    Regardless of the current read channel, this function returns all
    data available from the standard error of the process as a
    QByteArray.

    \sa readyReadStandardError(), readAllStandardOutput(), readChannel(), setReadChannel()
*/
QByteArray QProcess::readAllStandardError()
{
    ProcessChannel tmp = readChannel();
    setReadChannel(StandardError);
    QByteArray data = readAll();
    setReadChannel(tmp);
    return data;
}

/*!
    Starts the given \a program in a new process, passing the command line
    arguments in \a arguments.

    The QProcess object will immediately enter the Starting state. If the
    process starts successfully, QProcess will emit started(); otherwise,
    errorOccurred() will be emitted.

    \note Processes are started asynchronously, which means the started()
    and errorOccurred() signals may be delayed. Call waitForStarted() to make
    sure the process has started (or has failed to start) and those signals
    have been emitted.

    \note No further splitting of the arguments is performed.

    \b{Windows:} The arguments are quoted and joined into a command line
    that is compatible with the \c CommandLineToArgvW() Windows function.
    For programs that have different command line quoting requirements,
    you need to use setNativeArguments(). One notable program that does
    not follow the \c CommandLineToArgvW() rules is cmd.exe and, by
    consequence, all batch scripts.

    The OpenMode is set to \a mode.

    If the QProcess object is already running a process, a warning may be
    printed at the console, and the existing process will continue running
    unaffected.

    \sa processId(), started(), waitForStarted(), setNativeArguments()
*/
void QProcess::start(const QString &program, const QStringList &arguments, OpenMode mode)
{
    Q_D(QProcess);
    if (d->processState != NotRunning) {
        qWarning("QProcess::start: Process is already running");
        return;
    }
    if (program.isEmpty()) {
        d->setErrorAndEmit(QProcess::FailedToStart, tr("No program defined"));
        return;
    }

    d->program = program;
    d->arguments = arguments;

    d->start(mode);
}

/*!
    \since 5.1
    \overload

    Starts the program set by setProgram() with arguments set by setArguments().
    The OpenMode is set to \a mode.

    \sa open(), setProgram(), setArguments()
 */
void QProcess::start(OpenMode mode)
{
    Q_D(QProcess);
    if (d->processState != NotRunning) {
        qWarning("QProcess::start: Process is already running");
        return;
    }
    if (d->program.isEmpty()) {
        d->setErrorAndEmit(QProcess::FailedToStart, tr("No program defined"));
        return;
    }

    d->start(mode);
}

/*!
    \since 5.10

    Starts the program set by setProgram() with arguments set by setArguments()
    in a new process, and detaches from it. Returns \c true on success;
    otherwise returns \c false. If the calling process exits, the
    detached process will continue to run unaffected.

    \b{Unix:} The started process will run in its own session and act
    like a daemon.

    The process will be started in the directory set by setWorkingDirectory().
    If workingDirectory() is empty, the working directory is inherited
    from the calling process.

    \note On QNX, this may cause all application threads to
    temporarily freeze.

    If the function is successful then *\a pid is set to the process identifier
    of the started process. Note that the child process may exit and the PID
    may become invalid without notice. Furthermore, after the child process
    exits, the same PID may be recycled and used by a completely different
    process. User code should be careful when using this variable, especially
    if one intends to forcibly terminate the process by operating system means.

    Only the following property setters are supported by startDetached():
    \list
    \li setArguments()
    \li setCreateProcessArgumentsModifier()
    \li setNativeArguments()
    \li setProcessEnvironment()
    \li setProgram()
    \li setStandardErrorFile()
    \li setStandardInputFile()
    \li setStandardOutputFile()
    \li setWorkingDirectory()
    \endlist
    All other properties of the QProcess object are ignored.

    \note The called process inherits the console window of the calling
    process. To suppress console output, redirect standard/error output to
    QProcess::nullDevice().

    \sa start()
    \sa startDetached(const QString &program, const QStringList &arguments,
                      const QString &workingDirectory, qint64 *pid)
    \sa startDetached(const QString &command)
*/
bool QProcess::startDetached(qint64 *pid)
{
    Q_D(QProcess);
    if (d->processState != NotRunning) {
        qWarning("QProcess::startDetached: Process is already running");
        return false;
    }
    if (d->program.isEmpty()) {
        d->setErrorAndEmit(QProcess::FailedToStart, tr("No program defined"));
        return false;
    }
    return d->startDetached(pid);
}

/*!
    Starts the program set by setProgram() with arguments set by setArguments().
    The OpenMode is set to \a mode.

    This method is an alias for start(), and exists only to fully implement
    the interface defined by QIODevice.

    Returns \c true if the program has been started.

    \sa start(), setProgram(), setArguments()
*/
bool QProcess::open(OpenMode mode)
{
    Q_D(QProcess);
    if (d->processState != NotRunning) {
        qWarning("QProcess::start: Process is already running");
        return false;
    }
    if (d->program.isEmpty()) {
        qWarning("QProcess::start: program not set");
        return false;
    }

    d->start(mode);
    return true;
}

void QProcessPrivate::start(QIODevice::OpenMode mode)
{
    Q_Q(QProcess);
#if defined QPROCESS_DEBUG
    qDebug() << "QProcess::start(" << program << ',' << arguments << ',' << mode << ')';
#endif

    if (stdinChannel.type != QProcessPrivate::Channel::Normal)
        mode &= ~QIODevice::WriteOnly;     // not open for writing
    if (stdoutChannel.type != QProcessPrivate::Channel::Normal &&
        (stderrChannel.type != QProcessPrivate::Channel::Normal ||
         processChannelMode == QProcess::MergedChannels))
        mode &= ~QIODevice::ReadOnly;      // not open for reading
    if (mode == 0)
        mode = QIODevice::Unbuffered;
    if ((mode & QIODevice::ReadOnly) == 0) {
        if (stdoutChannel.type == QProcessPrivate::Channel::Normal)
            q->setStandardOutputFile(q->nullDevice());
        if (stderrChannel.type == QProcessPrivate::Channel::Normal
            && processChannelMode != QProcess::MergedChannels)
            q->setStandardErrorFile(q->nullDevice());
    }

    q->QIODevice::open(mode);

    if (q->isReadable() && processChannelMode != QProcess::MergedChannels)
        setReadChannelCount(2);

    stdinChannel.closed = false;
    stdoutChannel.closed = false;
    stderrChannel.closed = false;

    exitCode = 0;
    exitStatus = QProcess::NormalExit;
    processError = QProcess::UnknownError;
    errorString.clear();
    startProcess();
}


static QStringList parseCombinedArgString(const QString &program)
{
    QStringList args;
    QString tmp;
    int quoteCount = 0;
    bool inQuote = false;

    // handle quoting. tokens can be surrounded by double quotes
    // "hello world". three consecutive double quotes represent
    // the quote character itself.
    for (int i = 0; i < program.size(); ++i) {
        if (program.at(i) == QLatin1Char('"')) {
            ++quoteCount;
            if (quoteCount == 3) {
                // third consecutive quote
                quoteCount = 0;
                tmp += program.at(i);
            }
            continue;
        }
        if (quoteCount) {
            if (quoteCount == 1)
                inQuote = !inQuote;
            quoteCount = 0;
        }
        if (!inQuote && program.at(i).isSpace()) {
            if (!tmp.isEmpty()) {
                args += tmp;
                tmp.clear();
            }
        } else {
            tmp += program.at(i);
        }
    }
    if (!tmp.isEmpty())
        args += tmp;

    return args;
}

/*!
    \overload

    Starts the command \a command in a new process.
    The OpenMode is set to \a mode.

    \a command is a single string of text containing both the program name
    and its arguments. The arguments are separated by one or more spaces.
    For example:

    \snippet code/src_corelib_io_qprocess.cpp 5

    Arguments containing spaces must be quoted to be correctly supplied to
    the new process. For example:

    \snippet code/src_corelib_io_qprocess.cpp 6

    Literal quotes in the \a command string are represented by triple quotes.
    For example:

    \snippet code/src_corelib_io_qprocess.cpp 7

    After the \a command string has been split and unquoted, this function
    behaves like the overload which takes the arguments as a string list.

    You can disable this overload by defining \c
    QT_NO_PROCESS_COMBINED_ARGUMENT_START when you compile your applications.
    This can be useful if you want to ensure that you are not splitting arguments
    unintentionally, for example. In virtually all cases, using the other overload
    is the preferred method.

    On operating systems where the system API for passing command line
    arguments to a subprocess natively uses a single string (Windows), one can
    conceive command lines which cannot be passed via QProcess's portable
    list-based API. In these rare cases you need to use setProgram() and
    setNativeArguments() instead of this function.

*/
#if !defined(QT_NO_PROCESS_COMBINED_ARGUMENT_START)
void QProcess::start(const QString &command, OpenMode mode)
{
    QStringList args = parseCombinedArgString(command);
    if (args.isEmpty()) {
        Q_D(QProcess);
        d->setErrorAndEmit(QProcess::FailedToStart, tr("No program defined"));
        return;
    }

    const QString prog = args.takeFirst();

    start(prog, args, mode);
}
#endif

/*!
    \since 5.0

    Returns the program the process was last started with.

    \sa start()
*/
QString QProcess::program() const
{
    Q_D(const QProcess);
    return d->program;
}

/*!
    \since 5.1

    Set the \a program to use when starting the process.
    This function must be called before start().

    \sa start(), setArguments(), program()
*/
void QProcess::setProgram(const QString &program)
{
    Q_D(QProcess);
    if (d->processState != NotRunning) {
        qWarning("QProcess::setProgram: Process is already running");
        return;
    }
    d->program = program;
}

/*!
    \since 5.0

    Returns the command line arguments the process was last started with.

    \sa start()
*/
QStringList QProcess::arguments() const
{
    Q_D(const QProcess);
    return d->arguments;
}

/*!
    \since 5.1

    Set the \a arguments to pass to the called program when starting the process.
    This function must be called before start().

    \sa start(), setProgram(), arguments()
*/
void QProcess::setArguments(const QStringList &arguments)
{
    Q_D(QProcess);
    if (d->processState != NotRunning) {
        qWarning("QProcess::setProgram: Process is already running");
        return;
    }
    d->arguments = arguments;
}

/*!
    Attempts to terminate the process.

    The process may not exit as a result of calling this function (it is given
    the chance to prompt the user for any unsaved files, etc).

    On Windows, terminate() posts a WM_CLOSE message to all top-level windows
    of the process and then to the main thread of the process itself. On Unix
    and \macos the \c SIGTERM signal is sent.

    Console applications on Windows that do not run an event loop, or whose
    event loop does not handle the WM_CLOSE message, can only be terminated by
    calling kill().

    \sa kill()
*/
void QProcess::terminate()
{
    Q_D(QProcess);
    d->terminateProcess();
}

/*!
    Kills the current process, causing it to exit immediately.

    On Windows, kill() uses TerminateProcess, and on Unix and \macos, the
    SIGKILL signal is sent to the process.

    \sa terminate()
*/
void QProcess::kill()
{
    Q_D(QProcess);
    d->killProcess();
}

/*!
    Returns the exit code of the last process that finished.

    This value is not valid unless exitStatus() returns NormalExit.
*/
int QProcess::exitCode() const
{
    Q_D(const QProcess);
    return d->exitCode;
}

/*!
    \since 4.1

    Returns the exit status of the last process that finished.

    On Windows, if the process was terminated with TerminateProcess() from
    another application, this function will still return NormalExit
    unless the exit code is less than 0.
*/
QProcess::ExitStatus QProcess::exitStatus() const
{
    Q_D(const QProcess);
    return d->exitStatus;
}

/*!
    Starts the program \a program with the arguments \a arguments in a
    new process, waits for it to finish, and then returns the exit
    code of the process. Any data the new process writes to the
    console is forwarded to the calling process.

    The environment and working directory are inherited from the calling
    process.

    Argument handling is identical to the respective start() overload.

    If the process cannot be started, -2 is returned. If the process
    crashes, -1 is returned. Otherwise, the process' exit code is
    returned.

    \sa start()
*/
int QProcess::execute(const QString &program, const QStringList &arguments)
{
    QProcess process;
    process.setProcessChannelMode(ForwardedChannels);
    process.start(program, arguments);
    if (!process.waitForFinished(-1) || process.error() == FailedToStart)
        return -2;
    return process.exitStatus() == QProcess::NormalExit ? process.exitCode() : -1;
}

/*!
    \overload

    Starts the program \a command in a new process, waits for it to finish,
    and then returns the exit code.

    Argument handling is identical to the respective start() overload.

    After the \a command string has been split and unquoted, this function
    behaves like the overload which takes the arguments as a string list.

    \sa start()
*/
int QProcess::execute(const QString &command)
{
    QProcess process;
    process.setProcessChannelMode(ForwardedChannels);
    process.start(command);
    if (!process.waitForFinished(-1) || process.error() == FailedToStart)
        return -2;
    return process.exitStatus() == QProcess::NormalExit ? process.exitCode() : -1;
}

/*!
    \overload startDetached()

    Starts the program \a program with the arguments \a arguments in a
    new process, and detaches from it. Returns \c true on success;
    otherwise returns \c false. If the calling process exits, the
    detached process will continue to run unaffected.

    Argument handling is identical to the respective start() overload.

    The process will be started in the directory \a workingDirectory.
    If \a workingDirectory is empty, the working directory is inherited
    from the calling process.

    If the function is successful then *\a pid is set to the process
    identifier of the started process.

    \sa start()
*/
bool QProcess::startDetached(const QString &program,
                             const QStringList &arguments,
                             const QString &workingDirectory,
                             qint64 *pid)
{
    QProcess process;
    process.setProgram(program);
    process.setArguments(arguments);
    process.setWorkingDirectory(workingDirectory);
    return process.startDetached(pid);
}

/*!
    \internal
*/
bool QProcess::startDetached(const QString &program,
                             const QStringList &arguments)
{
    QProcess process;
    process.setProgram(program);
    process.setArguments(arguments);
    return process.startDetached();
}

/*!
    \overload startDetached()

    Starts the command \a command in a new process, and detaches from it.
    Returns \c true on success; otherwise returns \c false.

    Argument handling is identical to the respective start() overload.

    After the \a command string has been split and unquoted, this function
    behaves like the overload which takes the arguments as a string list.

    \sa start(const QString &command, QIODevice::OpenMode mode)
*/
bool QProcess::startDetached(const QString &command)
{
    QStringList args = parseCombinedArgString(command);
    if (args.isEmpty())
        return false;

    QProcess process;
    process.setProgram(args.takeFirst());
    process.setArguments(args);
    return process.startDetached();
}

QT_BEGIN_INCLUDE_NAMESPACE
#if defined(Q_OS_MACX)
# include <crt_externs.h>
# define environ (*_NSGetEnviron())
#elif defined(QT_PLATFORM_UIKIT)
  static char *qt_empty_environ[] = { 0 };
#define environ qt_empty_environ
#elif !defined(Q_OS_WIN)
  extern char **environ;
#endif
QT_END_INCLUDE_NAMESPACE

/*!
    \since 4.1

    Returns the environment of the calling process as a list of
    key=value pairs. Example:

    \snippet code/src_corelib_io_qprocess.cpp 8

    This function does not cache the system environment. Therefore, it's
    possible to obtain an updated version of the environment if low-level C
    library functions like \tt setenv or \tt putenv have been called.

    However, note that repeated calls to this function will recreate the
    list of environment variables, which is a non-trivial operation.

    \note For new code, it is recommended to use QProcessEnvironment::systemEnvironment()

    \sa QProcessEnvironment::systemEnvironment(), setProcessEnvironment()
*/
QStringList QProcess::systemEnvironment()
{
    QStringList tmp;
    char *entry = 0;
    int count = 0;
    while ((entry = environ[count++]))
        tmp << QString::fromLocal8Bit(entry);
    return tmp;
}

/*!
    \fn QProcessEnvironment QProcessEnvironment::systemEnvironment()

    \since 4.6

    \brief The systemEnvironment function returns the environment of
    the calling process.

    It is returned as a QProcessEnvironment. This function does not
    cache the system environment. Therefore, it's possible to obtain
    an updated version of the environment if low-level C library
    functions like \tt setenv or \tt putenv have been called.

    However, note that repeated calls to this function will recreate the
    QProcessEnvironment object, which is a non-trivial operation.

    \sa QProcess::systemEnvironment()
*/

/*!
    \since 5.2

    \brief The null device of the operating system.

    The returned file path uses native directory separators.

    \sa QProcess::setStandardInputFile(), QProcess::setStandardOutputFile(),
        QProcess::setStandardErrorFile()
*/
QString QProcess::nullDevice()
{
#ifdef Q_OS_WIN
    return QStringLiteral("\\\\.\\NUL");
#elif defined(_PATH_DEVNULL)
    return QStringLiteral(_PATH_DEVNULL);
#else
    return QStringLiteral("/dev/null");
#endif
}

/*!
    \typedef Q_PID
    \relates QProcess

    Typedef for the identifiers used to represent processes on the underlying
    platform. On Unix, this corresponds to \l qint64; on Windows, it
    corresponds to \c{_PROCESS_INFORMATION*}.

    \sa QProcess::pid()
*/

#endif // QT_CONFIG(process)

QT_END_NAMESPACE

#include "moc_qprocess.cpp"
