~ubuntu-branches/ubuntu/oneiric/valkyrie/oneiric

« back to all changes in this revision

Viewing changes to valkyrie/tool_utils/vk_process.h

  • Committer: Bazaar Package Importer
  • Author(s): Hai Zaar
  • Date: 2009-05-06 14:48:00 UTC
  • Revision ID: james.westby@ubuntu.com-20090506144800-vw617m4d4qa2pam3
Tags: upstream-1.4.0
ImportĀ upstreamĀ versionĀ 1.4.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ---------------------------------------------------------------------- 
 
2
 * Definition of class VKProcess                            vk_process.h
 
3
 * ---------------------------------------------------------------------
 
4
 * This file is part of Valkyrie, a front-end for Valgrind
 
5
 * Copyright (C) 2005-2008, OpenWorks LLP <info@open-works.co.uk>
 
6
 * This program is released under the terms of the GNU GPL v.2
 
7
 * See the file COPYING for the full license details.
 
8
 * ---------------------------------------------------------------------
 
9
 * This file is a re-implementation of QProcess:
 
10
 * ** $Id: qt/qprocess.h   3.3.4   edited May 27 2003 $
 
11
 * ** Created : 20000905
 
12
 * **
 
13
 * ** Copyright (C) 1992-2000 Trolltech AS.  All rights reserved.
 
14
 * **
 
15
 * ** This file may be distributed and/or modified under the terms of the
 
16
 * ** GNU General Public License version 2 as published by the Free Software
 
17
 * ** Foundation and appearing in the file COPYING included in the
 
18
 * ** packaging of this file.
 
19
 */
 
20
 
 
21
#ifndef VK_PROCESS_H
 
22
#define VK_PROCESS_H
 
23
 
 
24
#include <qobject.h>
 
25
#include <qstringlist.h>
 
26
#include <qdir.h>
 
27
#include <qptrqueue.h>
 
28
#include <qsocketnotifier.h>
 
29
 
 
30
#include <signal.h>
 
31
#include <stdlib.h>            // ssize_t
 
32
 
 
33
 
 
34
class VKMembuf
 
35
{
 
36
public:
 
37
   VKMembuf();
 
38
   ~VKMembuf();
 
39
 
 
40
   void append( QByteArray *ba );
 
41
   void clear();
 
42
 
 
43
   bool consumeBytes( Q_ULONG nbytes, char *sink );
 
44
   QByteArray readAll();
 
45
   bool scanNewline( QByteArray *store );
 
46
   bool canReadLine() const;
 
47
 
 
48
   int ungetch( int ch );
 
49
 
 
50
   QIODevice::Offset size() const;
 
51
 
 
52
private:
 
53
   QPtrList<QByteArray> *buf;
 
54
   QIODevice::Offset _size;
 
55
   QIODevice::Offset _index;
 
56
};
 
57
 
 
58
inline void VKMembuf::append( QByteArray *ba )
 
59
{ buf->append( ba ); _size += ba->size(); }
 
60
 
 
61
inline void VKMembuf::clear()
 
62
{ buf->clear(); _size=0; _index=0; }
 
63
 
 
64
inline QByteArray VKMembuf::readAll()
 
65
{ QByteArray ba(_size); consumeBytes(_size,ba.data()); return ba; }
 
66
 
 
67
inline bool VKMembuf::canReadLine() const
 
68
{ return ((VKMembuf*)this)->scanNewline( 0 ); }
 
69
 
 
70
inline QIODevice::Offset VKMembuf::size() const
 
71
{ return _size; }
 
72
 
 
73
 
 
74
 
 
75
 
 
76
/* class VKProc --------------------------------------------------------------
 
77
   The class VKProcess does not necessarily map exactly to the running
 
78
   child processes: if the process is finished, the VKProcess class
 
79
   may still be there; furthermore a user can use VKProcess to start
 
80
   more than one process.
 
81
   The helper-class VKProc has the semantics that one instance of this
 
82
   class maps directly to a running child process. */
 
83
class VKProcess;
 
84
 
 
85
class VKProc
 
86
{
 
87
public:
 
88
   VKProc( pid_t p, VKProcess *proc=0 );
 
89
   ~VKProc();
 
90
 
 
91
   pid_t pid;
 
92
   int socketFDin;
 
93
   int socketFDout;
 
94
   int socketStdin;
 
95
   int socketStdout;
 
96
   int socketStderr;
 
97
   VKProcess *process;
 
98
};
 
99
 
 
100
 
 
101
 
 
102
/* class VKProcessManager ---------------------------------------------------- */
 
103
class VKProcessManager : public QObject
 
104
{
 
105
   Q_OBJECT
 
106
public:
 
107
   VKProcessManager();
 
108
   ~VKProcessManager();
 
109
 
 
110
   void append( VKProc *p );
 
111
   void remove( VKProc *p );
 
112
 
 
113
   void cleanup();
 
114
 
 
115
   public slots:
 
116
      void removeMe();
 
117
   void sigchldHnd( int );
 
118
 
 
119
public:
 
120
   struct sigaction oldactChld;
 
121
   struct sigaction oldactPipe;
 
122
   QPtrList<VKProc> *procList;
 
123
   int sigchldFd[2];
 
124
 
 
125
private:
 
126
   QSocketNotifier *sn;
 
127
};
 
128
 
 
129
 
 
130
 
 
131
 
 
132
/* class VKProcess ----------------------------------------------------------- */
 
133
class VKProcessPrivate
 
134
{
 
135
public:
 
136
   VKProcessPrivate();
 
137
   ~VKProcessPrivate();
 
138
 
 
139
   void closeOpenSocketsForChild();
 
140
   void newProc( pid_t pid, VKProcess *process );
 
141
 
 
142
   VKMembuf bufFDout;
 
143
   VKMembuf bufStdout;
 
144
   VKMembuf bufStderr;
 
145
 
 
146
   QPtrQueue<QByteArray> fdinBuf;
 
147
   QPtrQueue<QByteArray> stdinBuf;
 
148
 
 
149
   QSocketNotifier *notifierFDin;
 
150
   QSocketNotifier *notifierFDout;
 
151
   QSocketNotifier *notifierStdin;
 
152
   QSocketNotifier *notifierStdout;
 
153
   QSocketNotifier *notifierStderr;
 
154
 
 
155
   ssize_t fdinBufRead;
 
156
   ssize_t stdinBufRead;
 
157
   VKProc *proc;
 
158
 
 
159
   bool exitValuesCalculated;
 
160
   bool socketReadCalled;
 
161
 
 
162
   static VKProcessManager *procManager;
 
163
};
 
164
 
 
165
 
 
166
class VKProcess : public QObject
 
167
{
 
168
   Q_OBJECT
 
169
public:
 
170
   VKProcess( QObject *parent=0, const char *name=0 );
 
171
   VKProcess( const QString& arg0, QObject *parent=0, const char *name=0 );
 
172
   VKProcess( const QStringList& args, QObject *parent=0, const char *name=0 );
 
173
   ~VKProcess();
 
174
 
 
175
   // set and get the arguments and working directory
 
176
   QStringList arguments() const;
 
177
   void clearArguments();
 
178
   virtual void setArguments( const QStringList& args );
 
179
   virtual void addArgument( const QString& arg );
 
180
#ifndef QT_NO_DIR
 
181
   QDir workingDirectory() const;
 
182
   virtual void setWorkingDirectory( const QDir& dir );
 
183
#endif
 
184
 
 
185
   // set and get the comms wanted
 
186
   enum Communication { Stdin=0x01, Stdout=0x02, Stderr=0x04, DupStderr=0x08, FDin=0x10, FDout=0x20 };
 
187
   int setCommunication( int c );
 
188
   int communication() const;
 
189
   void setFDin( int fd );
 
190
   void setFDout( int fd );
 
191
   int getFDin();
 
192
   int getFDout();
 
193
 
 
194
   // start the execution
 
195
   virtual bool start( QStringList *env=0 );
 
196
   virtual bool launch( const QString& buf, QStringList *env=0  );
 
197
   virtual bool launch( const QByteArray& buf, QStringList *env=0  );
 
198
 
 
199
   // inquire the status
 
200
   bool isRunning() const;
 
201
   bool normalExit() const;
 
202
   int exitStatus() const;
 
203
 
 
204
   // reading
 
205
   virtual QByteArray readFDout();
 
206
   virtual QByteArray readStdout();
 
207
   virtual QByteArray readStderr();
 
208
 
 
209
   bool canReadLineFDout() const;
 
210
   bool canReadLineStdout() const;
 
211
   bool canReadLineStderr() const;
 
212
 
 
213
   virtual QString readLineFDout();
 
214
   virtual QString readLineStdout();
 
215
   virtual QString readLineStderr();
 
216
  
 
217
   // get platform dependent process information
 
218
#if defined(Q_OS_WIN32)
 
219
   typedef void* PID;
 
220
#else
 
221
   typedef Q_LONG PID;
 
222
#endif
 
223
   PID processIdentifier();
 
224
 
 
225
   void flushFDin();
 
226
   void flushStdin();
 
227
 
 
228
signals:
 
229
   void readyReadFDout();
 
230
   void readyReadStdout();
 
231
   void readyReadStderr();
 
232
   void processExited();
 
233
   void wroteToFDin();
 
234
   void wroteToStdin();
 
235
   void launchFinished();
 
236
 
 
237
public slots:
 
238
   // end the execution
 
239
   void stop( int msec_kill_timeout=2000 );
 
240
   void tryTerminate() const;
 
241
   void kill() const;
 
242
 
 
243
   // input
 
244
   virtual void writeToFDin( const QByteArray& buf );
 
245
   virtual void writeToFDin( const QString& buf );
 
246
   virtual void closeFDin();
 
247
   virtual void writeToStdin( const QByteArray& buf );
 
248
   virtual void writeToStdin( const QString& buf );
 
249
   virtual void closeStdin();
 
250
 
 
251
protected: // ### or private?
 
252
   void connectNotify( const char * signal );
 
253
   void disconnectNotify( const char * signal );
 
254
 
 
255
private:
 
256
   void reprioritiseComms();
 
257
 
 
258
   void setIoRedirection( bool value );
 
259
   void setNotifyOnExit( bool value );
 
260
   void setWroteFDinConnected( bool value );
 
261
   void setWroteStdinConnected( bool value );
 
262
 
 
263
   void init();
 
264
   void reset();
 
265
#if defined(Q_OS_WIN32)
 
266
   uint readStddev( HANDLE dev, char *buf, uint bytes );
 
267
#endif
 
268
   VKMembuf* membufFDout();
 
269
   VKMembuf* membufStdout();
 
270
   VKMembuf* membufStderr();
 
271
 
 
272
private slots:
 
273
   void socketRead( int fd );
 
274
   void socketWrite( int fd );
 
275
   void timeout();
 
276
   void closeStdinLaunch();
 
277
 
 
278
private:
 
279
   VKProcessPrivate *d;
 
280
#ifndef QT_NO_DIR
 
281
   QDir workingDir;
 
282
#endif
 
283
   QStringList _arguments;
 
284
 
 
285
   int  exitStat;              // exit status
 
286
   bool exitNormal;            // normal exit?
 
287
   bool ioRedirection;         // automatically set be (dis)connectNotify
 
288
   bool notifyOnExit;          // automatically set be (dis)connectNotify
 
289
   bool wroteToFDinConnected;  // automatically set be (dis)connectNotify
 
290
   bool wroteToStdinConnected; // automatically set be (dis)connectNotify
 
291
 
 
292
   bool readFDoutCalled;
 
293
   bool readStdoutCalled;
 
294
   bool readStderrCalled;
 
295
   int comms;
 
296
   int filedesc_in, filedesc_out;
 
297
 
 
298
   friend class VKProcessPrivate;
 
299
#if defined(Q_OS_UNIX)
 
300
   friend class VKProcessManager;
 
301
   friend class VKProc;
 
302
#endif
 
303
 
 
304
#if defined(Q_DISABLE_COPY) // Disabled copy constructor and operator=
 
305
   VKProcess( const VKProcess & );
 
306
   VKProcess &operator=( const VKProcess & );
 
307
#endif
 
308
 
 
309
   /* Keep track of FDout/in disabling stdout/err/in */
 
310
   bool disabledStdin;
 
311
   bool disabledStdout;
 
312
   bool disabledStderr;
 
313
};
 
314
 
 
315
 
 
316
#endif // VK_PROCESS_H