1 /*
2     SPDX-FileCopyrightText: 2009 Nokia Corporation and /or its subsidiary(-ies).
3     Contact: Qt Software Information (qt-info@nokia.com)
4 
5     This file is part of the QtCore module of the Qt Toolkit.
6 
7     $QT_BEGIN_LICENSE:LGPL$
8     Commercial Usage
9     Licensees holding valid Qt Commercial licenses may use this file in
10     accordance with the Qt Commercial License Agreement provided with the
11     Software or, alternatively, in accordance with the terms contained in
12     a written agreement between you and Nokia.
13 
14     GNU Lesser General Public License Usage
15     Alternatively, this file may be used under the terms of the GNU Lesser
16     General Public License version 2.1 as published by the Free Software
17     Foundation and appearing in the file LICENSE.LGPL included in the
18     packaging of this file.  Please review the following information to
19     ensure the GNU Lesser General Public License version 2.1 requirements
20     will be met: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
21 
22     In addition, as a special exception, Nokia gives you certain
23     additional rights. These rights are described in the Nokia Qt LGPL
24     Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
25     package.
26 
27     GNU General Public License Usage
28     Alternatively, this file may be used under the terms of the GNU
29     General Public License version 3.0 as published by the Free Software
30     Foundation and appearing in the file LICENSE.GPL included in the
31     packaging of this file.  Please review the following information to
32     ensure the GNU General Public License version 3.0 requirements will be
33     met: https://www.gnu.org/licenses/gpl-3.0.html.
34 
35     If you are unsure which license is appropriate for your use, please
36     contact the sales department at qt-sales@nokia.com.
37     $QT_END_LICENSE$
38 
39 */
40 
41 #ifndef K3B_QPROCESS_H
42 #define K3B_QPROCESS_H
43 
44 #include <qiodevice.h>
45 #include <QStringList>
46 #include <qprocess.h>
47 
48 #include "k3b_export.h"
49 
50 // QT_BEGIN_HEADER
51 
52 // QT_BEGIN_NAMESPACE
53 
54 // QT_MODULE(Core)
55 
56 #ifndef QT_NO_PROCESS
57 
58 #if (!defined(Q_OS_WIN32) && !defined(Q_OS_WINCE)) || defined(qdoc)
59 typedef qint64 Q_PID;
60 #else
61 QT_END_NAMESPACE
62 typedef struct _PROCESS_INFORMATION *Q_PID;
63 QT_BEGIN_NAMESPACE
64 #endif
65 
66 class K3bQProcessPrivate;
67 
68 class LIBK3B_EXPORT K3bQProcess : public QIODevice
69 {
70     Q_OBJECT
71 public:
72     // BE AWARE: we use the original enums from QProcess to make the future transition of slots easier
73     /*
74     enum ProcessError {
75         FailedToStart, //### file not found, resource error
76         Crashed,
77         Timedout,
78         ReadError,
79         WriteError,
80         UnknownError
81     };
82     enum ProcessState {
83         NotRunning,
84         Starting,
85         Running
86     };
87     enum ProcessChannel {
88         StandardOutput,
89         StandardError
90     };
91     enum ProcessChannelMode {
92         SeparateChannels,
93         MergedChannels,
94         ForwardedChannels
95     };
96     enum ExitStatus {
97         NormalExit,
98         CrashExit
99     };
100     */
101     enum ProcessFlag {
102         NoFlags = 0x0,
103         RawStdin = 0x1,
104         RawStdout = 0x2
105     };
106     Q_DECLARE_FLAGS( ProcessFlags, ProcessFlag )
107 
108     explicit K3bQProcess(QObject *parent = 0);
109     ~K3bQProcess() override;
110 
111     void start(const QString &program, const QStringList &arguments, OpenMode mode = ReadWrite);
112     void start(const QString &program, OpenMode mode = ReadWrite);
113 
114     ::QProcess::ProcessChannelMode readChannelMode() const;
115     void setReadChannelMode(::QProcess::ProcessChannelMode mode);
116     ::QProcess::ProcessChannelMode processChannelMode() const;
117     void setProcessChannelMode(::QProcess::ProcessChannelMode mode);
118 
119     ProcessFlags flags() const;
120     void setFlags( ProcessFlags flags );
121 
122     ::QProcess::ProcessChannel readChannel() const;
123     void setReadChannel(::QProcess::ProcessChannel channel);
124 
125     void closeReadChannel(::QProcess::ProcessChannel channel);
126     void closeWriteChannel();
127 
128     void setStandardInputFile(const QString &fileName);
129     void setStandardOutputFile(const QString &fileName, OpenMode mode = Truncate);
130     void setStandardErrorFile(const QString &fileName, OpenMode mode = Truncate);
131     void setStandardOutputProcess(K3bQProcess *destination);
132 
133     QString workingDirectory() const;
134     void setWorkingDirectory(const QString &dir);
135 
136     void setEnvironment(const QStringList &environment);
137     QStringList environment() const;
138 
139     ::QProcess::ProcessError error() const;
140     ::QProcess::ProcessState state() const;
141 
142     // #### Qt 5: Q_PID is a pointer on Windows and a value on Unix
143     Q_PID pid() const;
144 
145     bool waitForStarted(int msecs = 30000);
146     bool waitForReadyRead(int msecs = 30000) override;
147     bool waitForBytesWritten(int msecs = 30000) override;
148     bool waitForFinished(int msecs = 30000);
149 
150     QByteArray readAllStandardOutput();
151     QByteArray readAllStandardError();
152 
153     int exitCode() const;
154     ::QProcess::ExitStatus exitStatus() const;
155 
156     // QIODevice
157     qint64 bytesAvailable() const override;
158     qint64 bytesToWrite() const override;
159     bool isSequential() const override;
160     bool canReadLine() const override;
161     void close() override;
162     bool atEnd() const override;
163 
164     bool isReadyWrite() const;
165 
166     static int execute(const QString &program, const QStringList &arguments);
167     static int execute(const QString &program);
168 
169     static bool startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory,
170                               qint64 *pid = 0);
171     static bool startDetached(const QString &program, const QStringList &arguments);
172     static bool startDetached(const QString &program);
173 
174     static QStringList systemEnvironment();
175 
176 public Q_SLOTS:
177     void terminate();
178     void kill();
179 
180 Q_SIGNALS:
181     void started();
182     void finished(int exitCode);
183     void finished(int exitCode, QProcess::ExitStatus exitStatus);
184     void error(QProcess::ProcessError error);
185     void stateChanged(QProcess::ProcessState state);
186 
187     void readyReadStandardOutput();
188     void readyReadStandardError();
189     void readyWrite();
190 
191 protected:
192     void setProcessState(QProcess::ProcessState state);
193 
194     virtual void setupChildProcess();
195 
196     // QIODevice
197     qint64 readData(char *data, qint64 maxlen) override;
198     qint64 writeData(const char *data, qint64 len) override;
199 
200 private:
201     Q_DECLARE_PRIVATE(K3bQProcess)
202     Q_DISABLE_COPY(K3bQProcess)
203 
204     K3bQProcessPrivate* d_ptr;
205 
206     Q_PRIVATE_SLOT(d_func(), bool _q_canReadStandardOutput())
207     Q_PRIVATE_SLOT(d_func(), bool _q_canReadStandardError())
208     Q_PRIVATE_SLOT(d_func(), bool _q_canWrite())
209     Q_PRIVATE_SLOT(d_func(), bool _q_startupNotification())
210     Q_PRIVATE_SLOT(d_func(), bool _q_processDied())
211     Q_PRIVATE_SLOT(d_func(), bool _q_notifyProcessDied())
212     Q_PRIVATE_SLOT(d_func(), void _q_notified())
213     friend class K3bQProcessManager;
214 };
215 
216 #endif // QT_NO_PROCESS
217 
218 // QT_END_NAMESPACE
219 
220 // QT_END_HEADER
221 
222 Q_DECLARE_OPERATORS_FOR_FLAGS( K3bQProcess::ProcessFlags )
223 
224 #endif // QPROCESS_H
225