summaryrefslogtreecommitdiff
authorzecke <zecke>2005-03-17 23:59:00 (UTC)
committer zecke <zecke>2005-03-17 23:59:00 (UTC)
commitc3ba7d98dc7d13132a75a14fce2cdaac6631dd26 (patch) (unidiff)
tree5732025b302537adf518bd3d5f8b36a8e18f84cc
parentc87b38dc7b0acc53f5c92ac5e53f40cfff15d956 (diff)
downloadopie-c3ba7d98dc7d13132a75a14fce2cdaac6631dd26.zip
opie-c3ba7d98dc7d13132a75a14fce2cdaac6631dd26.tar.gz
opie-c3ba7d98dc7d13132a75a14fce2cdaac6631dd26.tar.bz2
Update the API Documentation for OProcess and OApplicationFactory
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiecore/oapplicationfactory.h2
-rw-r--r--libopie2/opiecore/oprocess.h4
2 files changed, 3 insertions, 3 deletions
diff --git a/libopie2/opiecore/oapplicationfactory.h b/libopie2/opiecore/oapplicationfactory.h
index cabaf79..8516565 100644
--- a/libopie2/opiecore/oapplicationfactory.h
+++ b/libopie2/opiecore/oapplicationfactory.h
@@ -1,335 +1,335 @@
1/* 1/*
2                 This file is part of the Opie Project 2                 This file is part of the Opie Project
3              Copyright (C) Holger Freyther <zecke@handhelds.org> 3              Copyright (C) Holger Freyther <zecke@handhelds.org>
4 =. 4 =.
5 .=l. 5 .=l.
6           .>+-= 6           .>+-=
7 _;:,     .>    :=|. This program is free software; you can 7 _;:,     .>    :=|. This program is free software; you can
8.> <`_,   >  .   <= redistribute it and/or modify it under 8.> <`_,   >  .   <= redistribute it and/or modify it under
9:`=1 )Y*s>-.--   : the terms of the GNU Library General Public 9:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
10.="- .-=="i,     .._ License as published by the Free Software 10.="- .-=="i,     .._ License as published by the Free Software
11 - .   .-<_>     .<> Foundation; either version 2 of the License, 11 - .   .-<_>     .<> Foundation; either version 2 of the License,
12     ._= =}       : or (at your option) any later version. 12     ._= =}       : or (at your option) any later version.
13    .%`+i>       _;_. 13    .%`+i>       _;_.
14    .i_,=:_.      -<s. This program is distributed in the hope that 14    .i_,=:_.      -<s. This program is distributed in the hope that
15     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY; 15     +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
16    : ..    .:,     . . . without even the implied warranty of 16    : ..    .:,     . . . without even the implied warranty of
17    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A 17    =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
18  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU 18  _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
19..}^=.=       =       ; Library General Public License for more 19..}^=.=       =       ; Library General Public License for more
20++=   -.     .`     .: details. 20++=   -.     .`     .: details.
21 :     =  ...= . :.=- 21 :     =  ...= . :.=-
22 -.   .:....=;==+<; You should have received a copy of the GNU 22 -.   .:....=;==+<; You should have received a copy of the GNU
23  -_. . .   )=.  = Library General Public License along with 23  -_. . .   )=.  = Library General Public License along with
24    --        :-=` this library; see the file COPYING.LIB. 24    --        :-=` this library; see the file COPYING.LIB.
25 If not, write to the Free Software Foundation, 25 If not, write to the Free Software Foundation,
26 Inc., 59 Temple Place - Suite 330, 26 Inc., 59 Temple Place - Suite 330,
27 Boston, MA 02111-1307, USA. 27 Boston, MA 02111-1307, USA.
28*/ 28*/
29 29
30/* 30/*
31 This work is derived from: 31 This work is derived from:
32 ---- 32 ----
33 The Loki Library 33 The Loki Library
34 Copyright (c) 2001 by Andrei Alexandrescu 34 Copyright (c) 2001 by Andrei Alexandrescu
35 This code accompanies the book: 35 This code accompanies the book:
36 Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 36 Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
37 Patterns Applied". Copyright (c) 2001. Addison-Wesley. 37 Patterns Applied". Copyright (c) 2001. Addison-Wesley.
38 Permission to use, copy, modify, distribute and sell this software for any 38 Permission to use, copy, modify, distribute and sell this software for any
39 purpose is hereby granted without fee, provided that the above copyright 39 purpose is hereby granted without fee, provided that the above copyright
40 notice appear in all copies and that both that copyright notice and this 40 notice appear in all copies and that both that copyright notice and this
41 permission notice appear in supporting documentation. 41 permission notice appear in supporting documentation.
42 The author or Addison-Welsey Longman make no representations about the 42 The author or Addison-Welsey Longman make no representations about the
43 suitability of this software for any purpose. It is provided "as is" 43 suitability of this software for any purpose. It is provided "as is"
44 without express or implied warranty. 44 without express or implied warranty.
45 ---- 45 ----
46 46
47 And KGenericFactor et all from Simon Hausmann <tronical@kde.org> 47 And KGenericFactor et all from Simon Hausmann <tronical@kde.org>
48 48
49*/ 49*/
50 50
51#include <qstring.h> 51#include <qstring.h>
52#include <qmetaobject.h> 52#include <qmetaobject.h>
53 53
54#include <qtopia/qcom.h> 54#include <qtopia/qcom.h>
55#include <qtopia/applicationinterface.h> 55#include <qtopia/applicationinterface.h>
56 56
57namespace Opie { 57namespace Opie {
58namespace Core { 58namespace Core {
59 struct NullType; 59 struct NullType;
60 60
61 template <class T, class U> 61 template <class T, class U>
62 struct Typelist 62 struct Typelist
63 { 63 {
64 typedef T Head; 64 typedef T Head;
65 typedef U Tail; 65 typedef U Tail;
66 }; 66 };
67 template< 67 template<
68 typename T1 = NullType, typename T2 = NullType, typename T3 = NullType, 68 typename T1 = NullType, typename T2 = NullType, typename T3 = NullType,
69 typename T4 = NullType, typename T5 = NullType, typename T6 = NullType, 69 typename T4 = NullType, typename T5 = NullType, typename T6 = NullType,
70 typename T7 = NullType, typename T8 = NullType, typename T9 = NullType, 70 typename T7 = NullType, typename T8 = NullType, typename T9 = NullType,
71 typename T10 = NullType, typename T11 = NullType, typename T12 = NullType, 71 typename T10 = NullType, typename T11 = NullType, typename T12 = NullType,
72 typename T13 = NullType, typename T14 = NullType, typename T15 = NullType, 72 typename T13 = NullType, typename T14 = NullType, typename T15 = NullType,
73 typename T16 = NullType, typename T17 = NullType, typename T18 = NullType 73 typename T16 = NullType, typename T17 = NullType, typename T18 = NullType
74 > 74 >
75 struct MakeTypelist{ 75 struct MakeTypelist{
76 private: 76 private:
77 typedef typename MakeTypelist 77 typedef typename MakeTypelist
78 < 78 <
79 T2 , T3 , T4 , 79 T2 , T3 , T4 ,
80 T5 , T6 , T7 , 80 T5 , T6 , T7 ,
81 T8 , T9 , T10, 81 T8 , T9 , T10,
82 T11, T12, T13, 82 T11, T12, T13,
83 T14, T15, T16, 83 T14, T15, T16,
84 T17, T18 84 T17, T18
85 > 85 >
86 ::Result TailResult; 86 ::Result TailResult;
87 87
88public: 88public:
89 typedef Typelist<T1, TailResult> Result; 89 typedef Typelist<T1, TailResult> Result;
90}; 90};
91 91
92template<> 92template<>
93struct MakeTypelist<> 93struct MakeTypelist<>
94{ 94{
95 typedef NullType Result; 95 typedef NullType Result;
96}; 96};
97 97
98 98
99/** 99/**
100 * To allow your application to be quick launched some one needs 100 * To allow your application to be quick launched some one needs
101 * to create the QWidget. 101 * to create the QWidget.
102 * This is this factory. Make surce your widget has static QString Widget::appName() 102 * This is this factory. Make surce your widget has static QString Widget::appName()
103 * as one of its functions. 103 * as one of its functions.
104 * 104 *
105 * This template takes one QWidget and initialized it in the form of 105 * This template takes one QWidget and initialized it in the form of
106 * MyWidget::MyWidget( QWidget* parent, const char* name, WFlags f ); 106 * MyWidget::MyWidget( QWidget* parent, const char* name, WFlags f );
107 * 107 *
108 * To use it on your app do that: 108 * To use it on your app do that:
109 * typedef OApplicationFactory<MyWidget> MyFactory; 109 * typedef OApplicationFactory<MyWidget> MyFactory;
110 * OPIE_EXPORT_APP( MyFactory ) 110 * OPIE_EXPORT_APP( MyFactory )
111 * 111 *
112 */ 112 */
113template <class Product> 113template <class Product>
114struct OApplicationFactory : public ApplicationInterface { 114struct OApplicationFactory : public ApplicationInterface {
115 QRESULT queryInterface( const QUuid &uuid, QUnknownInterface **iface ) { 115 QRESULT queryInterface( const QUuid &uuid, QUnknownInterface **iface ) {
116 *iface = 0; 116 *iface = 0;
117 if ( uuid == IID_QUnknown ) *iface = this; 117 if ( uuid == IID_QUnknown ) *iface = this;
118 else if ( uuid == IID_QtopiaApplication ) *iface = this; 118 else if ( uuid == IID_QtopiaApplication ) *iface = this;
119 else return QS_FALSE; 119 else return QS_FALSE;
120 (*iface)->addRef(); 120 (*iface)->addRef();
121 return QS_OK; 121 return QS_OK;
122 } 122 }
123 123
124 /* 124 /*
125 * 125 *
126 */ 126 */
127 virtual QWidget *createMainWindow( const QString& appName, QWidget* parent, 127 virtual QWidget *createMainWindow( const QString& appName, QWidget* parent,
128 const char* name, Qt::WFlags f ) { 128 const char* name, Qt::WFlags f ) {
129 if (appName == Product::appName() ) 129 if (appName == Product::appName() )
130 return new Product(parent, name, f ); 130 return new Product(parent, name, f );
131 else 131 else
132 return 0l; 132 return 0l;
133 } 133 }
134 134
135 virtual QStringList applications()const { 135 virtual QStringList applications()const {
136 QStringList list; 136 QStringList list;
137 list << Product::appName() ; 137 list << Product::appName() ;
138 138
139 return list; 139 return list;
140 } 140 }
141 Q_REFCOUNT 141 Q_REFCOUNT
142 142
143}; 143};
144 144
145 145
146/* Internal */ 146/* Internal */
147 147
148template< class Product > 148template< class Product >
149struct OPrivate { 149struct OPrivate {
150 inline static QWidget *multiFactory( const QString& appName, QWidget* parent, 150 inline static QWidget *multiFactory( const QString& appName, QWidget* parent,
151 const char* name, Qt::WFlags fl ) { 151 const char* name, Qt::WFlags fl ) {
152 if ( appName == Product::appName() ) 152 if ( appName == Product::appName() )
153 return new Product( parent, name, fl ); 153 return new Product( parent, name, fl );
154 else 154 else
155 return 0; 155 return 0;
156 } 156 }
157 157
158 inline static QStringList multiString( const QStringList& _list ) { 158 inline static QStringList multiString( const QStringList& _list ) {
159 QStringList list = _list; 159 QStringList list = _list;
160 list << Product::appName(); 160 list << Product::appName();
161 return list; 161 return list;
162 } 162 }
163}; 163};
164 164
165template <> 165template <>
166struct OPrivate<Opie::Core::NullType > { 166struct OPrivate<Opie::Core::NullType > {
167 inline static QWidget* multiFactory ( const QString& , QWidget* , 167 inline static QWidget* multiFactory ( const QString& , QWidget* ,
168 const char* , Qt::WFlags ) { 168 const char* , Qt::WFlags ) {
169 return 0l; 169 return 0l;
170 } 170 }
171 inline static QStringList multiString( const QStringList& _list ) { 171 inline static QStringList multiString( const QStringList& _list ) {
172 return _list; 172 return _list;
173 } 173 }
174}; 174};
175 175
176/* 176/*
177template <> 177template <>
178struct OPrivate <Opie::NullType, Opie::NullType > { 178struct OPrivate <Opie::NullType, Opie::NullType > {
179 inline static QWidget* multiFactory( const QString& , QWidget* , 179 inline static QWidget* multiFactory( const QString& , QWidget* ,
180 const char* , Qt::WFlags ) { 180 const char* , Qt::WFlags ) {
181 return 0l; 181 return 0l;
182 } 182 }
183 183
184 inline static QStringList multiString( const QStringList& _list ) { 184 inline static QStringList multiString( const QStringList& _list ) {
185 return _list; 185 return _list;
186 } 186 }
187}; 187};
188*/ 188*/
189 189
190template <class Product, class ProductListTail> 190template <class Product, class ProductListTail>
191struct OPrivate< Opie::Core::Typelist<Product, ProductListTail> > { 191struct OPrivate< Opie::Core::Typelist<Product, ProductListTail> > {
192 inline static QWidget* multiFactory( const QString& appName, QWidget* parent, 192 inline static QWidget* multiFactory( const QString& appName, QWidget* parent,
193 const char* name, Qt::WFlags fl) { 193 const char* name, Qt::WFlags fl) {
194 QWidget* wid = OPrivate<Product>::multiFactory( appName, parent, name, fl ); 194 QWidget* wid = OPrivate<Product>::multiFactory( appName, parent, name, fl );
195 195
196 if (!wid ) 196 if (!wid )
197 wid = OPrivate<ProductListTail>::multiFactory( appName, parent, name, fl ); 197 wid = OPrivate<ProductListTail>::multiFactory( appName, parent, name, fl );
198 198
199 return wid; 199 return wid;
200 } 200 }
201 201
202 inline static QStringList multiString( const QStringList& _list ) { 202 inline static QStringList multiString( const QStringList& _list ) {
203 QStringList list = _list; 203 QStringList list = _list;
204 204
205 list = OPrivate<Product>::multiString( list ); 205 list = OPrivate<Product>::multiString( list );
206 list = OPrivate<ProductListTail>::multiString( list ); 206 list = OPrivate<ProductListTail>::multiString( list );
207 207
208 return list; 208 return list;
209 } 209 }
210}; 210};
211 211
212 212
213 213
214 214
215 215
216 216
217 217
218 218
219/* Internal END */ 219/* Internal END */
220 220
221/* 221/*
222 * If you want to export more than one Widget use that function 222 * If you want to export more than one Widget use that function
223 * Make sure all your Widgets provide the appName() static method 223 * Make sure all your Widgets provide the appName() static method
224 * otherwise you'll get a compiler error 224 * otherwise you'll get a compiler error
225 * 225 *
226 * typedef Opie::MakeTypeList<MyWidget, MyDialog, MyMediaPlayer >::Result MyTypes; 226 * typedef Opie::Core::MakeTypelist<MyWidget, MyDialog, MyMediaPlayer >::Result MyTypes;
227 * OPIE_EXPORT_APP( OApplicationFactory<MyTypes> ) 227 * OPIE_EXPORT_APP( OApplicationFactory<MyTypes> )
228 */ 228 */
229 229
230template<class Product, class ProductListTail> 230template<class Product, class ProductListTail>
231struct OApplicationFactory< Opie::Core::Typelist<Product, ProductListTail > > 231struct OApplicationFactory< Opie::Core::Typelist<Product, ProductListTail > >
232 : ApplicationInterface { 232 : ApplicationInterface {
233 QRESULT queryInterface( const QUuid &uuid, QUnknownInterface **iface ) { 233 QRESULT queryInterface( const QUuid &uuid, QUnknownInterface **iface ) {
234 *iface = 0; 234 *iface = 0;
235 if ( uuid == IID_QUnknown ) *iface = this; 235 if ( uuid == IID_QUnknown ) *iface = this;
236 else if ( uuid ==IID_QtopiaApplication ) *iface = this; 236 else if ( uuid ==IID_QtopiaApplication ) *iface = this;
237 else return QS_FALSE; 237 else return QS_FALSE;
238 (*iface)->addRef(); 238 (*iface)->addRef();
239 return QS_OK; 239 return QS_OK;
240 } 240 }
241 241
242 QWidget* createMainWindow ( const QString& appName, QWidget* parent, 242 QWidget* createMainWindow ( const QString& appName, QWidget* parent,
243 const char* name, Qt::WFlags fl ) { 243 const char* name, Qt::WFlags fl ) {
244 qWarning("StringList is %s", applications().join(":").latin1() ); 244 qWarning("StringList is %s", applications().join(":").latin1() );
245 return OPrivate< Opie::Core::Typelist<Product, ProductListTail > >::multiFactory( appName, parent, name, fl ); 245 return OPrivate< Opie::Core::Typelist<Product, ProductListTail > >::multiFactory( appName, parent, name, fl );
246 } 246 }
247 247
248 QStringList applications()const { 248 QStringList applications()const {
249 QStringList _list; 249 QStringList _list;
250 return OPrivate< Opie::Core::Typelist<Product, ProductListTail> >::multiString( _list ); 250 return OPrivate< Opie::Core::Typelist<Product, ProductListTail> >::multiString( _list );
251 } 251 }
252 252
253 Q_REFCOUNT 253 Q_REFCOUNT
254}; 254};
255 255
256} 256}
257} 257}
258 258
259/* If the library version should be build */ 259/* If the library version should be build */
260#ifdef OPIE_APP_INTERFACE 260#ifdef OPIE_APP_INTERFACE
261#define OPIE_EXPORT_APP( factory ) Q_EXPORT_INTERFACE() { Q_CREATE_INSTANCE( factory ) } 261#define OPIE_EXPORT_APP( factory ) Q_EXPORT_INTERFACE() { Q_CREATE_INSTANCE( factory ) }
262#else 262#else
263 263
264#include <qpe/qpeapplication.h> 264#include <qpe/qpeapplication.h>
265 265
266#define OPIE_EXPORT_APP( Factory ) \ 266#define OPIE_EXPORT_APP( Factory ) \
267int main( int argc, char **argv ) { \ 267int main( int argc, char **argv ) { \
268 QPEApplication a(argc, argv ); \ 268 QPEApplication a(argc, argv ); \
269 QWidget *mw = 0;\ 269 QWidget *mw = 0;\
270\ 270\
271 /* method from TT */ \ 271 /* method from TT */ \
272 QString executableName = QString::fromLatin1( argv[0] ); \ 272 QString executableName = QString::fromLatin1( argv[0] ); \
273 executableName = executableName.right(executableName.length() \ 273 executableName = executableName.right(executableName.length() \
274 - executableName.findRev('/') - 1); \ 274 - executableName.findRev('/') - 1); \
275 \ 275 \
276 Factory f; \ 276 Factory f; \
277 QStringList list = f.applications(); \ 277 QStringList list = f.applications(); \
278 if (list.contains(executableName) ) \ 278 if (list.contains(executableName) ) \
279 mw = f.createMainWindow(executableName, 0, 0, 0 ); \ 279 mw = f.createMainWindow(executableName, 0, 0, 0 ); \
280 else \ 280 else \
281 mw = f.createMainWindow( list[0], 0, 0, 0 ); \ 281 mw = f.createMainWindow( list[0], 0, 0, 0 ); \
282\ 282\
283 if( mw ) { \ 283 if( mw ) { \
284 if ( mw->metaObject()->slotNames().contains("setDocument(const QString&)" ) ) \ 284 if ( mw->metaObject()->slotNames().contains("setDocument(const QString&)" ) ) \
285 a.showMainDocumentWidget( mw ); \ 285 a.showMainDocumentWidget( mw ); \
286 else \ 286 else \
287 a.showMainWidget( mw ); \ 287 a.showMainWidget( mw ); \
288\ 288\
289 int rv = a.exec(); \ 289 int rv = a.exec(); \
290 delete mw; \ 290 delete mw; \
291 return rv; \ 291 return rv; \
292 }else \ 292 }else \
293 return -1; \ 293 return -1; \
294} 294}
295#endif 295#endif
296 296
297#ifdef OPIE_APP_INTERFACE 297#ifdef OPIE_APP_INTERFACE
298#define OPIE_EXPORT_APP_V2( factory,name ) Q_EXPORT_INTERFACE() { Q_CREATE_INSTANCE( factory ) } 298#define OPIE_EXPORT_APP_V2( factory,name ) Q_EXPORT_INTERFACE() { Q_CREATE_INSTANCE( factory ) }
299#else 299#else
300 300
301#include <opie2/oapplication.h> 301#include <opie2/oapplication.h>
302 302
303#define OPIE_EXPORT_APP_V2( Factory,name ) \ 303#define OPIE_EXPORT_APP_V2( Factory,name ) \
304int main( int argc, char **argv ) { \ 304int main( int argc, char **argv ) { \
305 Opie::Core::OApplication a(argc, argv, name ); \ 305 Opie::Core::OApplication a(argc, argv, name ); \
306 QWidget *mw = 0;\ 306 QWidget *mw = 0;\
307\ 307\
308 /* method from TT */ \ 308 /* method from TT */ \
309 QString executableName = QString::fromLatin1( argv[0] ); \ 309 QString executableName = QString::fromLatin1( argv[0] ); \
310 executableName = executableName.right(executableName.length() \ 310 executableName = executableName.right(executableName.length() \
311 - executableName.findRev('/') - 1); \ 311 - executableName.findRev('/') - 1); \
312 \ 312 \
313 Factory f; \ 313 Factory f; \
314 QStringList list = f.applications(); \ 314 QStringList list = f.applications(); \
315 if (list.contains(executableName) ) \ 315 if (list.contains(executableName) ) \
316 mw = f.createMainWindow(executableName, 0, 0, 0 ); \ 316 mw = f.createMainWindow(executableName, 0, 0, 0 ); \
317 else \ 317 else \
318 mw = f.createMainWindow( list[0], 0, 0, 0 ); \ 318 mw = f.createMainWindow( list[0], 0, 0, 0 ); \
319\ 319\
320 if( mw ) { \ 320 if( mw ) { \
321 if ( mw->metaObject()->slotNames().contains("setDocument(const QString&)" ) ) \ 321 if ( mw->metaObject()->slotNames().contains("setDocument(const QString&)" ) ) \
322 a.showMainDocumentWidget( mw ); \ 322 a.showMainDocumentWidget( mw ); \
323 else \ 323 else \
324 a.showMainWidget( mw ); \ 324 a.showMainWidget( mw ); \
325\ 325\
326 int rv = a.exec(); \ 326 int rv = a.exec(); \
327 delete mw; \ 327 delete mw; \
328 return rv; \ 328 return rv; \
329 }else \ 329 }else \
330 return -1; \ 330 return -1; \
331} 331}
332#endif 332#endif
333 333
334 334
335#define OPIE_EXPORT_APPNAME static QString appName() { return QString::fromLatin1( QUICKAPP_NAME ); } 335#define OPIE_EXPORT_APPNAME static QString appName() { return QString::fromLatin1( QUICKAPP_NAME ); }
diff --git a/libopie2/opiecore/oprocess.h b/libopie2/opiecore/oprocess.h
index ac6be98..23e9b10 100644
--- a/libopie2/opiecore/oprocess.h
+++ b/libopie2/opiecore/oprocess.h
@@ -1,763 +1,763 @@
1/* 1/*
2                This file is part of the Opie Project 2                This file is part of the Opie Project
3             Copyright (C) 2003-2004 Holger Freyther <zecke@handhelds.org> 3             Copyright (C) 2003-2004 Holger Freyther <zecke@handhelds.org>
4 Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 =. Based on KProcess (C) 1997 Christian Czezatke (e9025461@student.tuwien.ac.at) 5 =. Based on KProcess (C) 1997 Christian Czezatke (e9025461@student.tuwien.ac.at)
6 .=l. 6 .=l.
7          .>+-= 7          .>+-=
8_;:,     .>    :=|. This program is free software; you can 8_;:,     .>    :=|. This program is free software; you can
9.> <`_,   >  .   <= redistribute it and/or modify it under 9.> <`_,   >  .   <= redistribute it and/or modify it under
10:`=1 )Y*s>-.--   : the terms of the GNU Library General Public 10:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
11.="- .-=="i,     .._ License as published by the Free Software 11.="- .-=="i,     .._ License as published by the Free Software
12- .   .-<_>     .<> Foundation; either version 2 of the License, 12- .   .-<_>     .<> Foundation; either version 2 of the License,
13    ._= =}       : or (at your option) any later version. 13    ._= =}       : or (at your option) any later version.
14   .%`+i>       _;_. 14   .%`+i>       _;_.
15   .i_,=:_.      -<s. This program is distributed in the hope that 15   .i_,=:_.      -<s. This program is distributed in the hope that
16    +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY; 16    +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
17   : ..    .:,     . . . without even the implied warranty of 17   : ..    .:,     . . . without even the implied warranty of
18   =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A 18   =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
19 _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU 19 _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
20..}^=.=       =       ; Library General Public License for more 20..}^=.=       =       ; Library General Public License for more
21++=   -.     .`     .: details. 21++=   -.     .`     .: details.
22:     =  ...= . :.=- 22:     =  ...= . :.=-
23-.   .:....=;==+<; You should have received a copy of the GNU 23-.   .:....=;==+<; You should have received a copy of the GNU
24 -_. . .   )=.  = Library General Public License along with 24 -_. . .   )=.  = Library General Public License along with
25   --        :-=` this library; see the file COPYING.LIB. 25   --        :-=` this library; see the file COPYING.LIB.
26 If not, write to the Free Software Foundation, 26 If not, write to the Free Software Foundation,
27 Inc., 59 Temple Place - Suite 330, 27 Inc., 59 Temple Place - Suite 330,
28 Boston, MA 02111-1307, USA. 28 Boston, MA 02111-1307, USA.
29*/ 29*/
30 30
31#ifndef OPROCESS_H 31#ifndef OPROCESS_H
32#define OPROCESS_H 32#define OPROCESS_H
33 33
34/* QT */ 34/* QT */
35#include <qcstring.h> 35#include <qcstring.h>
36#include <qobject.h> 36#include <qobject.h>
37#include <qvaluelist.h> 37#include <qvaluelist.h>
38 38
39/* STD */ 39/* STD */
40#include <sys/types.h> // for pid_t 40#include <sys/types.h> // for pid_t
41#include <sys/wait.h> 41#include <sys/wait.h>
42#include <signal.h> 42#include <signal.h>
43#include <unistd.h> 43#include <unistd.h>
44 44
45class QSocketNotifier; 45class QSocketNotifier;
46 46
47namespace Opie { 47namespace Opie {
48namespace Core { 48namespace Core {
49namespace Internal { 49namespace Internal {
50class OProcessController; 50class OProcessController;
51class OProcessPrivate; 51class OProcessPrivate;
52} 52}
53 53
54/** 54/**
55 * Child process invocation, monitoring and control. 55 * Child process invocation, monitoring and control.
56 * 56 *
57 * @par General usage and features 57 * @par General usage and features
58 * 58 *
59 *This class allows a KDE and OPIE application to start child processes without having 59 *This class allows a KDE and OPIE application to start child processes without having
60 *to worry about UN*X signal handling issues and zombie process reaping. 60 *to worry about UN*X signal handling issues and zombie process reaping.
61 * 61 *
62 *@see KProcIO 62 *@see KProcIO
63 * 63 *
64 *Basically, this class distinguishes three different ways of running 64 *Basically, this class distinguishes three different ways of running
65 *child processes: 65 *child processes:
66 * 66 *
67 *@li OProcess::DontCare -- The child process is invoked and both the child 67 *@li OProcess::DontCare -- The child process is invoked and both the child
68 *process and the parent process continue concurrently. 68 *process and the parent process continue concurrently.
69 * 69 *
70 *Starting a DontCare child process means that the application is 70 *Starting a DontCare child process means that the application is
71 *not interested in any notification to determine whether the 71 *not interested in any notification to determine whether the
72 *child process has already exited or not. 72 *child process has already exited or not.
73 * 73 *
74 *@li OProcess::NotifyOnExit -- The child process is invoked and both the 74 *@li OProcess::NotifyOnExit -- The child process is invoked and both the
75 *child and the parent process run concurrently. 75 *child and the parent process run concurrently.
76 * 76 *
77 *When the child process exits, the OProcess instance 77 *When the child process exits, the OProcess instance
78 *corresponding to it emits the Qt signal @ref processExited(). 78 *corresponding to it emits the Qt signal @ref processExited().
79 * 79 *
80 *Since this signal is @em not emitted from within a UN*X 80 *Since this signal is @em not emitted from within a UN*X
81 *signal handler, arbitrary function calls can be made. 81 *signal handler, arbitrary function calls can be made.
82 * 82 *
83 *Be aware: When the OProcess objects gets destructed, the child 83 *Be aware: When the OProcess objects gets destructed, the child
84 *process will be killed if it is still running! 84 *process will be killed if it is still running!
85 *This means in particular, that you cannot use a OProcess on the stack 85 *This means in particular, that you cannot use a OProcess on the stack
86 *with OProcess::NotifyOnExit. 86 *with OProcess::NotifyOnExit.
87 * 87 *
88 *@li OProcess::Block -- The child process starts and the parent process 88 *@li OProcess::Block -- The child process starts and the parent process
89 *is suspended until the child process exits. (@em Really not recommended 89 *is suspended until the child process exits. (@em Really not recommended
90 *for programs with a GUI.) 90 *for programs with a GUI.)
91 * 91 *
92 *OProcess also provides several functions for determining the exit status 92 *OProcess also provides several functions for determining the exit status
93 *and the pid of the child process it represents. 93 *and the pid of the child process it represents.
94 * 94 *
95 *Furthermore it is possible to supply command-line arguments to the process 95 *Furthermore it is possible to supply command-line arguments to the process
96 *in a clean fashion (no null -- terminated stringlists and such...) 96 *in a clean fashion (no null -- terminated stringlists and such...)
97 * 97 *
98 *A small usage example: 98 *A small usage example:
99 *<pre> 99 *<pre>
100 *OProcess *proc = new OProcess; 100 *OProcess *proc = new OProcess;
101 * 101 *
102 **proc << "my_executable"; 102 **proc << "my_executable";
103 **proc << "These" << "are" << "the" << "command" << "line" << "args"; 103 **proc << "These" << "are" << "the" << "command" << "line" << "args";
104 *QApplication::connect(proc, SIGNAL(processExited(Opie::Core::OProcess *)), 104 *QObject::connect(proc, SIGNAL(processExited(Opie::Core::OProcess *)),
105 * pointer_to_my_object, SLOT(my_objects_slot(Opie::Core::OProcess *))); 105 * pointer_to_my_object, SLOT(my_objects_slot(Opie::Core::OProcess *)));
106 *proc->start(); 106 *proc->start();
107 *</pre> 107 *</pre>
108 * 108 *
109 *This will start "my_executable" with the commandline arguments "These"... 109 *This will start "my_executable" with the commandline arguments "These"...
110 * 110 *
111 *When the child process exits, the respective Qt signal will be emitted. 111 *When the child process exits, the respective Qt signal will be emitted.
112 * 112 *
113 *@par Communication with the child process 113 *@par Communication with the child process
114 * 114 *
115 *OProcess supports communication with the child process through 115 *OProcess supports communication with the child process through
116 *stdin/stdout/stderr. 116 *stdin/stdout/stderr.
117 * 117 *
118 *The following functions are provided for getting data from the child 118 *The following functions are provided for getting data from the child
119 *process or sending data to the child's stdin (For more information, 119 *process or sending data to the child's stdin (For more information,
120 *have a look at the documentation of each function): 120 *have a look at the documentation of each function):
121 * 121 *
122 *@li bool @ref writeStdin(char *buffer, int buflen); 122 *@li bool @ref writeStdin(char *buffer, int buflen);
123 *@li -- Transmit data to the child process's stdin. 123 *@li -- Transmit data to the child process's stdin.
124 * 124 *
125 *@li bool @ref closeStdin(); 125 *@li bool @ref closeStdin();
126 *@li -- Closes the child process's stdin (which causes it to see an feof(stdin)). 126 *@li -- Closes the child process's stdin (which causes it to see an feof(stdin)).
127 *Returns false if you try to close stdin for a process that has been started 127 *Returns false if you try to close stdin for a process that has been started
128 *without a communication channel to stdin. 128 *without a communication channel to stdin.
129 * 129 *
130 *@li bool @ref closeStdout(); 130 *@li bool @ref closeStdout();
131 *@li -- Closes the child process's stdout. 131 *@li -- Closes the child process's stdout.
132 *Returns false if you try to close stdout for a process that has been started 132 *Returns false if you try to close stdout for a process that has been started
133 *without a communication channel to stdout. 133 *without a communication channel to stdout.
134 * 134 *
135 *@li bool @ref closeStderr(); 135 *@li bool @ref closeStderr();
136 *@li -- Closes the child process's stderr. 136 *@li -- Closes the child process's stderr.
137 *Returns false if you try to close stderr for a process that has been started 137 *Returns false if you try to close stderr for a process that has been started
138 *without a communication channel to stderr. 138 *without a communication channel to stderr.
139 * 139 *
140 * 140 *
141 *@par QT signals: 141 *@par QT signals:
142 * 142 *
143 *@li void @ref receivedStdout(OProcess *proc, char *buffer, int buflen); 143 *@li void @ref receivedStdout(OProcess *proc, char *buffer, int buflen);
144 *@li void @ref receivedStderr(OProcess *proc, char *buffer, int buflen); 144 *@li void @ref receivedStderr(OProcess *proc, char *buffer, int buflen);
145 *@li -- Indicates that new data has arrived from either the 145 *@li -- Indicates that new data has arrived from either the
146 *child process's stdout or stderr. 146 *child process's stdout or stderr.
147 * 147 *
148 *@li void @ref wroteStdin(OProcess *proc); 148 *@li void @ref wroteStdin(OProcess *proc);
149 *@li -- Indicates that all data that has been sent to the child process 149 *@li -- Indicates that all data that has been sent to the child process
150 *by a prior call to @ref writeStdin() has actually been transmitted to the 150 *by a prior call to @ref writeStdin() has actually been transmitted to the
151 *client . 151 *client .
152 * 152 *
153 *@author Christian Czezakte e9025461@student.tuwien.ac.at 153 *@author Christian Czezakte e9025461@student.tuwien.ac.at
154 *@author Holger Freyther (Opie Port) 154 *@author Holger Freyther (Opie Port)
155 * 155 *
156 **/ 156 **/
157class OProcess : public QObject 157class OProcess : public QObject
158{ 158{
159 Q_OBJECT 159 Q_OBJECT
160 160
161public: 161public:
162 162
163 /** 163 /**
164 * Modes in which the communication channel can be opened. 164 * Modes in which the communication channel can be opened.
165 * 165 *
166 * If communication for more than one channel is required, 166 * If communication for more than one channel is required,
167 * the values have to be or'ed together, for example to get 167 * the values have to be or'ed together, for example to get
168 * communication with stdout as well as with stdin, you would 168 * communication with stdout as well as with stdin, you would
169 * specify @p Stdin @p | @p Stdout 169 * specify @p Stdin @p | @p Stdout
170 * 170 *
171 * If @p NoRead is specified in conjunction with @p Stdout, 171 * If @p NoRead is specified in conjunction with @p Stdout,
172 * no data is actually read from @p Stdout but only 172 * no data is actually read from @p Stdout but only
173 * the signal @ref childOutput(int fd) is emitted. 173 * the signal @ref childOutput(int fd) is emitted.
174 */ 174 */
175 enum Communication { NoCommunication = 0, Stdin = 1, Stdout = 2, Stderr = 4, 175 enum Communication { NoCommunication = 0, Stdin = 1, Stdout = 2, Stderr = 4,
176 AllOutput = 6, All = 7, 176 AllOutput = 6, All = 7,
177 NoRead }; 177 NoRead };
178 178
179 /** 179 /**
180 * Run-modes for a child process. 180 * Run-modes for a child process.
181 */ 181 */
182 enum RunMode { 182 enum RunMode {
183 /** 183 /**
184 * The application does not receive notifications from the subprocess when 184 * The application does not receive notifications from the subprocess when
185 * it is finished or aborted. 185 * it is finished or aborted.
186 */ 186 */
187 DontCare, 187 DontCare,
188 /** 188 /**
189 * The application is notified when the subprocess dies. 189 * The application is notified when the subprocess dies.
190 */ 190 */
191 NotifyOnExit, 191 NotifyOnExit,
192 /** 192 /**
193 * The application is suspended until the started process is finished. 193 * The application is suspended until the started process is finished.
194 */ 194 */
195 Block }; 195 Block };
196 196
197 /** 197 /**
198 * Constructor 198 * Constructor
199 */ 199 */
200 OProcess( QObject *parent = 0, const char *name = 0 ); 200 OProcess( QObject *parent = 0, const char *name = 0 );
201 /** 201 /**
202 * Constructor 202 * Constructor
203 */ 203 */
204 OProcess( const QString &arg0, QObject *parent = 0, const char *name = 0 ); 204 OProcess( const QString &arg0, QObject *parent = 0, const char *name = 0 );
205 /** 205 /**
206 * Constructor 206 * Constructor
207 */ 207 */
208 OProcess( const QStringList &args, QObject *parent = 0, const char *name = 0 ); 208 OProcess( const QStringList &args, QObject *parent = 0, const char *name = 0 );
209 209
210 /** 210 /**
211 *Destructor: 211 *Destructor:
212 * 212 *
213 * If the process is running when the destructor for this class 213 * If the process is running when the destructor for this class
214 * is called, the child process is killed with a SIGKILL, but 214 * is called, the child process is killed with a SIGKILL, but
215 * only if the run mode is not of type @p DontCare. 215 * only if the run mode is not of type @p DontCare.
216 * Processes started as @p DontCare keep running anyway. 216 * Processes started as @p DontCare keep running anyway.
217 */ 217 */
218 virtual ~OProcess(); 218 virtual ~OProcess();
219 219
220 /** 220 /**
221 @deprecated 221 @deprecated
222 222
223 The use of this function is now deprecated. -- Please use the 223 The use of this function is now deprecated. -- Please use the
224 "operator<<" instead of "setExecutable". 224 "operator<<" instead of "setExecutable".
225 225
226 Sets the executable to be started with this OProcess object. 226 Sets the executable to be started with this OProcess object.
227 Returns false if the process is currently running (in that 227 Returns false if the process is currently running (in that
228 case the executable remains unchanged.) 228 case the executable remains unchanged.)
229 229
230 @see operator<< 230 @see operator<<
231 231
232 */ 232 */
233 bool setExecutable( const QString& proc ); 233 bool setExecutable( const QString& proc );
234 234
235 235
236 /** 236 /**
237 * Sets the executable and the command line argument list for this process. 237 * Sets the executable and the command line argument list for this process.
238 * 238 *
239 * For example, doing an "ls -l /usr/local/bin" can be achieved by: 239 * For example, doing an "ls -l /usr/local/bin" can be achieved by:
240 * <pre> 240 * <pre>
241 * OProcess p; 241 * OProcess p;
242 * ... 242 * ...
243 * p << "ls" << "-l" << "/usr/local/bin" 243 * p << "ls" << "-l" << "/usr/local/bin"
244 * </pre> 244 * </pre>
245 * 245 *
246 **/ 246 **/
247 OProcess &operator<<( const QString& arg ); 247 OProcess &operator<<( const QString& arg );
248 /** 248 /**
249 * Similar to previous method, takes a char *, supposed to be in locale 8 bit already. 249 * Similar to previous method, takes a char *, supposed to be in locale 8 bit already.
250 */ 250 */
251 OProcess &operator<<( const char * arg ); 251 OProcess &operator<<( const char * arg );
252 /** 252 /**
253 * Similar to previous method, takes a QCString, supposed to be in locale 8 bit already. 253 * Similar to previous method, takes a QCString, supposed to be in locale 8 bit already.
254 */ 254 */
255 OProcess &operator<<( const QCString & arg ); 255 OProcess &operator<<( const QCString & arg );
256 256
257 /** 257 /**
258 * Sets the executable and the command line argument list for this process, 258 * Sets the executable and the command line argument list for this process,
259 * in a single method call, or add a list of arguments. 259 * in a single method call, or add a list of arguments.
260 **/ 260 **/
261 OProcess &operator<<( const QStringList& args ); 261 OProcess &operator<<( const QStringList& args );
262 262
263 /** 263 /**
264 * Clear a command line argument list that has been set by using 264 * Clear a command line argument list that has been set by using
265 * the "operator<<". 265 * the "operator<<".
266 */ 266 */
267 void clearArguments(); 267 void clearArguments();
268 268
269 /** 269 /**
270 * Starts the process. 270 * Starts the process.
271 * For a detailed description of the 271 * For a detailed description of the
272 * various run modes and communication semantics, have a look at the 272 * various run modes and communication semantics, have a look at the
273 * general description of the OProcess class. 273 * general description of the OProcess class.
274 * 274 *
275 * The following problems could cause this function to 275 * The following problems could cause this function to
276 * return false: 276 * return false:
277 * 277 *
278 * @li The process is already running. 278 * @li The process is already running.
279 * @li The command line argument list is empty. 279 * @li The command line argument list is empty.
280 * @li The starting of the process failed (could not fork). 280 * @li The starting of the process failed (could not fork).
281 * @li The executable was not found. 281 * @li The executable was not found.
282 * 282 *
283 * @param comm Specifies which communication links should be 283 * @param comm Specifies which communication links should be
284 * established to the child process (stdin/stdout/stderr). By default, 284 * established to the child process (stdin/stdout/stderr). By default,
285 * no communication takes place and the respective communication 285 * no communication takes place and the respective communication
286 * signals will never get emitted. 286 * signals will never get emitted.
287 * 287 *
288 * @return true on success, false on error 288 * @return true on success, false on error
289 * (see above for error conditions) 289 * (see above for error conditions)
290 **/ 290 **/
291 virtual bool start( RunMode runmode = NotifyOnExit, 291 virtual bool start( RunMode runmode = NotifyOnExit,
292 Communication comm = NoCommunication ); 292 Communication comm = NoCommunication );
293 293
294 /** 294 /**
295 * Stop the process (by sending it a signal). 295 * Stop the process (by sending it a signal).
296 * 296 *
297 * @param signoThe signal to send. The default is SIGTERM. 297 * @param signoThe signal to send. The default is SIGTERM.
298 * @return @p true if the signal was delivered successfully. 298 * @return @p true if the signal was delivered successfully.
299 */ 299 */
300 virtual bool kill( int signo = SIGTERM ); 300 virtual bool kill( int signo = SIGTERM );
301 301
302 /** 302 /**
303 @return @p true if the process is (still) considered to be running 303 @return @p true if the process is (still) considered to be running
304 */ 304 */
305 bool isRunning() const; 305 bool isRunning() const;
306 306
307 /** Returns the process id of the process. 307 /** Returns the process id of the process.
308 * 308 *
309 * If it is called after 309 * If it is called after
310 * the process has exited, it returns the process id of the last 310 * the process has exited, it returns the process id of the last
311 * child process that was created by this instance of OProcess. 311 * child process that was created by this instance of OProcess.
312 * 312 *
313 * Calling it before any child process has been started by this 313 * Calling it before any child process has been started by this
314 * OProcess instance causes pid() to return 0. 314 * OProcess instance causes pid() to return 0.
315 **/ 315 **/
316 pid_t pid() const; 316 pid_t pid() const;
317 317
318 /** 318 /**
319 * Suspend processing of data from stdout of the child process. 319 * Suspend processing of data from stdout of the child process.
320 */ 320 */
321 void suspend(); 321 void suspend();
322 322
323 /** 323 /**
324 * Resume processing of data from stdout of the child process. 324 * Resume processing of data from stdout of the child process.
325 */ 325 */
326 void resume(); 326 void resume();
327 327
328 /** 328 /**
329 * @return @p true if the process has already finished and has exited 329 * @return @p true if the process has already finished and has exited
330 * "voluntarily", ie: it has not been killed by a signal. 330 * "voluntarily", ie: it has not been killed by a signal.
331 * 331 *
332 * Note that you should check @ref OProcess::exitStatus() to determine 332 * Note that you should check @ref OProcess::exitStatus() to determine
333 * whether the process completed its task successful or not. 333 * whether the process completed its task successful or not.
334 */ 334 */
335 bool normalExit() const; 335 bool normalExit() const;
336 336
337 /** 337 /**
338 * Returns the exit status of the process. 338 * Returns the exit status of the process.
339 * 339 *
340 * Please use 340 * Please use
341 * @ref OProcess::normalExit() to check whether the process has exited 341 * @ref OProcess::normalExit() to check whether the process has exited
342 * cleanly (i.e., @ref OProcess::normalExit() returns @p true) before calling 342 * cleanly (i.e., @ref OProcess::normalExit() returns @p true) before calling
343 * this function because if the process did not exit normally, 343 * this function because if the process did not exit normally,
344 * it does not have a valid exit status. 344 * it does not have a valid exit status.
345 */ 345 */
346 int exitStatus() const; 346 int exitStatus() const;
347 347
348 348
349 /** 349 /**
350 * Transmit data to the child process's stdin. 350 * Transmit data to the child process's stdin.
351 * 351 *
352 * OProcess::writeStdin may return false in the following cases: 352 * OProcess::writeStdin may return false in the following cases:
353 * 353 *
354 * @li The process is not currently running. 354 * @li The process is not currently running.
355 * 355 *
356 * @li Communication to stdin has not been requested in the @ref start() call. 356 * @li Communication to stdin has not been requested in the @ref start() call.
357 * 357 *
358 * @li Transmission of data to the child process by a previous call to 358 * @li Transmission of data to the child process by a previous call to
359 * @ref writeStdin() is still in progress. 359 * @ref writeStdin() is still in progress.
360 * 360 *
361 * Please note that the data is sent to the client asynchronously, 361 * Please note that the data is sent to the client asynchronously,
362 * so when this function returns, the data might not have been 362 * so when this function returns, the data might not have been
363 * processed by the child process. 363 * processed by the child process.
364 * 364 *
365 * If all the data has been sent to the client, the signal 365 * If all the data has been sent to the client, the signal
366 * @ref wroteStdin() will be emitted. 366 * @ref wroteStdin() will be emitted.
367 * 367 *
368 * Please note that you must not free "buffer" or call @ref writeStdin() 368 * Please note that you must not free "buffer" or call @ref writeStdin()
369 * again until either a @ref wroteStdin() signal indicates that the 369 * again until either a @ref wroteStdin() signal indicates that the
370 * data has been sent or a @ref processHasExited() signal shows that 370 * data has been sent or a @ref processHasExited() signal shows that
371 * the child process is no longer alive... 371 * the child process is no longer alive...
372 **/ 372 **/
373 bool writeStdin( const char *buffer, int buflen ); 373 bool writeStdin( const char *buffer, int buflen );
374 374
375 void flushStdin(); 375 void flushStdin();
376 376
377 /** 377 /**
378 * This causes the stdin file descriptor of the child process to be 378 * This causes the stdin file descriptor of the child process to be
379 * closed indicating an "EOF" to the child. 379 * closed indicating an "EOF" to the child.
380 * 380 *
381 * @return @p false if no communication to the process's stdin 381 * @return @p false if no communication to the process's stdin
382 * had been specified in the call to @ref start(). 382 * had been specified in the call to @ref start().
383 */ 383 */
384 bool closeStdin(); 384 bool closeStdin();
385 385
386 /** 386 /**
387 * This causes the stdout file descriptor of the child process to be 387 * This causes the stdout file descriptor of the child process to be
388 * closed. 388 * closed.
389 * 389 *
390 * @return @p false if no communication to the process's stdout 390 * @return @p false if no communication to the process's stdout
391 * had been specified in the call to @ref start(). 391 * had been specified in the call to @ref start().
392 */ 392 */
393 bool closeStdout(); 393 bool closeStdout();
394 394
395 /** 395 /**
396 * This causes the stderr file descriptor of the child process to be 396 * This causes the stderr file descriptor of the child process to be
397 * closed. 397 * closed.
398 * 398 *
399 * @return @p false if no communication to the process's stderr 399 * @return @p false if no communication to the process's stderr
400 * had been specified in the call to @ref start(). 400 * had been specified in the call to @ref start().
401 */ 401 */
402 bool closeStderr(); 402 bool closeStderr();
403 403
404 /** 404 /**
405 * Lets you see what your arguments are for debugging. 405 * Lets you see what your arguments are for debugging.
406 * \todo make const 406 * \todo make const
407 */ 407 */
408 408
409 const QValueList<QCString> &args() 409 const QValueList<QCString> &args()
410 { 410 {
411 return arguments; 411 return arguments;
412 } 412 }
413 413
414 /** 414 /**
415 * Controls whether the started process should drop any 415 * Controls whether the started process should drop any
416 * setuid/segid privileges or whether it should keep them 416 * setuid/segid privileges or whether it should keep them
417 * 417 *
418 * The default is @p false : drop privileges 418 * The default is @p false : drop privileges
419 */ 419 */
420 void setRunPrivileged( bool keepPrivileges ); 420 void setRunPrivileged( bool keepPrivileges );
421 421
422 /** 422 /**
423 * Returns whether the started process will drop any 423 * Returns whether the started process will drop any
424 * setuid/segid privileges or whether it will keep them 424 * setuid/segid privileges or whether it will keep them
425 */ 425 */
426 bool runPrivileged() const; 426 bool runPrivileged() const;
427 427
428 /** 428 /**
429 * Modifies the environment of the process to be started. 429 * Modifies the environment of the process to be started.
430 * This function must be called before starting the process. 430 * This function must be called before starting the process.
431 */ 431 */
432 void setEnvironment( const QString &name, const QString &value ); 432 void setEnvironment( const QString &name, const QString &value );
433 433
434 /** 434 /**
435 * Changes the current working directory (CWD) of the process 435 * Changes the current working directory (CWD) of the process
436 * to be started. 436 * to be started.
437 * This function must be called before starting the process. 437 * This function must be called before starting the process.
438 */ 438 */
439 void setWorkingDirectory( const QString &dir ); 439 void setWorkingDirectory( const QString &dir );
440 440
441 /** 441 /**
442 * Specify whether to start the command via a shell or directly. 442 * Specify whether to start the command via a shell or directly.
443 * The default is to start the command directly. 443 * The default is to start the command directly.
444 * If @p useShell is true @p shell will be used as shell, or 444 * If @p useShell is true @p shell will be used as shell, or
445 * if shell is empty, the standard shell is used. 445 * if shell is empty, the standard shell is used.
446 * @p quote A flag indicating whether to quote the arguments. 446 * @p quote A flag indicating whether to quote the arguments.
447 * 447 *
448 * When using a shell, the caller should make sure that all filenames etc. 448 * When using a shell, the caller should make sure that all filenames etc.
449 * are properly quoted when passed as argument. 449 * are properly quoted when passed as argument.
450 * @see quote() 450 * @see quote()
451 */ 451 */
452 void setUseShell( bool useShell, const char *shell = 0 ); 452 void setUseShell( bool useShell, const char *shell = 0 );
453 453
454 /** 454 /**
455 * This function can be used to quote an argument string such that 455 * This function can be used to quote an argument string such that
456 * the shell processes it properly. This is e. g. necessary for 456 * the shell processes it properly. This is e. g. necessary for
457 * user-provided file names which may contain spaces or quotes. 457 * user-provided file names which may contain spaces or quotes.
458 * It also prevents expansion of wild cards and environment variables. 458 * It also prevents expansion of wild cards and environment variables.
459 */ 459 */
460 static QString quote( const QString &arg ); 460 static QString quote( const QString &arg );
461 461
462 /** 462 /**
463 * Detaches OProcess from child process. All communication is closed. 463 * Detaches OProcess from child process. All communication is closed.
464 * No exit notification is emitted any more for the child process. 464 * No exit notification is emitted any more for the child process.
465 * Deleting the OProcess will no longer kill the child process. 465 * Deleting the OProcess will no longer kill the child process.
466 * Note that the current process remains the parent process of the 466 * Note that the current process remains the parent process of the
467 * child process. 467 * child process.
468 */ 468 */
469 void detach(); 469 void detach();
470 470
471 /** 471 /**
472 * @return the PID of @a process, or -1 if the process is not running 472 * @return the PID of @a process, or -1 if the process is not running
473 */ 473 */
474 static int processPID( const QString& process ); 474 static int processPID( const QString& process );
475 475
476signals: 476signals:
477 477
478 /** 478 /**
479 * Emitted after the process has terminated when 479 * Emitted after the process has terminated when
480 * the process was run in the @p NotifyOnExit (==default option to 480 * the process was run in the @p NotifyOnExit (==default option to
481 * @ref start()) or the @ref Block mode. 481 * @ref start()) or the @ref Block mode.
482 **/ 482 **/
483 void processExited( Opie::Core::OProcess *proc ); 483 void processExited( Opie::Core::OProcess *proc );
484 484
485 485
486 /** 486 /**
487 * Emitted, when output from the child process has 487 * Emitted, when output from the child process has
488 * been received on stdout. 488 * been received on stdout.
489 * 489 *
490 * To actually get 490 * To actually get
491 * these signals, the respective communication link (stdout/stderr) 491 * these signals, the respective communication link (stdout/stderr)
492 * has to be turned on in @ref start(). 492 * has to be turned on in @ref start().
493 * 493 *
494 * @param proc The process 494 * @param proc The process
495 * @param buffer The data received. 495 * @param buffer The data received.
496 * @param buflen The number of bytes that are available. 496 * @param buflen The number of bytes that are available.
497 * 497 *
498 * You should copy the information contained in @p buffer to your private 498 * You should copy the information contained in @p buffer to your private
499 * data structures before returning from this slot. 499 * data structures before returning from this slot.
500 **/ 500 **/
501 void receivedStdout( Opie::Core::OProcess *proc, char *buffer, int buflen ); 501 void receivedStdout( Opie::Core::OProcess *proc, char *buffer, int buflen );
502 502
503 /** 503 /**
504 * Emitted when output from the child process has 504 * Emitted when output from the child process has
505 * been received on stdout. 505 * been received on stdout.
506 * 506 *
507 * To actually get these signals, the respective communications link 507 * To actually get these signals, the respective communications link
508 * (stdout/stderr) has to be turned on in @ref start() and the 508 * (stdout/stderr) has to be turned on in @ref start() and the
509 * @p NoRead flag should have been passed. 509 * @p NoRead flag should have been passed.
510 * 510 *
511 * You will need to explicitly call resume() after your call to start() 511 * You will need to explicitly call resume() after your call to start()
512 * to begin processing data from the child process's stdout. This is 512 * to begin processing data from the child process's stdout. This is
513 * to ensure that this signal is not emitted when no one is connected 513 * to ensure that this signal is not emitted when no one is connected
514 * to it, otherwise this signal will not be emitted. 514 * to it, otherwise this signal will not be emitted.
515 * 515 *
516 * The data still has to be read from file descriptor @p fd. 516 * The data still has to be read from file descriptor @p fd.
517 **/ 517 **/
518 void receivedStdout( int fd, int &len ); 518 void receivedStdout( int fd, int &len );
519 519
520 520
521 /** 521 /**
522 * Emitted, when output from the child process has 522 * Emitted, when output from the child process has
523 * been received on stderr. 523 * been received on stderr.
524 * To actually get 524 * To actually get
525 * these signals, the respective communication link (stdout/stderr) 525 * these signals, the respective communication link (stdout/stderr)
526 * has to be turned on in @ref start(). 526 * has to be turned on in @ref start().
527 * 527 *
528 * @param proc The process 528 * @param proc The process
529 * @param buffer The data received. 529 * @param buffer The data received.
530 * @param buflen The number of bytes that are available. 530 * @param buflen The number of bytes that are available.
531 * 531 *
532 * You should copy the information contained in @p buffer to your private 532 * You should copy the information contained in @p buffer to your private
533 * data structures before returning from this slot. 533 * data structures before returning from this slot.
534 */ 534 */
535 void receivedStderr( Opie::Core::OProcess *proc, char *buffer, int buflen ); 535 void receivedStderr( Opie::Core::OProcess *proc, char *buffer, int buflen );
536 536
537 /** 537 /**
538 * Emitted after all the data that has been 538 * Emitted after all the data that has been
539 * specified by a prior call to @ref writeStdin() has actually been 539 * specified by a prior call to @ref writeStdin() has actually been
540 * written to the child process. 540 * written to the child process.
541 **/ 541 **/
542 void wroteStdin( Opie::Core::OProcess *proc ); 542 void wroteStdin( Opie::Core::OProcess *proc );
543 543
544protected slots: 544protected slots:
545 545
546 /** 546 /**
547 * This slot gets activated when data from the child's stdout arrives. 547 * This slot gets activated when data from the child's stdout arrives.
548 * It usually calls "childOutput" 548 * It usually calls "childOutput"
549 */ 549 */
550 void slotChildOutput( int fdno ); 550 void slotChildOutput( int fdno );
551 551
552 /** 552 /**
553 * This slot gets activated when data from the child's stderr arrives. 553 * This slot gets activated when data from the child's stderr arrives.
554 * It usually calls "childError" 554 * It usually calls "childError"
555 */ 555 */
556 void slotChildError( int fdno ); 556 void slotChildError( int fdno );
557 /* 557 /*
558 Slot functions for capturing stdout and stderr of the child 558 Slot functions for capturing stdout and stderr of the child
559 */ 559 */
560 560
561 /** 561 /**
562 * Called when another bulk of data can be sent to the child's 562 * Called when another bulk of data can be sent to the child's
563 * stdin. If there is no more data to be sent to stdin currently 563 * stdin. If there is no more data to be sent to stdin currently
564 * available, this function must disable the QSocketNotifier "innot". 564 * available, this function must disable the QSocketNotifier "innot".
565 */ 565 */
566 void slotSendData( int dummy ); 566 void slotSendData( int dummy );
567 567
568protected: 568protected:
569 569
570 /** 570 /**
571 * Sets up the environment according to the data passed via 571 * Sets up the environment according to the data passed via
572 * setEnvironment(...) 572 * setEnvironment(...)
573 */ 573 */
574 void setupEnvironment(); 574 void setupEnvironment();
575 575
576 /** 576 /**
577 * The list of the process' command line arguments. The first entry 577 * The list of the process' command line arguments. The first entry
578 * in this list is the executable itself. 578 * in this list is the executable itself.
579 */ 579 */
580 QValueList<QCString> arguments; 580 QValueList<QCString> arguments;
581 /** 581 /**
582 * How to run the process (Block, NotifyOnExit, DontCare). You should 582 * How to run the process (Block, NotifyOnExit, DontCare). You should
583 * not modify this data member directly from derived classes. 583 * not modify this data member directly from derived classes.
584 */ 584 */
585 RunMode run_mode; 585 RunMode run_mode;
586 /** 586 /**
587 * true if the process is currently running. You should not 587 * true if the process is currently running. You should not
588 * modify this data member directly from derived classes. For 588 * modify this data member directly from derived classes. For
589 * reading the value of this data member, please use "isRunning()" 589 * reading the value of this data member, please use "isRunning()"
590 * since "runs" will probably be made private in later versions 590 * since "runs" will probably be made private in later versions
591 * of OProcess. 591 * of OProcess.
592 */ 592 */
593 bool runs; 593 bool runs;
594 594
595 /** 595 /**
596 * The PID of the currently running process (see "getPid()"). 596 * The PID of the currently running process (see "getPid()").
597 * You should not modify this data member in derived classes. 597 * You should not modify this data member in derived classes.
598 * Please use "getPid()" instead of directly accessing this 598 * Please use "getPid()" instead of directly accessing this
599 * member function since it will probably be made private in 599 * member function since it will probably be made private in
600 * later versions of OProcess. 600 * later versions of OProcess.
601 */ 601 */
602 pid_t pid_; 602 pid_t pid_;
603 603
604 /** 604 /**
605 * The process' exit status as returned by "waitpid". You should not 605 * The process' exit status as returned by "waitpid". You should not
606 * modify the value of this data member from derived classes. You should 606 * modify the value of this data member from derived classes. You should
607 * rather use @ref exitStatus than accessing this data member directly 607 * rather use @ref exitStatus than accessing this data member directly
608 * since it will probably be made private in further versions of 608 * since it will probably be made private in further versions of
609 * OProcess. 609 * OProcess.
610 */ 610 */
611 int status; 611 int status;
612 612
613 613
614 /** 614 /**
615 * See setRunPrivileged() 615 * See setRunPrivileged()
616 */ 616 */
617 bool keepPrivs; 617 bool keepPrivs;
618 618
619 /* 619 /*
620 Functions for setting up the sockets for communication. 620 Functions for setting up the sockets for communication.
621 setupCommunication 621 setupCommunication
622 -- is called from "start" before "fork"ing. 622 -- is called from "start" before "fork"ing.
623 commSetupDoneP 623 commSetupDoneP
624 -- completes communication socket setup in the parent 624 -- completes communication socket setup in the parent
625 commSetupDoneC 625 commSetupDoneC
626 -- completes communication setup in the child process 626 -- completes communication setup in the child process
627 commClose 627 commClose
628 -- frees all allocated communication resources in the parent 628 -- frees all allocated communication resources in the parent
629 after the process has exited 629 after the process has exited
630 */ 630 */
631 631
632 /** 632 /**
633 * This function is called from "OProcess::start" right before a "fork" takes 633 * This function is called from "OProcess::start" right before a "fork" takes
634 * place. According to 634 * place. According to
635 * the "comm" parameter this function has to initialize the "in", "out" and 635 * the "comm" parameter this function has to initialize the "in", "out" and
636 * "err" data member of OProcess. 636 * "err" data member of OProcess.
637 * 637 *
638 * This function should return 0 if setting the needed communication channels 638 * This function should return 0 if setting the needed communication channels
639 * was successful. 639 * was successful.
640 * 640 *
641 * The default implementation is to create UNIX STREAM sockets for the communication, 641 * The default implementation is to create UNIX STREAM sockets for the communication,
642 * but you could overload this function and establish a TCP/IP communication for 642 * but you could overload this function and establish a TCP/IP communication for
643 * network communication, for example. 643 * network communication, for example.
644 */ 644 */
645 virtual int setupCommunication( Communication comm ); 645 virtual int setupCommunication( Communication comm );
646 646
647 /** 647 /**
648 * Called right after a (successful) fork on the parent side. This function 648 * Called right after a (successful) fork on the parent side. This function
649 * will usually do some communications cleanup, like closing the reading end 649 * will usually do some communications cleanup, like closing the reading end
650 * of the "stdin" communication channel. 650 * of the "stdin" communication channel.
651 * 651 *
652 * Furthermore, it must also create the QSocketNotifiers "innot", "outnot" and 652 * Furthermore, it must also create the QSocketNotifiers "innot", "outnot" and
653 * "errnot" and connect their Qt slots to the respective OProcess member functions. 653 * "errnot" and connect their Qt slots to the respective OProcess member functions.
654 * 654 *
655 * For a more detailed explanation, it is best to have a look at the default 655 * For a more detailed explanation, it is best to have a look at the default
656 * implementation of "setupCommunication" in kprocess.cpp. 656 * implementation of "setupCommunication" in kprocess.cpp.
657 */ 657 */
658 virtual int commSetupDoneP(); 658 virtual int commSetupDoneP();
659 659
660 /** 660 /**
661 * Called right after a (successful) fork, but before an "exec" on the child 661 * Called right after a (successful) fork, but before an "exec" on the child
662 * process' side. It usually just closes the unused communication ends of 662 * process' side. It usually just closes the unused communication ends of
663 * "in", "out" and "err" (like the writing end of the "in" communication 663 * "in", "out" and "err" (like the writing end of the "in" communication
664 * channel. 664 * channel.
665 */ 665 */
666 virtual int commSetupDoneC(); 666 virtual int commSetupDoneC();
667 667
668 668
669 /** 669 /**
670 * Immediately called after a process has exited. This function normally 670 * Immediately called after a process has exited. This function normally
671 * calls commClose to close all open communication channels to this 671 * calls commClose to close all open communication channels to this
672 * process and emits the "processExited" signal (if the process was 672 * process and emits the "processExited" signal (if the process was
673 * not running in the "DontCare" mode). 673 * not running in the "DontCare" mode).
674 */ 674 */
675 virtual void processHasExited( int state ); 675 virtual void processHasExited( int state );
676 676
677 /** 677 /**
678 * Should clean up the communication links to the child after it has 678 * Should clean up the communication links to the child after it has
679 * exited. Should be called from "processHasExited". 679 * exited. Should be called from "processHasExited".
680 */ 680 */
681 virtual void commClose(); 681 virtual void commClose();
682 682
683 683
684 /** 684 /**
685 * the socket descriptors for stdin/stdout/stderr. 685 * the socket descriptors for stdin/stdout/stderr.
686 */ 686 */
687 int out[ 2 ]; 687 int out[ 2 ];
688 int in[ 2 ]; 688 int in[ 2 ];
689 int err[ 2 ]; 689 int err[ 2 ];
690 690
691 /** 691 /**
692 * The socket notifiers for the above socket descriptors. 692 * The socket notifiers for the above socket descriptors.
693 */ 693 */
694 QSocketNotifier *innot; 694 QSocketNotifier *innot;
695 QSocketNotifier *outnot; 695 QSocketNotifier *outnot;
696 QSocketNotifier *errnot; 696 QSocketNotifier *errnot;
697 697
698 /** 698 /**
699 * Lists the communication links that are activated for the child 699 * Lists the communication links that are activated for the child
700 * process. Should not be modified from derived classes. 700 * process. Should not be modified from derived classes.
701 */ 701 */
702 Communication communication; 702 Communication communication;
703 703
704 /** 704 /**
705 * Called by "slotChildOutput" this function copies data arriving from the 705 * Called by "slotChildOutput" this function copies data arriving from the
706 * child process's stdout to the respective buffer and emits the signal 706 * child process's stdout to the respective buffer and emits the signal
707 * "@ref receivedStderr". 707 * "@ref receivedStderr".
708 */ 708 */
709 int childOutput( int fdno ); 709 int childOutput( int fdno );
710 710
711 /** 711 /**
712 * Called by "slotChildOutput" this function copies data arriving from the 712 * Called by "slotChildOutput" this function copies data arriving from the
713 * child process's stdout to the respective buffer and emits the signal 713 * child process's stdout to the respective buffer and emits the signal
714 * "@ref receivedStderr" 714 * "@ref receivedStderr"
715 */ 715 */
716 int childError( int fdno ); 716 int childError( int fdno );
717 717
718 // information about the data that has to be sent to the child: 718 // information about the data that has to be sent to the child:
719 719
720 const char *input_data; // the buffer holding the data 720 const char *input_data; // the buffer holding the data
721 int input_sent; // # of bytes already transmitted 721 int input_sent; // # of bytes already transmitted
722 int input_total; // total length of input_data 722 int input_total; // total length of input_data
723 723
724 /** 724 /**
725 * @ref OProcessController is a friend of OProcess because it has to have 725 * @ref OProcessController is a friend of OProcess because it has to have
726 * access to various data members. 726 * access to various data members.
727 */ 727 */
728 friend class Internal::OProcessController; 728 friend class Internal::OProcessController;
729 729
730private: 730private:
731 /** 731 /**
732 * Searches for a valid shell. 732 * Searches for a valid shell.
733 * Here is the algorithm used for finding an executable shell: 733 * Here is the algorithm used for finding an executable shell:
734 * 734 *
735 * @li Try the executable pointed to by the "SHELL" environment 735 * @li Try the executable pointed to by the "SHELL" environment
736 * variable with white spaces stripped off 736 * variable with white spaces stripped off
737 * 737 *
738 * @li If your process runs with uid != euid or gid != egid, a shell 738 * @li If your process runs with uid != euid or gid != egid, a shell
739 * not listed in /etc/shells will not used. 739 * not listed in /etc/shells will not used.
740 * 740 *
741 * @li If no valid shell could be found, "/bin/sh" is used as a last resort. 741 * @li If no valid shell could be found, "/bin/sh" is used as a last resort.
742 */ 742 */
743 QCString searchShell(); 743 QCString searchShell();
744 744
745 /** 745 /**
746 * Used by @ref searchShell in order to find out whether the shell found 746 * Used by @ref searchShell in order to find out whether the shell found
747 * is actually executable at all. 747 * is actually executable at all.
748 */ 748 */
749 bool isExecutable( const QCString &filename ); 749 bool isExecutable( const QCString &filename );
750 750
751 // Disallow assignment and copy-construction 751 // Disallow assignment and copy-construction
752 OProcess( const OProcess& ); 752 OProcess( const OProcess& );
753 OProcess& operator= ( const OProcess& ); 753 OProcess& operator= ( const OProcess& );
754 754
755private: 755private:
756 void init ( ); 756 void init ( );
757 Internal::OProcessPrivate *d; 757 Internal::OProcessPrivate *d;
758}; 758};
759} 759}
760} 760}
761 761
762#endif 762#endif
763 763