1
/****************************************************************************
2
**
3
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4
** All rights reserved.
5
** Contact: Nokia Corporation (qt-info@nokia.com)
6
**
7
** This file is part of the QtCore module of the Qt Toolkit.
8
**
9
** $QT_BEGIN_LICENSE:LGPL$
10
** No Commercial Usage
11
** This file contains pre-release code and may not be distributed.
12
** You may use this file in accordance with the terms and conditions
13
** contained in the Technology Preview License Agreement accompanying
14
** this package.
15
**
16
** GNU Lesser General Public License Usage
17
** Alternatively, this file may be used under the terms of the GNU Lesser
18
** General Public License version 2.1 as published by the Free Software
19
** Foundation and appearing in the file LICENSE.LGPL included in the
20
** packaging of this file.  Please review the following information to
21
** ensure the GNU Lesser General Public License version 2.1 requirements
22
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23
**
24
** In addition, as a special exception, Nokia gives you certain additional
25
** rights.  These rights are described in the Nokia Qt LGPL Exception
26
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27
**
28
** If you have questions regarding the use of this file, please contact
29
** Nokia at qt-info@nokia.com.
30
**
31
**
32
**
33
**
34
**
35
**
36
**
37
**
38
** $QT_END_LICENSE$
39
**
40
****************************************************************************/
41
42
#ifndef QPROCESS_P_H
43
#define QPROCESS_P_H
44
45
//
46
//  W A R N I N G
47
//  -------------
48
//
49
// This file is not part of the Qt API.  It exists purely as an
50
// implementation detail.  This header file may change from version to
51
// version without notice, or even be removed.
52
//
53
// We mean it.
54
//
55
56
#include "QtCore/qprocess.h"
57
#include "QtCore/qstringlist.h"
58
#include "private/qringbuffer_p.h"
59
#include "private/qiodevice_p.h"
60
61
#ifdef Q_OS_WIN
62
#include "QtCore/qt_windows.h"
63
typedef HANDLE Q_PIPE;
64
#define INVALID_Q_PIPE INVALID_HANDLE_VALUE
65
#else
66
typedef int Q_PIPE;
67
#define INVALID_Q_PIPE -1
68
#endif
69
70
#ifndef QT_NO_PROCESS
71
72
QT_BEGIN_NAMESPACE
73
74
class QSocketNotifier;
75
class QWindowsPipeWriter;
76
class QWinEventNotifier;
77
class QTimer;
78
79
class QProcessPrivate : public QIODevicePrivate
80
{
81
public:
82
    Q_DECLARE_PUBLIC(QProcess)
83
84
    struct Channel {
85
        enum ProcessChannelType {
86
            Normal = 0,
87
            PipeSource = 1,
88
            PipeSink = 2,
89
            Redirect = 3
90
            // if you add "= 4" here, increase the number of bits below
91
        };
92
93
        Channel() : process(0), notifier(0), type(Normal), closed(false), append(false)
94
        {
95
            pipe[0] = INVALID_Q_PIPE;
96
            pipe[1] = INVALID_Q_PIPE;
97
        }
98
99
        void clear();
100
101
        Channel &operator=(const QString &fileName)
102
        {
103
            clear();
104
            file = fileName;
105
            type = fileName.isEmpty() ? Normal : Redirect;
106
            return *this;
107
        }
108
109
        void pipeTo(QProcessPrivate *other)
110
        {
111
            clear();
112
            process = other;
113
            type = PipeSource;
114
        }
115
116
        void pipeFrom(QProcessPrivate *other)
117
        {
118
            clear();
119
            process = other;
120
            type = PipeSink;
121
        }
122
123
        QString file;
124
        QProcessPrivate *process;
125
        QSocketNotifier *notifier;
126
        Q_PIPE pipe[2];
127
128
        unsigned type : 2;
129
        bool closed : 1;
130
        bool append : 1;
131
    };
132
133
    QProcessPrivate();
134
    virtual ~QProcessPrivate();
135
136
    // private slots
137
    bool _q_canReadStandardOutput();
138
    bool _q_canReadStandardError();
139
    bool _q_canWrite();
140
    bool _q_startupNotification();
141
    bool _q_processDied();
142
    void _q_notified();
143
144
    QProcess::ProcessChannel processChannel;
145
    QProcess::ProcessChannelMode processChannelMode;
146
    QProcess::ProcessError processError;
147
    QProcess::ProcessState processState;
148
    QString workingDirectory;
149
    Q_PID pid;
150
    int sequenceNumber;
151
152
    bool dying;
153
    bool emittedReadyRead;
154
    bool emittedBytesWritten;
155
156
    Channel stdinChannel;
157
    Channel stdoutChannel;
158
    Channel stderrChannel;
159
    bool createChannel(Channel &channel);
160
    void closeWriteChannel();
161
162
    QString program;
163
    QStringList arguments;
164
    QStringList environment;
165
166
    QRingBuffer outputReadBuffer;
167
    QRingBuffer errorReadBuffer;
168
    QRingBuffer writeBuffer;
169
170
    Q_PIPE childStartedPipe[2];
171
    Q_PIPE deathPipe[2];
172
    void destroyPipe(Q_PIPE pipe[2]);
173
174
    QSocketNotifier *startupSocketNotifier;
175
    QSocketNotifier *deathNotifier;
176
177
    // the wonderful windows notifier
178
    QTimer *notifier;
179
    QWindowsPipeWriter *pipeWriter;
180
    QWinEventNotifier *processFinishedNotifier;
181
182
    void startProcess();
183
#ifdef Q_OS_UNIX
184
    void execChild(const char *workingDirectory, char **path, char **argv, char **envp);
185
#endif
186
    bool processStarted();
187
    void terminateProcess();
188
    void killProcess();
189
    void findExitCode();
190
#ifdef Q_OS_UNIX
191
    bool waitForDeadChild();
192
#endif
193
#ifdef Q_OS_WIN
194
    void flushPipeWriter();
195
    qint64 pipeWriterBytesToWrite() const;
196
#endif
197
198
    static bool startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory = QString(),
199
                              qint64 *pid = 0);
200
201
    int exitCode;
202
    QProcess::ExitStatus exitStatus;
203
    bool crashed;
204
#ifdef Q_OS_UNIX
205
    int serial;
206
#endif
207
208
    bool waitForStarted(int msecs = 30000);
209
    bool waitForReadyRead(int msecs = 30000);
210
    bool waitForBytesWritten(int msecs = 30000);
211
    bool waitForFinished(int msecs = 30000);
212
    bool waitForWrite(int msecs = 30000);
213
214
    qint64 bytesAvailableFromStdout() const;
215
    qint64 bytesAvailableFromStderr() const;
216
    qint64 readFromStdout(char *data, qint64 maxlen);
217
    qint64 readFromStderr(char *data, qint64 maxlen);
218
    qint64 writeToStdin(const char *data, qint64 maxlen);
219
220
    void cleanup();
221
#ifdef Q_OS_UNIX
222
    static void initializeProcessManager();
223
#endif
224
};
225
226
QT_END_NAMESPACE
227
228
#endif // QT_NO_PROCESS
229
230
#endif // QPROCESS_P_H