1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
/*
* Copyright 2013 Red Hat Inc., Durham, North Carolina.
* All Rights Reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Authors:
* Martin Preisler <mpreisle@redhat.com>
*/
#ifndef SCAP_WORKBENCH_PROCESS_HELPERS_H_
#define SCAP_WORKBENCH_PROCESS_HELPERS_H_
#include "ForwardDecls.h"
#include <QObject>
#include <QString>
#include <QStringList>
#include <QProcessEnvironment>
#include <QDialog>
/// This class is never exposed, it is internal only
class ProcessProgressDialog;
/**
* @brief Runs a process and pumps event queue of given thread
*/
class SyncProcess : public QObject
{
Q_OBJECT
public:
explicit SyncProcess(QObject* parent = 0);
virtual ~SyncProcess();
/**
* @brief Sets the main command (without arguments)
*
* This always needs to be called before the SyncProcess::run method is called.
* Command is a strictly required property!
*/
void setCommand(const QString& command);
/**
* @brief Sets all passed arguments
*
* Default is empty.
*/
void setArguments(const QStringList& args);
/**
* @brief Sets the running environment
*
* Default is to inherit the system environment.
*/
void setEnvironment(const QProcessEnvironment& env);
/**
* @brief Sets the working directory
*
* Default is current working directory ("./")
*/
void setWorkingDirectory(const QString& dir);
/**
* @brief Sets external cancel request source (indirect)
*
* The only reason this exists is to accommodate the interface of OscapScannerBase.
* We should move to the cancel() slot in the future.
* @todo Get rid of this non-sense
*/
void setCancelRequestSource(bool* source);
/**
* @brief Runs the SyncProcess, blocks until the process exits
*
* @see SyncProcess::isRunning
* @see SyncProcess::getExitCode
*/
void run();
/**
* @brief Similar to SyncProcess::run, runs the process and shows a dialog of the progress
*
* This method has a limitation compared to SyncProcess::run in the fact that it does
* not fill stdout and stderr outputs with the correct data. It's reading all output
* and immediatelly showing it in the dialog, stdout and stderr will be empty after
* this method finishes!
*/
QDialog* runWithDialog(QWidget* widgetParent, const QString& title,
bool closeAfterFinished = false, bool modal = true);
public slots:
/**
* @brief Requests cancellation
*
* Cancellation will not happen immediately! First SIGTERM is sent to the process.
* If the process fails to respond and exit in 3 seconds SIGKILL is sent.
*/
void cancel();
public:
bool isRunning() const;
void setStdInFile(const QString& path);
const QString& getStdInFile() const;
int getExitCode() const;
const QString& getStdOutContents() const;
const QString& getStdErrContents() const;
const QString& getDiagnosticInfo() const;
protected:
void startQProcess(QProcess& process);
bool wasCancelRequested() const;
virtual QString generateFullCommand() const;
virtual QStringList generateFullArguments() const;
virtual QProcessEnvironment generateFullEnvironment() const;
virtual QString generateDescription() const;
void readAllChannelsIntoDialog(QProcess& process, ProcessProgressDialog& dialog);
QString mCommand;
QStringList mArguments;
QProcessEnvironment mEnvironment;
QString mWorkingDirectory;
/// How often do we poll for status, in msec
unsigned int mPollInterval;
/// How long will we wait for the process to exit after term is signaled, in msec
unsigned int mTermLimit;
bool mRunning;
/// A crappy makeshift synchronization primitive. We should abolish this in the future.
/// It works fine for now because we only change it from within the Qt event loop.
bool* mCancelRequestSource;
/// Was cancellation requested locally (cancel() slot)
bool mLocalCancelRequested;
QString mStdInFile;
int mExitCode;
QString mStdOutContents;
QString mStdErrContents;
QString mDiagnosticInfo;
};
#endif
|