File: ProcessHelpers.h

package info (click to toggle)
scap-workbench 1.2.1-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 3,292 kB
  • sloc: cpp: 7,519; sh: 205; xml: 38; ansic: 15; makefile: 13
file content (158 lines) | stat: -rw-r--r-- 5,202 bytes parent folder | download
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