1 /* 2 * This file is a part of QTerminal - http://gitorious.org/qterminal 3 * 4 * This file was un-linked from KDE and modified 5 * by Maxim Bourmistrov <maxim@unixconn.com> 6 * 7 */ 8 9 /* 10 This file is part of the KDE libraries 11 12 Copyright (C) 2007 Oswald Buddenhagen <ossi@kde.org> 13 14 This library is free software; you can redistribute it and/or 15 modify it under the terms of the GNU Library General Public 16 License as published by the Free Software Foundation; either 17 version 2 of the License, or (at your option) any later version. 18 19 This library is distributed in the hope that it will be useful, 20 but WITHOUT ANY WARRANTY; without even the implied warranty of 21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 Library General Public License for more details. 23 24 You should have received a copy of the GNU Library General Public License 25 along with this library; see the file COPYING.LIB. If not, write to 26 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 27 Boston, MA 02110-1301, USA. 28 */ 29 30 #ifndef KPROCESS_H 31 #define KPROCESS_H 32 33 //#include <kdecore_export.h> 34 35 #include <QProcess> 36 37 class KProcessPrivate; 38 39 /** 40 * \class KProcess kprocess.h <KProcess> 41 * 42 * Child process invocation, monitoring and control. 43 * 44 * This class extends QProcess by some useful functionality, overrides 45 * some defaults with saner values and wraps parts of the API into a more 46 * accessible one. 47 * This is the preferred way of spawning child processes in KDE; don't 48 * use QProcess directly. 49 * 50 * @author Oswald Buddenhagen <ossi@kde.org> 51 **/ 52 class KProcess : public QProcess 53 { 54 Q_OBJECT 55 Q_DECLARE_PRIVATE(KProcess) 56 57 public: 58 59 /** 60 * Modes in which the output channels can be opened. 61 */ 62 enum OutputChannelMode { 63 SeparateChannels = QProcess::SeparateChannels, 64 /**< Standard output and standard error are handled by KProcess 65 as separate channels */ 66 MergedChannels = QProcess::MergedChannels, 67 /**< Standard output and standard error are handled by KProcess 68 as one channel */ 69 ForwardedChannels = QProcess::ForwardedChannels, 70 /**< Both standard output and standard error are forwarded 71 to the parent process' respective channel */ 72 OnlyStdoutChannel, 73 /**< Only standard output is handled; standard error is forwarded */ 74 OnlyStderrChannel /**< Only standard error is handled; standard output is forwarded */ 75 }; 76 77 /** 78 * Constructor 79 */ 80 explicit KProcess(QObject *parent = nullptr); 81 82 /** 83 * Destructor 84 */ 85 ~KProcess() override; 86 87 /** 88 * Set how to handle the output channels of the child process. 89 * 90 * The default is ForwardedChannels, which is unlike in QProcess. 91 * Do not request more than you actually handle, as this output is 92 * simply lost otherwise. 93 * 94 * This function must be called before starting the process. 95 * 96 * \param mode the output channel handling mode 97 */ 98 void setOutputChannelMode(OutputChannelMode mode); 99 100 /** 101 * Query how the output channels of the child process are handled. 102 * 103 * \returns the output channel handling mode 104 */ 105 OutputChannelMode outputChannelMode() const; 106 107 /** 108 * Set the QIODevice open mode the process will be opened in. 109 * 110 * This function must be called before starting the process, obviously. 111 * 112 * \param mode the open mode. Note that this mode is automatically 113 * "reduced" according to the channel modes and redirections. 114 * The default is QIODevice::ReadWrite. 115 */ 116 void setNextOpenMode(QIODevice::OpenMode mode); 117 118 /** 119 * Adds the variable @p name to the process' environment. 120 * 121 * This function must be called before starting the process. 122 * 123 * \param name the name of the environment variable 124 * \param value the new value for the environment variable 125 * \param overwrite if \c false and the environment variable is already 126 * set, the old value will be preserved 127 */ 128 void setEnv(const QString &name, const QString &value, bool overwrite = true); 129 130 /** 131 * Removes the variable @p name from the process' environment. 132 * 133 * This function must be called before starting the process. 134 * 135 * \param name the name of the environment variable 136 */ 137 void unsetEnv(const QString &name); 138 139 /** 140 * Empties the process' environment. 141 * 142 * Note that LD_LIBRARY_PATH/DYLD_LIBRARY_PATH is automatically added 143 * on *NIX. 144 * 145 * This function must be called before starting the process. 146 */ 147 void clearEnvironment(); 148 149 /** 150 * Set the program and the command line arguments. 151 * 152 * This function must be called before starting the process, obviously. 153 * 154 * \param exe the program to execute 155 * \param args the command line arguments for the program, 156 * one per list element 157 */ 158 void setProgram(const QString &exe, const QStringList &args = QStringList()); 159 160 /** 161 * @overload 162 * 163 * \param argv the program to execute and the command line arguments 164 * for the program, one per list element 165 */ 166 void setProgram(const QStringList &argv); 167 168 /** 169 * Append an element to the command line argument list for this process. 170 * 171 * If no executable is set yet, it will be set instead. 172 * 173 * For example, doing an "ls -l /usr/local/bin" can be achieved by: 174 * \code{.cpp} 175 * KProcess p; 176 * p << "ls" << "-l" << "/usr/local/bin"; 177 * ... 178 * \endcode 179 * 180 * This function must be called before starting the process, obviously. 181 * 182 * \param arg the argument to add 183 * \returns a reference to this KProcess 184 */ 185 KProcess &operator<<(const QString& arg); 186 187 /** 188 * @overload 189 * 190 * \param args the arguments to add 191 * \returns a reference to this KProcess 192 */ 193 KProcess &operator<<(const QStringList& args); 194 195 /** 196 * Clear the program and command line argument list. 197 */ 198 void clearProgram(); 199 200 /** 201 * Set a command to execute through a shell (a POSIX sh on *NIX 202 * and cmd.exe on Windows). 203 * 204 * Using this for anything but user-supplied commands is usually a bad 205 * idea, as the command's syntax depends on the platform. 206 * Redirections including pipes, etc. are better handled by the 207 * respective functions provided by QProcess. 208 * 209 * If KProcess determines that the command does not really need a 210 * shell, it will transparently execute it without one for performance 211 * reasons. 212 * 213 * This function must be called before starting the process, obviously. 214 * 215 * \param cmd the command to execute through a shell. 216 * The caller must make sure that all filenames etc. are properly 217 * quoted when passed as argument. Failure to do so often results in 218 * serious security holes. See KShell::quoteArg(). 219 */ 220 void setShellCommand(const QString &cmd); 221 222 /** 223 * Obtain the currently set program and arguments. 224 * 225 * \returns a list, the first element being the program, the remaining ones 226 * being command line arguments to the program. 227 */ 228 QStringList program() const; 229 230 /** 231 * Start the process. 232 * 233 * \see QProcess::start(const QString &, const QStringList &, OpenMode) 234 */ 235 void start(); 236 237 /** 238 * Start the process, wait for it to finish, and return the exit code. 239 * 240 * This method is roughly equivalent to the sequence: 241 * <code> 242 * start(); 243 * waitForFinished(msecs); 244 * return exitCode(); 245 * </code> 246 * 247 * Unlike the other execute() variants this method is not static, 248 * so the process can be parametrized properly and talked to. 249 * 250 * \param msecs time to wait for process to exit before killing it 251 * \returns -2 if the process could not be started, -1 if it crashed, 252 * otherwise its exit code 253 */ 254 int execute(int msecs = -1); 255 256 /** 257 * @overload 258 * 259 * \param exe the program to execute 260 * \param args the command line arguments for the program, 261 * one per list element 262 * \param msecs time to wait for process to exit before killing it 263 * \returns -2 if the process could not be started, -1 if it crashed, 264 * otherwise its exit code 265 */ 266 static int execute(const QString &exe, const QStringList &args = QStringList(), int msecs = -1); 267 268 /** 269 * @overload 270 * 271 * \param argv the program to execute and the command line arguments 272 * for the program, one per list element 273 * \param msecs time to wait for process to exit before killing it 274 * \returns -2 if the process could not be started, -1 if it crashed, 275 * otherwise its exit code 276 */ 277 static int execute(const QStringList &argv, int msecs = -1); 278 279 /** 280 * Start the process and detach from it. See QProcess::startDetached() 281 * for details. 282 * 283 * Unlike the other startDetached() variants this method is not static, 284 * so the process can be parametrized properly. 285 * \note Currently, only the setProgram()/setShellCommand() and 286 * setWorkingDirectory() parametrizations are supported. 287 * 288 * The KProcess object may be re-used immediately after calling this 289 * function. 290 * 291 * \returns the PID of the started process or 0 on error 292 */ 293 int startDetached(); 294 295 /** 296 * @overload 297 * 298 * \param exe the program to start 299 * \param args the command line arguments for the program, 300 * one per list element 301 * \returns the PID of the started process or 0 on error 302 */ 303 static int startDetached(const QString &exe, const QStringList &args = QStringList()); 304 305 /** 306 * @overload 307 * 308 * \param argv the program to start and the command line arguments 309 * for the program, one per list element 310 * \returns the PID of the started process or 0 on error 311 */ 312 static int startDetached(const QStringList &argv); 313 314 /** 315 * Obtain the process' ID as known to the system. 316 * 317 * Unlike with QProcess::pid(), this is a real PID also on Windows. 318 * 319 * This function can be called only while the process is running. 320 * It cannot be applied to detached processes. 321 * 322 * \returns the process ID 323 */ 324 int pid() const; 325 326 protected: 327 /** 328 * @internal 329 */ 330 KProcess(KProcessPrivate *d, QObject *parent); 331 332 /** 333 * @internal 334 */ 335 KProcessPrivate * const d_ptr; 336 337 private: 338 // hide those 339 using QProcess::setReadChannelMode; 340 using QProcess::readChannelMode; 341 using QProcess::setProcessChannelMode; 342 using QProcess::processChannelMode; 343 344 Q_PRIVATE_SLOT(d_func(), void _k_forwardStdout()) 345 Q_PRIVATE_SLOT(d_func(), void _k_forwardStderr()) 346 }; 347 348 /* ----------- kprocess_p.h ---------------- */ 349 class KProcessPrivate { 350 Q_DECLARE_PUBLIC(KProcess)351 Q_DECLARE_PUBLIC(KProcess) 352 353 protected: 354 KProcessPrivate() : 355 openMode(QIODevice::ReadWrite) 356 { 357 } 358 void writeAll(const QByteArray &buf, int fd); 359 void forwardStd(KProcess::ProcessChannel good, int fd); 360 void _k_forwardStdout(); 361 void _k_forwardStderr(); 362 363 QString prog; 364 QStringList args; 365 KProcess::OutputChannelMode outputChannelMode = KProcess::SeparateChannels; // arbitrary value 366 QIODevice::OpenMode openMode; 367 368 KProcess *q_ptr = nullptr; 369 }; 370 /* ------------------------------------------- */ 371 #endif 372 373