MythTV  master
mythsystemlegacy.h
Go to the documentation of this file.
1 /* -*- Mode: c++ -*-
2  * Class MythSystemLegacy
3  *
4  * Copyright (C) Gavin Hurlbut 2012
5  * Copyright (C) Issac Richards 2008
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #ifndef _MYTHSYSTEMLEGACY_H_
23 #define _MYTHSYSTEMLEGACY_H_
24 
25 #include "mythbaseexp.h"
26 
27 // Note: The FIXME were added 2013-05-18, as part of a multi-pass
28 // cleanup of MythSystemLegacy.
29 //
30 // MythSystemLegacy exists because the Qt QProcess has caused us numerous
31 // headaches, most importantly:
32 // http://code.mythtv.org/trac/ticket/7135
33 // https://bugreports.qt-project.org/browse/QTBUG-5990
34 // QProcess also demands that the thread in which it is used
35 // and created run a Qt event loop, which MythSystemLegacy does not
36 // require. A number of MythTV threads do not run an event loop
37 // so this requirement is a bit onerous.
38 //
39 // MythSystemLegacy has grown a bit fat around the middle as functionality
40 // has been added and as a core functionality class is due for a code
41 // review and some cleanup.
42 
43 // C headers
44 #include <cstdint>
45 #include <ctime>
46 
47 #ifdef __cplusplus
48 
49 #include "exitcodes.h" // included for GENERIC_EXIT_OK
50 #include "mythsystem.h" // included for MythSystemFlag and MythSignal
51 
52 #include <QStringList>
53 #include <QSemaphore>
54 #include <QBuffer>
55 #include <QObject>
56 #include <QString>
57 #include <QMap> // FIXME: This shouldn't be needed, Setting_t is not public
58 
59 using Setting = QMap<QString, bool>;
60 
62 
63 // FIXME: Does MythSystemLegacy really need to inherit from QObject?
64 // we can probably create a private class that inherits
65 // from QObject to avoid exposing lots of thread-unsafe
66 // methods & complicated life-time management.
68 class MBASE_PUBLIC MythSystemLegacy : public QObject
69 {
70  Q_OBJECT;
71 
72  public:
73  explicit MythSystemLegacy(QObject * = nullptr);
74  MythSystemLegacy(const QString &, uint, QObject * = nullptr);
75  MythSystemLegacy(const QString &, const QStringList &, uint,
76  QObject * = nullptr);
77  ~MythSystemLegacy(void);
78 
79  // FIXME: We should not allow a MythSystemLegacy to be reused for a new command.
80  void SetCommand(const QString &, uint);
81  // FIXME: We should not allow a MythSystemLegacy to be reused for a new command.
82  void SetCommand(const QString &, const QStringList &, uint);
83  // FIXME: This should only be in the constructor
84  void SetDirectory(const QString &);
85  // FIXME: This should only be in the constructor
86  bool SetNice(int nice);
87  // FIXME: This should only be in the constructor
88  bool SetIOPrio(int prio);
89 
90  // FIXME: Forks, should be called Start() for consistency with MThread.
91  // FIXME: Do we need this call at all?
92  void Run(time_t timeout = 0);
93  // FIXME: This should just return a bool telling us if we hit the timeout.
94  uint Wait(time_t timeout = 0);
95 
96  int Write(const QByteArray&);
97  QByteArray Read(int size);
98  QByteArray ReadErr(int size);
99  // FIXME: We should not return a reference here
100  QByteArray& ReadAll();
101  // FIXME: We should not return a reference here
102  QByteArray& ReadAllErr();
103 
104  // FIXME: Can Term be wrapped into Signal?
105  void Term(bool force = false);
106  void Signal(MythSignal);
107 
108  // FIXME: Should be IsBackground() + documented
109  bool isBackground(void) { return GetSetting("RunInBackground"); }
110  // FIXME: Should be IsAutoCleanupProcess() + documented
111  bool doAutoCleanup(void) { return GetSetting("AutoCleanup"); }
112  // FIXME: No idea what this is querying but should be StudlyCase
113  // and should be documented
114  bool onlyLowExitVal(void) { return GetSetting("OnlyLowExitVal"); }
115  // FIXME: Why is this public?
116  void HandlePreRun(void);
117  // FIXME: Why is this public?
118  void HandlePostRun(void);
119 
120  // FIXME: Rename "GetExitStatus" and document that this does not
121  // block until an exit status exists.
122  // FIXME: Document what this actually returns.
123  uint GetStatus(void) { return m_status; }
124  // FIXME Make private.
125  void SetStatus(uint status) { m_status = status; }
126 
127  // FIXME: We should not return a reference here, add a Set if necessary
128  // Do we even need this function? Should it then be better named?
129  QString& GetLogCmd(void) { return m_logcmd; }
130  // FIXME: We should not return a reference here
131  QString& GetDirectory(void) { return m_directory; }
132 
133  // FIXME: Eliminate or make private, we don't allow any settings
134  // that can not be enumerated.
135  bool GetSetting(const char *setting)
136  { return m_settings.value(QString(setting)); }
137 
138  // FIXME: We should not return a reference here
139  QString& GetCommand(void) { return m_command; }
140  // FIXME: Eliminate. We should not allow setting the command
141  // after construcion.
142  void SetCommand(QString &cmd) { m_command = cmd; }
143 
144  // FIXME: We should not return a reference here
145  // FIXME: Rename "GetArguments"
146  QStringList &GetArgs(void) { return m_args; }
147  // FIXME: Eliminate. We should not allow setting the arguements
148  // after construcion.
149  void SetArgs(QStringList &args) { m_args = args; }
150 
151  int GetNice(void) { return m_nice; }
152  int GetIOPrio(void) { return m_ioprio; }
153 
154  // FIXME: We should not return a pointer to a QBuffer
155  QBuffer *GetBuffer(int index) { return &m_stdbuff[index]; }
156 
157  // FIXME: We should not make locking public
158  void Unlock(void) { m_semReady.release(1); }
159 
161 
162  // FIXME: This should be an independent function living elsewhere
163  static QString ShellEscape(const QString &in);
164 
165  // FIXME: Do we really need to expose Qt signals?
166  // If so why are they lower case?
167  signals:
168  void started(void);
169  void finished(void);
170  void error(uint status);
171  void readDataReady(int fd);
172 
173  private:
174  Q_DISABLE_COPY(MythSystemLegacy)
175  void initializePrivate(void);
176  MythSystemLegacyPrivate *d {nullptr}; // FIXME we generally call this m_priv in MythTV
177 
178  protected:
179  void ProcessFlags(uint flags);
180 
181  // FIXME if we already have a private helper, why all this?
182  uint m_status {GENERIC_EXIT_OK};
183  QSemaphore m_semReady;
184 
185  QString m_command;
186  QString m_logcmd;
187  QStringList m_args;
188  QString m_directory;
189 
190  int m_nice {0};
191  int m_ioprio {0};
192 
194  QBuffer m_stdbuff[3];
195 };
196 
197 MBASE_PUBLIC uint myth_system(const QString &command,
198  uint flags = kMSNone,
199  uint timeout = 0);
200 #endif // __cplusplus
201 
202 #ifdef __cplusplus
203 extern "C"
204 #endif // __cplusplus
205 MBASE_PUBLIC uint myth_system_c(char *command, uint flags, uint timeout);
206 
207 #endif // _MYTHSYSTEMLEGACY_H_
208 /*
209  * vim:ts=4:sw=4:ai:et:si:sts=4
210  */
bool onlyLowExitVal(void)
#define GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:10
bool isBackground(void)
QBuffer * GetBuffer(int index)
static void error(const char *str,...)
Definition: vbi.c:42
void SetArgs(QStringList &args)
QStringList & GetArgs(void)
QString & GetLogCmd(void)
#define MBASE_PUBLIC
Definition: mythbaseexp.h:15
void SetStatus(uint status)
static const uint16_t * d
void readDataReady(int fd)
#define nice(x)
Definition: compat.h:195
unsigned int uint
Definition: compat.h:140
void MBASE_PUBLIC ShutdownMythSystemLegacy(void)
bool doAutoCleanup(void)
MBASE_PUBLIC uint myth_system(const QString &command, uint flags=kMSNone, uint timeout=0)
QString & GetDirectory(void)
MythSignal
Definition: mythsystem.h:54
bool GetSetting(const char *setting)
void SetCommand(QString &cmd)
MBASE_PUBLIC uint myth_system_c(char *command, uint flags, uint timeout)
QString & GetCommand(void)
QMap< QString, bool > Setting