summaryrefslogtreecommitdiff
path: root/libopie2
Unidiff
Diffstat (limited to 'libopie2') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiecore/oprocess.cpp689
-rw-r--r--libopie2/opiecore/oprocess.h152
2 files changed, 393 insertions, 448 deletions
diff --git a/libopie2/opiecore/oprocess.cpp b/libopie2/opiecore/oprocess.cpp
index fb51bf9..f1a5f3b 100644
--- a/libopie2/opiecore/oprocess.cpp
+++ b/libopie2/opiecore/oprocess.cpp
@@ -1,118 +1,97 @@
1/* 1/*
2 2                This file is part of the Opie Project
3 $Id$ 3             Copyright (C) 2002-2004 Holger Freyther <zecke@handhelds.org>
4 4 and The Opie Team <opie-devel@handhelds.org>
5 This file is part of the KDE libraries 5 =. Based on KProcess (C) 1997 Christian Czezatke (e9025461@student.tuwien.ac.at)
6 Copyright (C) 1997 Christian Czezatke (e9025461@student.tuwien.ac.at) 6 .=l.
7 7          .>+-=
8 This library is free software; you can redistribute it and/or 8_;:,     .>    :=|. This program is free software; you can
9 modify it under the terms of the GNU Library General Public 9.> <`_,   >  .   <= redistribute it and/or modify it under
10 License as published by the Free Software Foundation; either 10:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
11 version 2 of the License, or (at your option) any later version. 11.="- .-=="i,     .._ License as published by the Free Software
12 12- .   .-<_>     .<> Foundation; either version 2 of the License,
13 This library is distributed in the hope that it will be useful, 13    ._= =}       : or (at your option) any later version.
14 but WITHOUT ANY WARRANTY; without even the implied warranty of 14   .%`+i>       _;_.
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15   .i_,=:_.      -<s. This program is distributed in the hope that
16 Library General Public License for more details. 16    +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
17 17   : ..    .:,     . . . without even the implied warranty of
18 You should have received a copy of the GNU Library General Public License 18   =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
19 along with this library; see the file COPYING.LIB. If not, write to 19 _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 20..}^=.=       =       ; Library General Public License for more
21 Boston, MA 02111-1307, USA. 21++=   -.     .`     .: details.
22 22:     =  ...= . :.=-
23-.   .:....=;==+<; You should have received a copy of the GNU
24 -_. . .   )=.  = Library General Public License along with
25   --        :-=` this library; see the file COPYING.LIB.
26 If not, write to the Free Software Foundation,
27 Inc., 59 Temple Place - Suite 330,
28 Boston, MA 02111-1307, USA.
23*/ 29*/
24 30
25
26//
27// KPROCESS -- A class for handling child processes in KDE without
28// having to take care of Un*x specific implementation details
29//
30// version 0.3.1, Jan 8th 1998
31//
32// (C) Christian Czezatke
33// e9025461@student.tuwien.ac.at
34//
35// Changes:
36//
37// March 2nd, 1998: Changed parameter list for KShellProcess:
38// Arguments are now placed in a single string so that
39// <shell> -c <commandstring> is passed to the shell
40// to make the use of "operator<<" consistent with KProcess
41//
42//
43// Ported by Holger Freyther
44// <zekce> Harlekin: oprocess and say it was ported to Qt by the Opie developers an Qt 2
45
46
47
48#include "oprocess.h"
49#define _MAY_INCLUDE_KPROCESSCONTROLLER_
50#include "oprocctrl.h" 31#include "oprocctrl.h"
51 32
52//#include <config.h> 33/* OPIE */
34#include <opie2/oprocess.h>
35
36/* QT */
53 37
38#include <qapplication.h>
54#include <qfile.h> 39#include <qfile.h>
55#include <qsocketnotifier.h> 40#include <qmap.h>
56#include <qregexp.h> 41#include <qregexp.h>
42#include <qsocketnotifier.h>
57 43
58#include <sys/time.h> 44/* STD */
59#include <sys/types.h>
60#include <sys/stat.h>
61#include <sys/socket.h>
62
63#include <errno.h> 45#include <errno.h>
64#include <fcntl.h> 46#include <fcntl.h>
47#include <pwd.h>
65#include <stdlib.h> 48#include <stdlib.h>
66#include <signal.h> 49#include <signal.h>
67#include <stdio.h> 50#include <stdio.h>
68#include <string.h> 51#include <string.h>
52#include <sys/time.h>
53#include <sys/types.h>
54#include <sys/stat.h>
55#include <sys/socket.h>
69#include <unistd.h> 56#include <unistd.h>
70#ifdef HAVE_SYS_SELECT_H 57#ifdef HAVE_SYS_SELECT_H
71#include <sys/select.h> 58#include <sys/select.h>
72#endif 59#endif
73#ifdef HAVE_INITGROUPS 60#ifdef HAVE_INITGROUPS
74#include <grp.h> 61#include <grp.h>
75#endif 62#endif
76#include <pwd.h>
77
78#include <qapplication.h>
79#include <qmap.h>
80//#include <kdebug.h>
81
82/////////////////////////////
83// public member functions //
84/////////////////////////////
85 63
86class OProcessPrivate 64class OProcessPrivate
87{ 65{
88public: 66public:
89 OProcessPrivate() : useShell(false) { } 67 OProcessPrivate() : useShell( false )
68 { }
90 69
91 bool useShell; 70 bool useShell;
92 QMap<QString,QString> env; 71 QMap<QString, QString> env;
93 QString wd; 72 QString wd;
94 QCString shell; 73 QCString shell;
95}; 74};
96 75
97 76
98OProcess::OProcess(QObject *parent, const char *name) 77OProcess::OProcess( QObject *parent, const char *name )
99 : QObject(parent, name) 78 : QObject( parent, name )
100{ 79{
101 init ( ); 80 init ( );
102} 81}
103 82
104OProcess::OProcess(const QString &arg0, QObject *parent, const char *name) 83OProcess::OProcess( const QString &arg0, QObject *parent, const char *name )
105 : QObject(parent, name) 84 : QObject( parent, name )
106{ 85{
107 init ( ); 86 init ( );
108 *this << arg0; 87 *this << arg0;
109} 88}
110 89
111OProcess::OProcess(const QStringList &args, QObject *parent, const char *name) 90OProcess::OProcess( const QStringList &args, QObject *parent, const char *name )
112 : QObject(parent, name) 91 : QObject( parent, name )
113{ 92{
114 init ( ); 93 init ( );
115 *this << args; 94 *this << args;
116} 95}
117 96
118void OProcess::init ( ) 97void OProcess::init ( )
@@ -128,389 +107,379 @@ void OProcess::init ( )
128 communication = NoCommunication; 107 communication = NoCommunication;
129 input_data = 0; 108 input_data = 0;
130 input_sent = 0; 109 input_sent = 0;
131 input_total = 0; 110 input_total = 0;
132 d = 0; 111 d = 0;
133 112
134 if (0 == OProcessController::theOProcessController) 113 if ( 0 == OProcessController::theOProcessController )
135 { 114 {
136 (void) new OProcessController(); 115 ( void ) new OProcessController();
137 CHECK_PTR(OProcessController::theOProcessController); 116 CHECK_PTR( OProcessController::theOProcessController );
138 } 117 }
139 118
140 OProcessController::theOProcessController->addOProcess(this); 119 OProcessController::theOProcessController->addOProcess( this );
141 out[0] = out[1] = -1; 120 out[ 0 ] = out[ 1 ] = -1;
142 in[0] = in[1] = -1; 121 in[ 0 ] = in[ 1 ] = -1;
143 err[0] = err[1] = -1; 122 err[ 0 ] = err[ 1 ] = -1;
144} 123}
145 124
146void 125void OProcess::setEnvironment( const QString &name, const QString &value )
147OProcess::setEnvironment(const QString &name, const QString &value)
148{ 126{
149 if (!d) 127 if ( !d )
150 d = new OProcessPrivate; 128 d = new OProcessPrivate;
151 d->env.insert(name, value); 129 d->env.insert( name, value );
152} 130}
153 131
154void 132void OProcess::setWorkingDirectory( const QString &dir )
155OProcess::setWorkingDirectory(const QString &dir)
156{ 133{
157 if (!d) 134 if ( !d )
158 d = new OProcessPrivate; 135 d = new OProcessPrivate;
159 d->wd = dir; 136 d->wd = dir;
160} 137}
161 138
162void 139void OProcess::setupEnvironment()
163OProcess::setupEnvironment()
164{ 140{
165 if (d) 141 if ( d )
166 { 142 {
167 QMap<QString,QString>::Iterator it; 143 QMap<QString, QString>::Iterator it;
168 for(it = d->env.begin(); it != d->env.end(); ++it) 144 for ( it = d->env.begin(); it != d->env.end(); ++it )
169 setenv(QFile::encodeName(it.key()).data(), 145 setenv( QFile::encodeName( it.key() ).data(),
170 QFile::encodeName(it.data()).data(), 1); 146 QFile::encodeName( it.data() ).data(), 1 );
171 if (!d->wd.isEmpty()) 147 if ( !d->wd.isEmpty() )
172 chdir(QFile::encodeName(d->wd).data()); 148 chdir( QFile::encodeName( d->wd ).data() );
173 } 149 }
174} 150}
175 151
176void 152void OProcess::setRunPrivileged( bool keepPrivileges )
177OProcess::setRunPrivileged(bool keepPrivileges)
178{ 153{
179 keepPrivs = keepPrivileges; 154 keepPrivs = keepPrivileges;
180} 155}
181 156
182bool 157bool OProcess::runPrivileged() const
183OProcess::runPrivileged() const
184{ 158{
185 return keepPrivs; 159 return keepPrivs;
186} 160}
187 161
188
189OProcess::~OProcess() 162OProcess::~OProcess()
190{ 163{
191 // destroying the OProcess instance sends a SIGKILL to the 164 // destroying the OProcess instance sends a SIGKILL to the
192 // child process (if it is running) after removing it from the 165 // child process (if it is running) after removing it from the
193 // list of valid processes (if the process is not started as 166 // list of valid processes (if the process is not started as
194 // "DontCare") 167 // "DontCare")
195 168
196 OProcessController::theOProcessController->removeOProcess(this); 169 OProcessController::theOProcessController->removeOProcess( this );
197 // this must happen before we kill the child 170 // this must happen before we kill the child
198 // TODO: block the signal while removing the current process from the process list 171 // TODO: block the signal while removing the current process from the process list
199 172
200 if (runs && (run_mode != DontCare)) 173 if ( runs && ( run_mode != DontCare ) )
201 kill(SIGKILL); 174 kill( SIGKILL );
202 175
203 // Clean up open fd's and socket notifiers. 176 // Clean up open fd's and socket notifiers.
204 closeStdin(); 177 closeStdin();
205 closeStdout(); 178 closeStdout();
206 closeStderr(); 179 closeStderr();
207 180
208 // TODO: restore SIGCHLD and SIGPIPE handler if this is the last OProcess 181 // TODO: restore SIGCHLD and SIGPIPE handler if this is the last OProcess
209 delete d; 182 delete d;
210} 183}
211 184
212void OProcess::detach() 185void OProcess::detach()
213{ 186{
214 OProcessController::theOProcessController->removeOProcess(this); 187 OProcessController::theOProcessController->removeOProcess( this );
215 188
216 runs = false; 189 runs = false;
217 pid_ = 0; 190 pid_ = 0;
218 191
219 // Clean up open fd's and socket notifiers. 192 // Clean up open fd's and socket notifiers.
220 closeStdin(); 193 closeStdin();
221 closeStdout(); 194 closeStdout();
222 closeStderr(); 195 closeStderr();
223} 196}
224 197
225bool OProcess::setExecutable(const QString& proc) 198bool OProcess::setExecutable( const QString& proc )
226{ 199{
227 if (runs) return false; 200 if ( runs )
201 return false;
228 202
229 if (proc.isEmpty()) return false; 203 if ( proc.isEmpty() )
204 return false;
230 205
231 if (!arguments.isEmpty()) 206 if ( !arguments.isEmpty() )
232 arguments.remove(arguments.begin()); 207 arguments.remove( arguments.begin() );
233 arguments.prepend(QFile::encodeName(proc)); 208 arguments.prepend( QFile::encodeName( proc ) );
234 209
235 return true; 210 return true;
236} 211}
237 212
238OProcess &OProcess::operator<<(const QStringList& args) 213OProcess &OProcess::operator<<( const QStringList& args )
239{ 214{
240 QStringList::ConstIterator it = args.begin(); 215 QStringList::ConstIterator it = args.begin();
241 for ( ; it != args.end() ; ++it ) 216 for ( ; it != args.end() ; ++it )
242 arguments.append(QFile::encodeName(*it)); 217 arguments.append( QFile::encodeName( *it ) );
243 return *this; 218 return *this;
244} 219}
245 220
246OProcess &OProcess::operator<<(const QCString& arg) 221OProcess &OProcess::operator<<( const QCString& arg )
247{ 222{
248 return operator<< (arg.data()); 223 return operator<< ( arg.data() );
249} 224}
250 225
251OProcess &OProcess::operator<<(const char* arg) 226OProcess &OProcess::operator<<( const char* arg )
252{ 227{
253 arguments.append(arg); 228 arguments.append( arg );
254 return *this; 229 return *this;
255} 230}
256 231
257OProcess &OProcess::operator<<(const QString& arg) 232OProcess &OProcess::operator<<( const QString& arg )
258{ 233{
259 arguments.append(QFile::encodeName(arg)); 234 arguments.append( QFile::encodeName( arg ) );
260 return *this; 235 return *this;
261} 236}
262 237
263void OProcess::clearArguments() 238void OProcess::clearArguments()
264{ 239{
265 arguments.clear(); 240 arguments.clear();
266} 241}
267 242
268bool OProcess::start(RunMode runmode, Communication comm) 243bool OProcess::start( RunMode runmode, Communication comm )
269{ 244{
270 uint i; 245 uint i;
271 uint n = arguments.count(); 246 uint n = arguments.count();
272 char **arglist; 247 char **arglist;
273 248
274 if (runs || (0 == n)) 249 if ( runs || ( 0 == n ) )
275 { 250 {
276 return false; // cannot start a process that is already running 251 return false; // cannot start a process that is already running
277 // or if no executable has been assigned 252 // or if no executable has been assigned
278 } 253 }
279 run_mode = runmode; 254 run_mode = runmode;
280 status = 0; 255 status = 0;
281 256
282 QCString shellCmd; 257 QCString shellCmd;
283 if (d && d->useShell) 258 if ( d && d->useShell )
284 { 259 {
285 if (d->shell.isEmpty()) 260 if ( d->shell.isEmpty() )
286 { 261 {
287 qWarning( "Could not find a valid shell" ); 262 qWarning( "Could not find a valid shell" );
288 return false; 263 return false;
289 } 264 }
290 265
291 arglist = static_cast<char **>(malloc( (4)*sizeof(char *))); 266 arglist = static_cast<char **>( malloc( ( 4 ) * sizeof( char * ) ) );
292 for (i=0; i < n; i++) 267 for ( i = 0; i < n; i++ )
293 { 268 {
294 shellCmd += arguments[i]; 269 shellCmd += arguments[ i ];
295 shellCmd += " "; // CC: to separate the arguments 270 shellCmd += " "; // CC: to separate the arguments
296 } 271 }
297 272
298 arglist[0] = d->shell.data(); 273 arglist[ 0 ] = d->shell.data();
299 arglist[1] = (char *) "-c"; 274 arglist[ 1 ] = ( char * ) "-c";
300 arglist[2] = shellCmd.data(); 275 arglist[ 2 ] = shellCmd.data();
301 arglist[3] = 0; 276 arglist[ 3 ] = 0;
302 } 277 }
303 else 278 else
304 { 279 {
305 arglist = static_cast<char **>(malloc( (n+1)*sizeof(char *))); 280 arglist = static_cast<char **>( malloc( ( n + 1 ) * sizeof( char * ) ) );
306 for (i=0; i < n; i++) 281 for ( i = 0; i < n; i++ )
307 arglist[i] = arguments[i].data(); 282 arglist[ i ] = arguments[ i ].data();
308 arglist[n]= 0; 283 arglist[ n ] = 0;
309 } 284 }
310 285
311 if (!setupCommunication(comm)) 286 if ( !setupCommunication( comm ) )
312 qWarning( "Could not setup Communication!"); 287 qWarning( "Could not setup Communication!" );
313 288
314 // We do this in the parent because if we do it in the child process 289 // We do this in the parent because if we do it in the child process
315 // gdb gets confused when the application runs from gdb. 290 // gdb gets confused when the application runs from gdb.
316 uid_t uid = getuid(); 291 uid_t uid = getuid();
317 gid_t gid = getgid(); 292 gid_t gid = getgid();
318#ifdef HAVE_INITGROUPS 293#ifdef HAVE_INITGROUPS
319 struct passwd *pw = getpwuid(uid); 294
295 struct passwd *pw = getpwuid( uid );
320#endif 296#endif
321 297
322 int fd[2]; 298 int fd[ 2 ];
323 if (0 > pipe(fd)) 299 if ( 0 > pipe( fd ) )
324 { 300 {
325 fd[0] = fd[1] = 0; // Pipe failed.. continue 301 fd[ 0 ] = fd[ 1 ] = 0; // Pipe failed.. continue
326 } 302 }
327 303
328 runs = true; 304 runs = true;
329 305
330 QApplication::flushX(); 306 QApplication::flushX();
331 307
332 // WABA: Note that we use fork() and not vfork() because 308 // WABA: Note that we use fork() and not vfork() because
333 // vfork() has unclear semantics and is not standardized. 309 // vfork() has unclear semantics and is not standardized.
334 pid_ = fork(); 310 pid_ = fork();
335 311
336 if (0 == pid_) 312 if ( 0 == pid_ )
337 { 313 {
338 if (fd[0]) 314 if ( fd[ 0 ] )
339 close(fd[0]); 315 close( fd[ 0 ] );
340 if (!runPrivileged()) 316 if ( !runPrivileged() )
341 { 317 {
342 setgid(gid); 318 setgid( gid );
343#if defined( HAVE_INITGROUPS) 319#if defined( HAVE_INITGROUPS)
344 if(pw) 320
345 initgroups(pw->pw_name, pw->pw_gid); 321 if ( pw )
322 initgroups( pw->pw_name, pw->pw_gid );
346#endif 323#endif
347 setuid(uid); 324
325 setuid( uid );
348 } 326 }
349 // The child process 327 // The child process
350 if(!commSetupDoneC()) 328 if ( !commSetupDoneC() )
351 qWarning( "Could not finish comm setup in child!" ); 329 qWarning( "Could not finish comm setup in child!" );
352 330
353 setupEnvironment(); 331 setupEnvironment();
354 332
355 // Matthias 333 // Matthias
356 if (run_mode == DontCare) 334 if ( run_mode == DontCare )
357 setpgid(0,0); 335 setpgid( 0, 0 );
358 // restore default SIGPIPE handler (Harri) 336 // restore default SIGPIPE handler (Harri)
359 struct sigaction act; 337 struct sigaction act;
360 sigemptyset(&(act.sa_mask)); 338 sigemptyset( &( act.sa_mask ) );
361 sigaddset(&(act.sa_mask), SIGPIPE); 339 sigaddset( &( act.sa_mask ), SIGPIPE );
362 act.sa_handler = SIG_DFL; 340 act.sa_handler = SIG_DFL;
363 act.sa_flags = 0; 341 act.sa_flags = 0;
364 sigaction(SIGPIPE, &act, 0L); 342 sigaction( SIGPIPE, &act, 0L );
365 343
366 // We set the close on exec flag. 344 // We set the close on exec flag.
367 // Closing of fd[1] indicates that the execvp succeeded! 345 // Closing of fd[1] indicates that the execvp succeeded!
368 if (fd[1]) 346 if ( fd[ 1 ] )
369 fcntl(fd[1], F_SETFD, FD_CLOEXEC); 347 fcntl( fd[ 1 ], F_SETFD, FD_CLOEXEC );
370 execvp(arglist[0], arglist); 348 execvp( arglist[ 0 ], arglist );
371 char resultByte = 1; 349 char resultByte = 1;
372 if (fd[1]) 350 if ( fd[ 1 ] )
373 write(fd[1], &resultByte, 1); 351 write( fd[ 1 ], &resultByte, 1 );
374 _exit(-1); 352 _exit( -1 );
375 } 353 }
376 else if (-1 == pid_) 354 else if ( -1 == pid_ )
377 { 355 {
378 // forking failed 356 // forking failed
379 357
380 runs = false; 358 runs = false;
381 free(arglist); 359 free( arglist );
382 return false; 360 return false;
383 } 361 }
384 else 362 else
385 { 363 {
386 if (fd[1]) 364 if ( fd[ 1 ] )
387 close(fd[1]); 365 close( fd[ 1 ] );
388 // the parent continues here 366 // the parent continues here
389 367
390 // Discard any data for stdin that might still be there 368 // Discard any data for stdin that might still be there
391 input_data = 0; 369 input_data = 0;
392 370
393 // Check whether client could be started. 371 // Check whether client could be started.
394 if (fd[0]) for(;;) 372 if ( fd[ 0 ] )
373 for ( ;; )
395 { 374 {
396 char resultByte; 375 char resultByte;
397 int n = ::read(fd[0], &resultByte, 1); 376 int n = ::read( fd[ 0 ], &resultByte, 1 );
398 if (n == 1) 377 if ( n == 1 )
399 { 378 {
400 // Error 379 // Error
401 runs = false; 380 runs = false;
402 close(fd[0]); 381 close( fd[ 0 ] );
403 free(arglist); 382 free( arglist );
404 pid_ = 0; 383 pid_ = 0;
405 return false; 384 return false;
406 } 385 }
407 if (n == -1) 386 if ( n == -1 )
408 { 387 {
409 if ((errno == ECHILD) || (errno == EINTR)) 388 if ( ( errno == ECHILD ) || ( errno == EINTR ) )
410 continue; // Ignore 389 continue; // Ignore
411 } 390 }
412 break; // success 391 break; // success
413 } 392 }
414 if (fd[0]) 393 if ( fd[ 0 ] )
415 close(fd[0]); 394 close( fd[ 0 ] );
416 395
417 if (!commSetupDoneP()) // finish communication socket setup for the parent 396 if ( !commSetupDoneP() ) // finish communication socket setup for the parent
418 qWarning( "Could not finish comm setup in parent!" ); 397 qWarning( "Could not finish comm setup in parent!" );
419 398
420 if (run_mode == Block) 399 if ( run_mode == Block )
421 { 400 {
422 commClose(); 401 commClose();
423 402
424 // The SIGCHLD handler of the process controller will catch 403 // The SIGCHLD handler of the process controller will catch
425 // the exit and set the status 404 // the exit and set the status
426 while(runs) 405 while ( runs )
427 { 406 {
428 OProcessController::theOProcessController-> 407 OProcessController::theOProcessController->
429 slotDoHousekeeping(0); 408 slotDoHousekeeping( 0 );
430 } 409 }
431 runs = FALSE; 410 runs = FALSE;
432 emit processExited(this); 411 emit processExited( this );
433 } 412 }
434 } 413 }
435 free(arglist); 414 free( arglist );
436 return true; 415 return true;
437} 416}
438 417
439 418
440 419
441bool OProcess::kill(int signo) 420bool OProcess::kill( int signo )
442{ 421{
443 bool rv=false; 422 bool rv = false;
444 423
445 if (0 != pid_) 424 if ( 0 != pid_ )
446 rv= (-1 != ::kill(pid_, signo)); 425 rv = ( -1 != ::kill( pid_, signo ) );
447 // probably store errno somewhere... 426 // probably store errno somewhere...
448 return rv; 427 return rv;
449} 428}
450 429
451
452
453bool OProcess::isRunning() const 430bool OProcess::isRunning() const
454{ 431{
455 return runs; 432 return runs;
456} 433}
457 434
458
459
460pid_t OProcess::pid() const 435pid_t OProcess::pid() const
461{ 436{
462 return pid_; 437 return pid_;
463} 438}
464 439
465
466
467bool OProcess::normalExit() const 440bool OProcess::normalExit() const
468{ 441{
469 int _status = status; 442 int _status = status;
470 return (pid_ != 0) && (!runs) && (WIFEXITED((_status))); 443 return ( pid_ != 0 ) && ( !runs ) && ( WIFEXITED( ( _status ) ) );
471} 444}
472 445
473
474
475int OProcess::exitStatus() const 446int OProcess::exitStatus() const
476{ 447{
477 int _status = status; 448 int _status = status;
478 return WEXITSTATUS((_status)); 449 return WEXITSTATUS( ( _status ) );
479} 450}
480 451
481 452bool OProcess::writeStdin( const char *buffer, int buflen )
482
483bool OProcess::writeStdin(const char *buffer, int buflen)
484{ 453{
485 bool rv; 454 bool rv;
486 455
487 // if there is still data pending, writing new data 456 // if there is still data pending, writing new data
488 // to stdout is not allowed (since it could also confuse 457 // to stdout is not allowed (since it could also confuse
489 // kprocess... 458 // kprocess...
490 if (0 != input_data) 459 if ( 0 != input_data )
491 return false; 460 return false;
492 461
493 if (runs && (communication & Stdin)) 462 if ( runs && ( communication & Stdin ) )
494 { 463 {
495 input_data = buffer; 464 input_data = buffer;
496 input_sent = 0; 465 input_sent = 0;
497 input_total = buflen; 466 input_total = buflen;
498 slotSendData(0); 467 slotSendData( 0 );
499 innot->setEnabled(true); 468 innot->setEnabled( true );
500 rv = true; 469 rv = true;
501 } 470 }
502 else 471 else
503 rv = false; 472 rv = false;
504 return rv; 473 return rv;
505} 474}
506 475
507void OProcess::flushStdin ( ) 476void OProcess::flushStdin ( )
508{ 477{
509 if ( !input_data || ( input_sent == input_total )) 478 if ( !input_data || ( input_sent == input_total ) )
510 return; 479 return ;
511 480
512 int d1, d2; 481 int d1, d2;
513 482
514 do 483 do
515 { 484 {
516 d1 = input_total - input_sent; 485 d1 = input_total - input_sent;
@@ -519,452 +488,428 @@ void OProcess::flushStdin ( )
519 } 488 }
520 while ( d2 <= d1 ); 489 while ( d2 <= d1 );
521} 490}
522 491
523void OProcess::suspend() 492void OProcess::suspend()
524{ 493{
525 if ((communication & Stdout) && outnot) 494 if ( ( communication & Stdout ) && outnot )
526 outnot->setEnabled(false); 495 outnot->setEnabled( false );
527} 496}
528 497
529void OProcess::resume() 498void OProcess::resume()
530{ 499{
531 if ((communication & Stdout) && outnot) 500 if ( ( communication & Stdout ) && outnot )
532 outnot->setEnabled(true); 501 outnot->setEnabled( true );
533} 502}
534 503
535bool OProcess::closeStdin() 504bool OProcess::closeStdin()
536{ 505{
537 bool rv; 506 bool rv;
538 507
539 if (communication & Stdin) 508 if ( communication & Stdin )
540 { 509 {
541 communication = (Communication) (communication & ~Stdin); 510 communication = ( Communication ) ( communication & ~Stdin );
542 delete innot; 511 delete innot;
543 innot = 0; 512 innot = 0;
544 close(in[1]); 513 close( in[ 1 ] );
545 rv = true; 514 rv = true;
546 } 515 }
547 else 516 else
548 rv = false; 517 rv = false;
549 return rv; 518 return rv;
550} 519}
551 520
552bool OProcess::closeStdout() 521bool OProcess::closeStdout()
553{ 522{
554 bool rv; 523 bool rv;
555 524
556 if (communication & Stdout) 525 if ( communication & Stdout )
557 { 526 {
558 communication = (Communication) (communication & ~Stdout); 527 communication = ( Communication ) ( communication & ~Stdout );
559 delete outnot; 528 delete outnot;
560 outnot = 0; 529 outnot = 0;
561 close(out[0]); 530 close( out[ 0 ] );
562 rv = true; 531 rv = true;
563 } 532 }
564 else 533 else
565 rv = false; 534 rv = false;
566 return rv; 535 return rv;
567} 536}
568 537
569bool OProcess::closeStderr() 538bool OProcess::closeStderr()
570{ 539{
571 bool rv; 540 bool rv;
572 541
573 if (communication & Stderr) 542 if ( communication & Stderr )
574 { 543 {
575 communication = static_cast<Communication>(communication & ~Stderr); 544 communication = static_cast<Communication>( communication & ~Stderr );
576 delete errnot; 545 delete errnot;
577 errnot = 0; 546 errnot = 0;
578 close(err[0]); 547 close( err[ 0 ] );
579 rv = true; 548 rv = true;
580 } 549 }
581 else 550 else
582 rv = false; 551 rv = false;
583 return rv; 552 return rv;
584} 553}
585 554
586 555void OProcess::slotChildOutput( int fdno )
587/////////////////////////////
588// protected slots //
589/////////////////////////////
590
591
592
593void OProcess::slotChildOutput(int fdno)
594{ 556{
595 if (!childOutput(fdno)) 557 if ( !childOutput( fdno ) )
596 closeStdout(); 558 closeStdout();
597} 559}
598 560
599 561void OProcess::slotChildError( int fdno )
600void OProcess::slotChildError(int fdno)
601{ 562{
602 if (!childError(fdno)) 563 if ( !childError( fdno ) )
603 closeStderr(); 564 closeStderr();
604} 565}
605 566
606 567void OProcess::slotSendData( int )
607void OProcess::slotSendData(int)
608{ 568{
609 if (input_sent == input_total) 569 if ( input_sent == input_total )
610 { 570 {
611 innot->setEnabled(false); 571 innot->setEnabled( false );
612 input_data = 0; 572 input_data = 0;
613 emit wroteStdin(this); 573 emit wroteStdin( this );
614 } 574 }
615 else 575 else
616 input_sent += ::write(in[1], input_data+input_sent, input_total-input_sent); 576 input_sent += ::write( in[ 1 ], input_data + input_sent, input_total - input_sent );
617} 577}
618 578
619 579void OProcess::processHasExited( int state )
620
621//////////////////////////////
622// private member functions //
623//////////////////////////////
624
625
626
627void OProcess::processHasExited(int state)
628{ 580{
629 if (runs) 581 if ( runs )
630 { 582 {
631 runs = false; 583 runs = false;
632 status = state; 584 status = state;
633 585
634 commClose(); // cleanup communication sockets 586 commClose(); // cleanup communication sockets
635 587
636 // also emit a signal if the process was run Blocking 588 // also emit a signal if the process was run Blocking
637 if (DontCare != run_mode) 589 if ( DontCare != run_mode )
638 { 590 {
639 emit processExited(this); 591 emit processExited( this );
640 } 592 }
641 } 593 }
642} 594}
643 595
644 596int OProcess::childOutput( int fdno )
645
646int OProcess::childOutput(int fdno)
647{ 597{
648 if (communication & NoRead) 598 if ( communication & NoRead )
649 { 599 {
650 int len = -1; 600 int len = -1;
651 emit receivedStdout(fdno, len); 601 emit receivedStdout( fdno, len );
652 errno = 0; // Make sure errno doesn't read "EAGAIN" 602 errno = 0; // Make sure errno doesn't read "EAGAIN"
653 return len; 603 return len;
654 } 604 }
655 else 605 else
656 { 606 {
657 char buffer[1024]; 607 char buffer[ 1024 ];
658 int len; 608 int len;
659 609
660 len = ::read(fdno, buffer, 1024); 610 len = ::read( fdno, buffer, 1024 );
661 611
662 if ( 0 < len) 612 if ( 0 < len )
663 { 613 {
664 emit receivedStdout(this, buffer, len); 614 emit receivedStdout( this, buffer, len );
665 } 615 }
666 return len; 616 return len;
667 } 617 }
668} 618}
669 619
670 620int OProcess::childError( int fdno )
671
672int OProcess::childError(int fdno)
673{ 621{
674 char buffer[1024]; 622 char buffer[ 1024 ];
675 int len; 623 int len;
676 624
677 len = ::read(fdno, buffer, 1024); 625 len = ::read( fdno, buffer, 1024 );
678 626
679 if ( 0 < len) 627 if ( 0 < len )
680 emit receivedStderr(this, buffer, len); 628 emit receivedStderr( this, buffer, len );
681 return len; 629 return len;
682} 630}
683 631
684 632int OProcess::setupCommunication( Communication comm )
685
686int OProcess::setupCommunication(Communication comm)
687{ 633{
688 int ok; 634 int ok;
689 635
690 communication = comm; 636 communication = comm;
691 637
692 ok = 1; 638 ok = 1;
693 if (comm & Stdin) 639 if ( comm & Stdin )
694 ok &= socketpair(AF_UNIX, SOCK_STREAM, 0, in) >= 0; 640 ok &= socketpair( AF_UNIX, SOCK_STREAM, 0, in ) >= 0;
695 641
696 if (comm & Stdout) 642 if ( comm & Stdout )
697 ok &= socketpair(AF_UNIX, SOCK_STREAM, 0, out) >= 0; 643 ok &= socketpair( AF_UNIX, SOCK_STREAM, 0, out ) >= 0;
698 644
699 if (comm & Stderr) 645 if ( comm & Stderr )
700 ok &= socketpair(AF_UNIX, SOCK_STREAM, 0, err) >= 0; 646 ok &= socketpair( AF_UNIX, SOCK_STREAM, 0, err ) >= 0;
701 647
702 return ok; 648 return ok;
703} 649}
704 650
705
706
707int OProcess::commSetupDoneP() 651int OProcess::commSetupDoneP()
708{ 652{
709 int ok = 1; 653 int ok = 1;
710 654
711 if (communication != NoCommunication) 655 if ( communication != NoCommunication )
712 { 656 {
713 if (communication & Stdin) 657 if ( communication & Stdin )
714 close(in[0]); 658 close( in[ 0 ] );
715 if (communication & Stdout) 659 if ( communication & Stdout )
716 close(out[1]); 660 close( out[ 1 ] );
717 if (communication & Stderr) 661 if ( communication & Stderr )
718 close(err[1]); 662 close( err[ 1 ] );
719 663
720 // Don't create socket notifiers and set the sockets non-blocking if 664 // Don't create socket notifiers and set the sockets non-blocking if
721 // blocking is requested. 665 // blocking is requested.
722 if (run_mode == Block) return ok; 666 if ( run_mode == Block )
667 return ok;
723 668
724 if (communication & Stdin) 669 if ( communication & Stdin )
725 { 670 {
726 // ok &= (-1 != fcntl(in[1], F_SETFL, O_NONBLOCK)); 671 // ok &= (-1 != fcntl(in[1], F_SETFL, O_NONBLOCK));
727 innot = new QSocketNotifier(in[1], QSocketNotifier::Write, this); 672 innot = new QSocketNotifier( in[ 1 ], QSocketNotifier::Write, this );
728 CHECK_PTR(innot); 673 CHECK_PTR( innot );
729 innot->setEnabled(false); // will be enabled when data has to be sent 674 innot->setEnabled( false ); // will be enabled when data has to be sent
730 QObject::connect(innot, SIGNAL(activated(int)), 675 QObject::connect( innot, SIGNAL( activated( int ) ),
731 this, SLOT(slotSendData(int))); 676 this, SLOT( slotSendData( int ) ) );
732 } 677 }
733 678
734 if (communication & Stdout) 679 if ( communication & Stdout )
735 { 680 {
736 // ok &= (-1 != fcntl(out[0], F_SETFL, O_NONBLOCK)); 681 // ok &= (-1 != fcntl(out[0], F_SETFL, O_NONBLOCK));
737 outnot = new QSocketNotifier(out[0], QSocketNotifier::Read, this); 682 outnot = new QSocketNotifier( out[ 0 ], QSocketNotifier::Read, this );
738 CHECK_PTR(outnot); 683 CHECK_PTR( outnot );
739 QObject::connect(outnot, SIGNAL(activated(int)), 684 QObject::connect( outnot, SIGNAL( activated( int ) ),
740 this, SLOT(slotChildOutput(int))); 685 this, SLOT( slotChildOutput( int ) ) );
741 if (communication & NoRead) 686 if ( communication & NoRead )
742 suspend(); 687 suspend();
743 } 688 }
744 689
745 if (communication & Stderr) 690 if ( communication & Stderr )
746 { 691 {
747 // ok &= (-1 != fcntl(err[0], F_SETFL, O_NONBLOCK)); 692 // ok &= (-1 != fcntl(err[0], F_SETFL, O_NONBLOCK));
748 errnot = new QSocketNotifier(err[0], QSocketNotifier::Read, this ); 693 errnot = new QSocketNotifier( err[ 0 ], QSocketNotifier::Read, this );
749 CHECK_PTR(errnot); 694 CHECK_PTR( errnot );
750 QObject::connect(errnot, SIGNAL(activated(int)), 695 QObject::connect( errnot, SIGNAL( activated( int ) ),
751 this, SLOT(slotChildError(int))); 696 this, SLOT( slotChildError( int ) ) );
752 } 697 }
753 } 698 }
754 return ok; 699 return ok;
755} 700}
756 701
757
758
759int OProcess::commSetupDoneC() 702int OProcess::commSetupDoneC()
760{ 703{
761 int ok = 1; 704 int ok = 1;
762 struct linger so; 705 struct linger so;
763 memset(&so, 0, sizeof(so)); 706 memset( &so, 0, sizeof( so ) );
764 707
765 if (communication & Stdin) 708 if ( communication & Stdin )
766 close(in[1]); 709 close( in[ 1 ] );
767 if (communication & Stdout) 710 if ( communication & Stdout )
768 close(out[0]); 711 close( out[ 0 ] );
769 if (communication & Stderr) 712 if ( communication & Stderr )
770 close(err[0]); 713 close( err[ 0 ] );
771 714
772 if (communication & Stdin) 715 if ( communication & Stdin )
773 ok &= dup2(in[0], STDIN_FILENO) != -1; 716 ok &= dup2( in[ 0 ], STDIN_FILENO ) != -1;
774 else 717 else
775 { 718 {
776 int null_fd = open( "/dev/null", O_RDONLY ); 719 int null_fd = open( "/dev/null", O_RDONLY );
777 ok &= dup2( null_fd, STDIN_FILENO ) != -1; 720 ok &= dup2( null_fd, STDIN_FILENO ) != -1;
778 close( null_fd ); 721 close( null_fd );
779 } 722 }
780 if (communication & Stdout) 723 if ( communication & Stdout )
781 { 724 {
782 ok &= dup2(out[1], STDOUT_FILENO) != -1; 725 ok &= dup2( out[ 1 ], STDOUT_FILENO ) != -1;
783 ok &= !setsockopt(out[1], SOL_SOCKET, SO_LINGER, (char*)&so, sizeof(so)); 726 ok &= !setsockopt( out[ 1 ], SOL_SOCKET, SO_LINGER, ( char* ) & so, sizeof( so ) );
784 } 727 }
785 else 728 else
786 { 729 {
787 int null_fd = open( "/dev/null", O_WRONLY ); 730 int null_fd = open( "/dev/null", O_WRONLY );
788 ok &= dup2( null_fd, STDOUT_FILENO ) != -1; 731 ok &= dup2( null_fd, STDOUT_FILENO ) != -1;
789 close( null_fd ); 732 close( null_fd );
790 } 733 }
791 if (communication & Stderr) 734 if ( communication & Stderr )
792 { 735 {
793 ok &= dup2(err[1], STDERR_FILENO) != -1; 736 ok &= dup2( err[ 1 ], STDERR_FILENO ) != -1;
794 ok &= !setsockopt(err[1], SOL_SOCKET, SO_LINGER, reinterpret_cast<char *>(&so), sizeof(so)); 737 ok &= !setsockopt( err[ 1 ], SOL_SOCKET, SO_LINGER, reinterpret_cast<char *>( &so ), sizeof( so ) );
795 } 738 }
796 else 739 else
797 { 740 {
798 int null_fd = open( "/dev/null", O_WRONLY ); 741 int null_fd = open( "/dev/null", O_WRONLY );
799 ok &= dup2( null_fd, STDERR_FILENO ) != -1; 742 ok &= dup2( null_fd, STDERR_FILENO ) != -1;
800 close( null_fd ); 743 close( null_fd );
801 } 744 }
802 return ok; 745 return ok;
803} 746}
804 747
805
806
807void OProcess::commClose() 748void OProcess::commClose()
808{ 749{
809 if (NoCommunication != communication) 750 if ( NoCommunication != communication )
810 { 751 {
811 bool b_in = (communication & Stdin); 752 bool b_in = ( communication & Stdin );
812 bool b_out = (communication & Stdout); 753 bool b_out = ( communication & Stdout );
813 bool b_err = (communication & Stderr); 754 bool b_err = ( communication & Stderr );
814 if (b_in) 755 if ( b_in )
815 delete innot; 756 delete innot;
816 757
817 if (b_out || b_err) 758 if ( b_out || b_err )
818 { 759 {
819 // If both channels are being read we need to make sure that one socket buffer 760 // If both channels are being read we need to make sure that one socket buffer
820 // doesn't fill up whilst we are waiting for data on the other (causing a deadlock). 761 // doesn't fill up whilst we are waiting for data on the other (causing a deadlock).
821 // Hence we need to use select. 762 // Hence we need to use select.
822 763
823 // Once one or other of the channels has reached EOF (or given an error) go back 764 // Once one or other of the channels has reached EOF (or given an error) go back
824 // to the usual mechanism. 765 // to the usual mechanism.
825 766
826 int fds_ready = 1; 767 int fds_ready = 1;
827 fd_set rfds; 768 fd_set rfds;
828 769
829 int max_fd = 0; 770 int max_fd = 0;
830 if (b_out) 771 if ( b_out )
831 { 772 {
832 fcntl(out[0], F_SETFL, O_NONBLOCK); 773 fcntl( out[ 0 ], F_SETFL, O_NONBLOCK );
833 if (out[0] > max_fd) 774 if ( out[ 0 ] > max_fd )
834 max_fd = out[0]; 775 max_fd = out[ 0 ];
835 delete outnot; 776 delete outnot;
836 outnot = 0; 777 outnot = 0;
837 } 778 }
838 if (b_err) 779 if ( b_err )
839 { 780 {
840 fcntl(err[0], F_SETFL, O_NONBLOCK); 781 fcntl( err[ 0 ], F_SETFL, O_NONBLOCK );
841 if (err[0] > max_fd) 782 if ( err[ 0 ] > max_fd )
842 max_fd = err[0]; 783 max_fd = err[ 0 ];
843 delete errnot; 784 delete errnot;
844 errnot = 0; 785 errnot = 0;
845 } 786 }
846 787
847 788
848 while (b_out || b_err) 789 while ( b_out || b_err )
849 { 790 {
850 // * If the process is still running we block until we 791 // * If the process is still running we block until we
851 // receive data. (p_timeout = 0, no timeout) 792 // receive data. (p_timeout = 0, no timeout)
852 // * If the process has already exited, we only check 793 // * If the process has already exited, we only check
853 // the available data, we don't wait for more. 794 // the available data, we don't wait for more.
854 // (p_timeout = &timeout, timeout immediately) 795 // (p_timeout = &timeout, timeout immediately)
855 struct timeval timeout; 796 struct timeval timeout;
856 timeout.tv_sec = 0; 797 timeout.tv_sec = 0;
857 timeout.tv_usec = 0; 798 timeout.tv_usec = 0;
858 struct timeval *p_timeout = runs ? 0 : &timeout; 799 struct timeval *p_timeout = runs ? 0 : &timeout;
859 800
860 FD_ZERO(&rfds); 801 FD_ZERO( &rfds );
861 if (b_out) 802 if ( b_out )
862 FD_SET(out[0], &rfds); 803 FD_SET( out[ 0 ], &rfds );
863 804
864 if (b_err) 805 if ( b_err )
865 FD_SET(err[0], &rfds); 806 FD_SET( err[ 0 ], &rfds );
866 807
867 fds_ready = select(max_fd+1, &rfds, 0, 0, p_timeout); 808 fds_ready = select( max_fd + 1, &rfds, 0, 0, p_timeout );
868 if (fds_ready <= 0) break; 809 if ( fds_ready <= 0 )
810 break;
869 811
870 if (b_out && FD_ISSET(out[0], &rfds)) 812 if ( b_out && FD_ISSET( out[ 0 ], &rfds ) )
871 { 813 {
872 int ret = 1; 814 int ret = 1;
873 while (ret > 0) ret = childOutput(out[0]); 815 while ( ret > 0 )
874 if ((ret == -1 && errno != EAGAIN) || ret == 0) 816 ret = childOutput( out[ 0 ] );
817 if ( ( ret == -1 && errno != EAGAIN ) || ret == 0 )
875 b_out = false; 818 b_out = false;
876 } 819 }
877 820
878 if (b_err && FD_ISSET(err[0], &rfds)) 821 if ( b_err && FD_ISSET( err[ 0 ], &rfds ) )
879 { 822 {
880 int ret = 1; 823 int ret = 1;
881 while (ret > 0) ret = childError(err[0]); 824 while ( ret > 0 )
882 if ((ret == -1 && errno != EAGAIN) || ret == 0) 825 ret = childError( err[ 0 ] );
826 if ( ( ret == -1 && errno != EAGAIN ) || ret == 0 )
883 b_err = false; 827 b_err = false;
884 } 828 }
885 } 829 }
886 } 830 }
887 831
888 if (b_in) 832 if ( b_in )
889 { 833 {
890 communication = (Communication) (communication & ~Stdin); 834 communication = ( Communication ) ( communication & ~Stdin );
891 close(in[1]); 835 close( in[ 1 ] );
892 } 836 }
893 if (b_out) 837 if ( b_out )
894 { 838 {
895 communication = (Communication) (communication & ~Stdout); 839 communication = ( Communication ) ( communication & ~Stdout );
896 close(out[0]); 840 close( out[ 0 ] );
897 } 841 }
898 if (b_err) 842 if ( b_err )
899 { 843 {
900 communication = (Communication) (communication & ~Stderr); 844 communication = ( Communication ) ( communication & ~Stderr );
901 close(err[0]); 845 close( err[ 0 ] );
902 } 846 }
903 } 847 }
904} 848}
905 849
906void OProcess::setUseShell(bool useShell, const char *shell) 850void OProcess::setUseShell( bool useShell, const char *shell )
907{ 851{
908 if (!d) 852 if ( !d )
909 d = new OProcessPrivate; 853 d = new OProcessPrivate;
910 d->useShell = useShell; 854 d->useShell = useShell;
911 d->shell = shell; 855 d->shell = shell;
912 if (d->shell.isEmpty()) 856 if ( d->shell.isEmpty() )
913 d->shell = searchShell(); 857 d->shell = searchShell();
914} 858}
915 859
916QString OProcess::quote(const QString &arg) 860QString OProcess::quote( const QString &arg )
917{ 861{
918 QString res = arg; 862 QString res = arg;
919 res.replace(QRegExp(QString::fromLatin1("\'")), 863 res.replace( QRegExp( QString::fromLatin1( "\'" ) ),
920 QString::fromLatin1("'\"'\"'")); 864 QString::fromLatin1( "'\"'\"'" ) );
921 res.prepend('\''); 865 res.prepend( '\'' );
922 res.append('\''); 866 res.append( '\'' );
923 return res; 867 return res;
924} 868}
925 869
926QCString OProcess::searchShell() 870QCString OProcess::searchShell()
927{ 871{
928 QCString tmpShell = QCString(getenv("SHELL")).stripWhiteSpace(); 872 QCString tmpShell = QCString( getenv( "SHELL" ) ).stripWhiteSpace();
929 if (!isExecutable(tmpShell)) 873 if ( !isExecutable( tmpShell ) )
930 { 874 {
931 tmpShell = "/bin/sh"; 875 tmpShell = "/bin/sh";
932 } 876 }
933 877
934 return tmpShell; 878 return tmpShell;
935} 879}
936 880
937bool OProcess::isExecutable(const QCString &filename) 881bool OProcess::isExecutable( const QCString &filename )
938{ 882{
939 struct stat fileinfo; 883 struct stat fileinfo;
940 884
941 if (filename.isEmpty()) return false; 885 if ( filename.isEmpty() )
886 return false;
942 887
943 // CC: we've got a valid filename, now let's see whether we can execute that file 888 // CC: we've got a valid filename, now let's see whether we can execute that file
944 889
945 if (-1 == stat(filename.data(), &fileinfo)) return false; 890 if ( -1 == stat( filename.data(), &fileinfo ) )
891 return false;
946 // CC: return false if the file does not exist 892 // CC: return false if the file does not exist
947 893
948 // CC: anyway, we cannot execute directories, block/character devices, fifos or sockets 894 // CC: anyway, we cannot execute directories, block/character devices, fifos or sockets
949 if ( (S_ISDIR(fileinfo.st_mode)) || 895 if ( ( S_ISDIR( fileinfo.st_mode ) ) ||
950 (S_ISCHR(fileinfo.st_mode)) || 896 ( S_ISCHR( fileinfo.st_mode ) ) ||
951 (S_ISBLK(fileinfo.st_mode)) || 897 ( S_ISBLK( fileinfo.st_mode ) ) ||
952#ifdef S_ISSOCK 898#ifdef S_ISSOCK
953 // CC: SYSVR4 systems don't have that macro 899 // CC: SYSVR4 systems don't have that macro
954 (S_ISSOCK(fileinfo.st_mode)) || 900 ( S_ISSOCK( fileinfo.st_mode ) ) ||
955#endif 901#endif
956 (S_ISFIFO(fileinfo.st_mode)) || 902 ( S_ISFIFO( fileinfo.st_mode ) ) ||
957 (S_ISDIR(fileinfo.st_mode)) ) 903 ( S_ISDIR( fileinfo.st_mode ) ) )
958 { 904 {
959 return false; 905 return false;
960 } 906 }
961 907
962 // CC: now check for permission to execute the file 908 // CC: now check for permission to execute the file
963 if (access(filename.data(), X_OK) != 0) return false; 909 if ( access( filename.data(), X_OK ) != 0 )
910 return false;
964 911
965 // CC: we've passed all the tests... 912 // CC: we've passed all the tests...
966 return true; 913 return true;
967} 914}
968 915
969
970
diff --git a/libopie2/opiecore/oprocess.h b/libopie2/opiecore/oprocess.h
index 8dd19b5..352485b 100644
--- a/libopie2/opiecore/oprocess.h
+++ b/libopie2/opiecore/oprocess.h
@@ -1,45 +1,49 @@
1/* This file is part of the KDE libraries 1/*
2 Copyright (C) 1997 Christian Czezakte (e9025461@student.tuwien.ac.at) 2                This file is part of the Opie Project
3 3             Copyright (C) 2003-2004 Holger Freyther <zecke@handhelds.org>
4 This library is free software; you can redistribute it and/or 4 Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 modify it under the terms of the GNU Library General Public 5 =. Based on KProcess (C) 1997 Christian Czezatke (e9025461@student.tuwien.ac.at)
6 License as published by the Free Software Foundation; either 6 .=l.
7 version 2 of the License, or (at your option) any later version. 7          .>+-=
8 8_;:,     .>    :=|. This program is free software; you can
9 This library is distributed in the hope that it will be useful, 9.> <`_,   >  .   <= redistribute it and/or modify it under
10 but WITHOUT ANY WARRANTY; without even the implied warranty of 10:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11.="- .-=="i,     .._ License as published by the Free Software
12 Library General Public License for more details. 12- .   .-<_>     .<> Foundation; either version 2 of the License,
13 13    ._= =}       : or (at your option) any later version.
14 You should have received a copy of the GNU Library General Public License 14   .%`+i>       _;_.
15 along with this library; see the file COPYING.LIB. If not, write to 15   .i_,=:_.      -<s. This program is distributed in the hope that
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 16    +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
17 Boston, MA 02111-1307, USA. 17   : ..    .:,     . . . without even the implied warranty of
18   =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
19 _.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
20..}^=.=       =       ; Library General Public License for more
21++=   -.     .`     .: details.
22:     =  ...= . :.=-
23-.   .:....=;==+<; You should have received a copy of the GNU
24 -_. . .   )=.  = Library General Public License along with
25   --        :-=` this library; see the file COPYING.LIB.
26 If not, write to the Free Software Foundation,
27 Inc., 59 Temple Place - Suite 330,
28 Boston, MA 02111-1307, USA.
18*/ 29*/
19//
20// KPROCESS -- A class for handling child processes in KDE without
21// having to take care of Un*x specific implementation details
22//
23// version 0.3.1, Jan 8th 1998
24//
25// (C) Christian Czezatke
26// e9025461@student.tuwien.ac.at
27// Ported by Holger Freyther to the Open Palmtop Integrated Environment
28//
29
30#ifndef __kprocess_h__
31#define __kprocess_h__
32 30
31#ifndef OPROCESS_H
32#define OPROCESS_H
33
34/* QT */
35#include <qcstring.h>
36#include <qobject.h>
37#include <qvaluelist.h>
38
39/* STD */
33#include <sys/types.h> // for pid_t 40#include <sys/types.h> // for pid_t
34#include <sys/wait.h> 41#include <sys/wait.h>
35#include <signal.h> 42#include <signal.h>
36#include <unistd.h> 43#include <unistd.h>
37#include <qvaluelist.h>
38#include <qcstring.h>
39#include <qobject.h>
40 44
41class QSocketNotifier; 45class QSocketNotifier;
42class OProcessPrivate; 46class OProcessPrivate;
43 47
44/** 48/**
45 * Child process invocation, monitoring and control. 49 * Child process invocation, monitoring and control.
@@ -138,13 +142,13 @@ class OProcessPrivate;
138 *@li void @ref wroteStdin(OProcess *proc); 142 *@li void @ref wroteStdin(OProcess *proc);
139 *@li -- Indicates that all data that has been sent to the child process 143 *@li -- Indicates that all data that has been sent to the child process
140 *by a prior call to @ref writeStdin() has actually been transmitted to the 144 *by a prior call to @ref writeStdin() has actually been transmitted to the
141 *client . 145 *client .
142 * 146 *
143 *@author Christian Czezakte e9025461@student.tuwien.ac.at 147 *@author Christian Czezakte e9025461@student.tuwien.ac.at
144 * 148 *@author Holger Freyther (Opie Port)
145 * 149 *
146 **/ 150 **/
147class OProcess : public QObject 151class OProcess : public QObject
148{ 152{
149 Q_OBJECT 153 Q_OBJECT
150 154
@@ -184,21 +188,21 @@ public:
184 */ 188 */
185 Block }; 189 Block };
186 190
187 /** 191 /**
188 * Constructor 192 * Constructor
189 */ 193 */
190 OProcess(QObject *parent = 0, const char *name = 0); 194 OProcess( QObject *parent = 0, const char *name = 0 );
191 /** 195 /**
192 * Constructor 196 * Constructor
193 */ 197 */
194 OProcess(const QString &arg0, QObject *parent = 0, const char *name = 0); 198 OProcess( const QString &arg0, QObject *parent = 0, const char *name = 0 );
195 /** 199 /**
196 * Constructor 200 * Constructor
197 */ 201 */
198 OProcess(const QStringList &args, QObject *parent = 0, const char *name = 0); 202 OProcess( const QStringList &args, QObject *parent = 0, const char *name = 0 );
199 203
200 /** 204 /**
201 *Destructor: 205 *Destructor:
202 * 206 *
203 * If the process is running when the destructor for this class 207 * If the process is running when the destructor for this class
204 * is called, the child process is killed with a SIGKILL, but 208 * is called, the child process is killed with a SIGKILL, but
@@ -217,13 +221,13 @@ public:
217 Returns false if the process is currently running (in that 221 Returns false if the process is currently running (in that
218 case the executable remains unchanged.) 222 case the executable remains unchanged.)
219 223
220 @see operator<< 224 @see operator<<
221 225
222 */ 226 */
223 bool setExecutable(const QString& proc); 227 bool setExecutable( const QString& proc );
224 228
225 229
226 /** 230 /**
227 * Sets the executable and the command line argument list for this process. 231 * Sets the executable and the command line argument list for this process.
228 * 232 *
229 * For example, doing an "ls -l /usr/local/bin" can be achieved by: 233 * For example, doing an "ls -l /usr/local/bin" can be achieved by:
@@ -231,27 +235,27 @@ public:
231 * OProcess p; 235 * OProcess p;
232 * ... 236 * ...
233 * p << "ls" << "-l" << "/usr/local/bin" 237 * p << "ls" << "-l" << "/usr/local/bin"
234 * </pre> 238 * </pre>
235 * 239 *
236 **/ 240 **/
237 OProcess &operator<<(const QString& arg); 241 OProcess &operator<<( const QString& arg );
238 /** 242 /**
239 * Similar to previous method, takes a char *, supposed to be in locale 8 bit already. 243 * Similar to previous method, takes a char *, supposed to be in locale 8 bit already.
240 */ 244 */
241 OProcess &operator<<(const char * arg); 245 OProcess &operator<<( const char * arg );
242 /** 246 /**
243 * Similar to previous method, takes a QCString, supposed to be in locale 8 bit already. 247 * Similar to previous method, takes a QCString, supposed to be in locale 8 bit already.
244 */ 248 */
245 OProcess &operator<<(const QCString & arg); 249 OProcess &operator<<( const QCString & arg );
246 250
247 /** 251 /**
248 * Sets the executable and the command line argument list for this process, 252 * Sets the executable and the command line argument list for this process,
249 * in a single method call, or add a list of arguments. 253 * in a single method call, or add a list of arguments.
250 **/ 254 **/
251 OProcess &operator<<(const QStringList& args); 255 OProcess &operator<<( const QStringList& args );
252 256
253 /** 257 /**
254 * Clear a command line argument list that has been set by using 258 * Clear a command line argument list that has been set by using
255 * the "operator<<". 259 * the "operator<<".
256 */ 260 */
257 void clearArguments(); 261 void clearArguments();
@@ -275,22 +279,22 @@ public:
275 * no communication takes place and the respective communication 279 * no communication takes place and the respective communication
276 * signals will never get emitted. 280 * signals will never get emitted.
277 * 281 *
278 * @return true on success, false on error 282 * @return true on success, false on error
279 * (see above for error conditions) 283 * (see above for error conditions)
280 **/ 284 **/
281 virtual bool start(RunMode runmode = NotifyOnExit, 285 virtual bool start( RunMode runmode = NotifyOnExit,
282 Communication comm = NoCommunication); 286 Communication comm = NoCommunication );
283 287
284 /** 288 /**
285 * Stop the process (by sending it a signal). 289 * Stop the process (by sending it a signal).
286 * 290 *
287 * @param signoThe signal to send. The default is SIGTERM. 291 * @param signoThe signal to send. The default is SIGTERM.
288 * @return @p true if the signal was delivered successfully. 292 * @return @p true if the signal was delivered successfully.
289 */ 293 */
290 virtual bool kill(int signo = SIGTERM); 294 virtual bool kill( int signo = SIGTERM );
291 295
292 /** 296 /**
293 @return @p true if the process is (still) considered to be running 297 @return @p true if the process is (still) considered to be running
294 */ 298 */
295 bool isRunning() const; 299 bool isRunning() const;
296 300
@@ -330,13 +334,13 @@ public:
330 * Please use 334 * Please use
331 * @ref OProcess::normalExit() to check whether the process has exited 335 * @ref OProcess::normalExit() to check whether the process has exited
332 * cleanly (i.e., @ref OProcess::normalExit() returns @p true) before calling 336 * cleanly (i.e., @ref OProcess::normalExit() returns @p true) before calling
333 * this function because if the process did not exit normally, 337 * this function because if the process did not exit normally,
334 * it does not have a valid exit status. 338 * it does not have a valid exit status.
335 */ 339 */
336 int exitStatus() const; 340 int exitStatus() const;
337 341
338 342
339 /** 343 /**
340 * Transmit data to the child process's stdin. 344 * Transmit data to the child process's stdin.
341 * 345 *
342 * OProcess::writeStdin may return false in the following cases: 346 * OProcess::writeStdin may return false in the following cases:
@@ -357,13 +361,13 @@ public:
357 * 361 *
358 * Please note that you must not free "buffer" or call @ref writeStdin() 362 * Please note that you must not free "buffer" or call @ref writeStdin()
359 * again until either a @ref wroteStdin() signal indicates that the 363 * again until either a @ref wroteStdin() signal indicates that the
360 * data has been sent or a @ref processHasExited() signal shows that 364 * data has been sent or a @ref processHasExited() signal shows that
361 * the child process is no longer alive... 365 * the child process is no longer alive...
362 **/ 366 **/
363 bool writeStdin(const char *buffer, int buflen); 367 bool writeStdin( const char *buffer, int buflen );
364 368
365 void flushStdin(); 369 void flushStdin();
366 370
367 /** 371 /**
368 * This causes the stdin file descriptor of the child process to be 372 * This causes the stdin file descriptor of the child process to be
369 * closed indicating an "EOF" to the child. 373 * closed indicating an "EOF" to the child.
@@ -392,81 +396,82 @@ public:
392 bool closeStderr(); 396 bool closeStderr();
393 397
394 /** 398 /**
395 * Lets you see what your arguments are for debugging. 399 * Lets you see what your arguments are for debugging.
396 */ 400 */
397 401
398 const QValueList<QCString> &args() { return arguments; } 402 const QValueList<QCString> &args()
403 {
404 return arguments;
405 }
399 406
400 /** 407 /**
401 * Controls whether the started process should drop any 408 * Controls whether the started process should drop any
402 * setuid/segid privileges or whether it should keep them 409 * setuid/segid privileges or whether it should keep them
403 * 410 *
404 * The default is @p false : drop privileges 411 * The default is @p false : drop privileges
405 */ 412 */
406 void setRunPrivileged(bool keepPrivileges); 413 void setRunPrivileged( bool keepPrivileges );
407 414
408 /** 415 /**
409 * Returns whether the started process will drop any 416 * Returns whether the started process will drop any
410 * setuid/segid privileges or whether it will keep them 417 * setuid/segid privileges or whether it will keep them
411 */ 418 */
412 bool runPrivileged() const; 419 bool runPrivileged() const;
413 420
414 /** 421 /**
415 * Modifies the environment of the process to be started. 422 * Modifies the environment of the process to be started.
416 * This function must be called before starting the process. 423 * This function must be called before starting the process.
417 */ 424 */
418 void setEnvironment(const QString &name, const QString &value); 425 void setEnvironment( const QString &name, const QString &value );
419 426
420 /** 427 /**
421 * Changes the current working directory (CWD) of the process 428 * Changes the current working directory (CWD) of the process
422 * to be started. 429 * to be started.
423 * This function must be called before starting the process. 430 * This function must be called before starting the process.
424 */ 431 */
425 void setWorkingDirectory(const QString &dir); 432 void setWorkingDirectory( const QString &dir );
426 433
427 /** 434 /**
428 * Specify whether to start the command via a shell or directly. 435 * Specify whether to start the command via a shell or directly.
429 * The default is to start the command directly. 436 * The default is to start the command directly.
430 * If @p useShell is true @p shell will be used as shell, or 437 * If @p useShell is true @p shell will be used as shell, or
431 * if shell is empty, the standard shell is used. 438 * if shell is empty, the standard shell is used.
432 * @p quote A flag indicating whether to quote the arguments. 439 * @p quote A flag indicating whether to quote the arguments.
433 * 440 *
434 * When using a shell, the caller should make sure that all filenames etc. 441 * When using a shell, the caller should make sure that all filenames etc.
435 * are properly quoted when passed as argument. 442 * are properly quoted when passed as argument.
436 * @see quote() 443 * @see quote()
437 */ 444 */
438 void setUseShell(bool useShell, const char *shell = 0); 445 void setUseShell( bool useShell, const char *shell = 0 );
439 446
440 /** 447 /**
441 * This function can be used to quote an argument string such that 448 * This function can be used to quote an argument string such that
442 * the shell processes it properly. This is e. g. necessary for 449 * the shell processes it properly. This is e. g. necessary for
443 * user-provided file names which may contain spaces or quotes. 450 * user-provided file names which may contain spaces or quotes.
444 * It also prevents expansion of wild cards and environment variables. 451 * It also prevents expansion of wild cards and environment variables.
445 */ 452 */
446 static QString quote(const QString &arg); 453 static QString quote( const QString &arg );
447 454
448 /** 455 /**
449 * Detaches OProcess from child process. All communication is closed. 456 * Detaches OProcess from child process. All communication is closed.
450 * No exit notification is emitted any more for the child process. 457 * No exit notification is emitted any more for the child process.
451 * Deleting the OProcess will no longer kill the child process. 458 * Deleting the OProcess will no longer kill the child process.
452 * Note that the current process remains the parent process of the 459 * Note that the current process remains the parent process of the
453 * child process. 460 * child process.
454 */ 461 */
455 void detach(); 462 void detach();
456 463
457
458
459signals: 464signals:
460 465
461 /** 466 /**
462 * Emitted after the process has terminated when 467 * Emitted after the process has terminated when
463 * the process was run in the @p NotifyOnExit (==default option to 468 * the process was run in the @p NotifyOnExit (==default option to
464 * @ref start()) or the @ref Block mode. 469 * @ref start()) or the @ref Block mode.
465 **/ 470 **/
466 void processExited(OProcess *proc); 471 void processExited( OProcess *proc );
467 472
468 473
469 /** 474 /**
470 * Emitted, when output from the child process has 475 * Emitted, when output from the child process has
471 * been received on stdout. 476 * been received on stdout.
472 * 477 *
@@ -477,13 +482,13 @@ signals:
477 * @param buffer The data received. 482 * @param buffer The data received.
478 * @param buflen The number of bytes that are available. 483 * @param buflen The number of bytes that are available.
479 * 484 *
480 * You should copy the information contained in @p buffer to your private 485 * You should copy the information contained in @p buffer to your private
481 * data structures before returning from this slot. 486 * data structures before returning from this slot.
482 **/ 487 **/
483 void receivedStdout(OProcess *proc, char *buffer, int buflen); 488 void receivedStdout( OProcess *proc, char *buffer, int buflen );
484 489
485 /** 490 /**
486 * Emitted when output from the child process has 491 * Emitted when output from the child process has
487 * been received on stdout. 492 * been received on stdout.
488 * 493 *
489 * To actually get these signals, the respective communications link 494 * To actually get these signals, the respective communications link
@@ -494,13 +499,13 @@ signals:
494 * to begin processing data from the child process's stdout. This is 499 * to begin processing data from the child process's stdout. This is
495 * to ensure that this signal is not emitted when no one is connected 500 * to ensure that this signal is not emitted when no one is connected
496 * to it, otherwise this signal will not be emitted. 501 * to it, otherwise this signal will not be emitted.
497 * 502 *
498 * The data still has to be read from file descriptor @p fd. 503 * The data still has to be read from file descriptor @p fd.
499 **/ 504 **/
500 void receivedStdout(int fd, int &len); 505 void receivedStdout( int fd, int &len );
501 506
502 507
503 /** 508 /**
504 * Emitted, when output from the child process has 509 * Emitted, when output from the child process has
505 * been received on stderr. 510 * been received on stderr.
506 * To actually get 511 * To actually get
@@ -510,45 +515,44 @@ signals:
510 * @param buffer The data received. 515 * @param buffer The data received.
511 * @param buflen The number of bytes that are available. 516 * @param buflen The number of bytes that are available.
512 * 517 *
513 * You should copy the information contained in @p buffer to your private 518 * You should copy the information contained in @p buffer to your private
514 * data structures before returning from this slot. 519 * data structures before returning from this slot.
515 */ 520 */
516 void receivedStderr(OProcess *proc, char *buffer, int buflen); 521 void receivedStderr( OProcess *proc, char *buffer, int buflen );
517 522
518 /** 523 /**
519 * Emitted after all the data that has been 524 * Emitted after all the data that has been
520 * specified by a prior call to @ref writeStdin() has actually been 525 * specified by a prior call to @ref writeStdin() has actually been
521 * written to the child process. 526 * written to the child process.
522 **/ 527 **/
523 void wroteStdin(OProcess *proc); 528 void wroteStdin( OProcess *proc );
524
525 529
526protected slots: 530protected slots:
527 531
528 /** 532 /**
529 * This slot gets activated when data from the child's stdout arrives. 533 * This slot gets activated when data from the child's stdout arrives.
530 * It usually calls "childOutput" 534 * It usually calls "childOutput"
531 */ 535 */
532 void slotChildOutput(int fdno); 536 void slotChildOutput( int fdno );
533 537
534 /** 538 /**
535 * This slot gets activated when data from the child's stderr arrives. 539 * This slot gets activated when data from the child's stderr arrives.
536 * It usually calls "childError" 540 * It usually calls "childError"
537 */ 541 */
538 void slotChildError(int fdno); 542 void slotChildError( int fdno );
539 /* 543 /*
540 Slot functions for capturing stdout and stderr of the child 544 Slot functions for capturing stdout and stderr of the child
541 */ 545 */
542 546
543 /** 547 /**
544 * Called when another bulk of data can be sent to the child's 548 * Called when another bulk of data can be sent to the child's
545 * stdin. If there is no more data to be sent to stdin currently 549 * stdin. If there is no more data to be sent to stdin currently
546 * available, this function must disable the QSocketNotifier "innot". 550 * available, this function must disable the QSocketNotifier "innot".
547 */ 551 */
548 void slotSendData(int dummy); 552 void slotSendData( int dummy );
549 553
550protected: 554protected:
551 555
552 /** 556 /**
553 * Sets up the environment according to the data passed via 557 * Sets up the environment according to the data passed via
554 * setEnvironment(...) 558 * setEnvironment(...)
@@ -621,13 +625,13 @@ protected:
621 * was successful. 625 * was successful.
622 * 626 *
623 * The default implementation is to create UNIX STREAM sockets for the communication, 627 * The default implementation is to create UNIX STREAM sockets for the communication,
624 * but you could overload this function and establish a TCP/IP communication for 628 * but you could overload this function and establish a TCP/IP communication for
625 * network communication, for example. 629 * network communication, for example.
626 */ 630 */
627 virtual int setupCommunication(Communication comm); 631 virtual int setupCommunication( Communication comm );
628 632
629 /** 633 /**
630 * Called right after a (successful) fork on the parent side. This function 634 * Called right after a (successful) fork on the parent side. This function
631 * will usually do some communications cleanup, like closing the reading end 635 * will usually do some communications cleanup, like closing the reading end
632 * of the "stdin" communication channel. 636 * of the "stdin" communication channel.
633 * 637 *
@@ -651,27 +655,27 @@ protected:
651 /** 655 /**
652 * Immediately called after a process has exited. This function normally 656 * Immediately called after a process has exited. This function normally
653 * calls commClose to close all open communication channels to this 657 * calls commClose to close all open communication channels to this
654 * process and emits the "processExited" signal (if the process was 658 * process and emits the "processExited" signal (if the process was
655 * not running in the "DontCare" mode). 659 * not running in the "DontCare" mode).
656 */ 660 */
657 virtual void processHasExited(int state); 661 virtual void processHasExited( int state );
658 662
659 /** 663 /**
660 * Should clean up the communication links to the child after it has 664 * Should clean up the communication links to the child after it has
661 * exited. Should be called from "processHasExited". 665 * exited. Should be called from "processHasExited".
662 */ 666 */
663 virtual void commClose(); 667 virtual void commClose();
664 668
665 669
666 /** 670 /**
667 * the socket descriptors for stdin/stdout/stderr. 671 * the socket descriptors for stdin/stdout/stderr.
668 */ 672 */
669 int out[2]; 673 int out[ 2 ];
670 int in[2]; 674 int in[ 2 ];
671 int err[2]; 675 int err[ 2 ];
672 676
673 /** 677 /**
674 * The socket notifiers for the above socket descriptors. 678 * The socket notifiers for the above socket descriptors.
675 */ 679 */
676 QSocketNotifier *innot; 680 QSocketNotifier *innot;
677 QSocketNotifier *outnot; 681 QSocketNotifier *outnot;
@@ -685,20 +689,20 @@ protected:
685 689
686 /** 690 /**
687 * Called by "slotChildOutput" this function copies data arriving from the 691 * Called by "slotChildOutput" this function copies data arriving from the
688 * child process's stdout to the respective buffer and emits the signal 692 * child process's stdout to the respective buffer and emits the signal
689 * "@ref receivedStderr". 693 * "@ref receivedStderr".
690 */ 694 */
691 int childOutput(int fdno); 695 int childOutput( int fdno );
692 696
693 /** 697 /**
694 * Called by "slotChildOutput" this function copies data arriving from the 698 * Called by "slotChildOutput" this function copies data arriving from the
695 * child process's stdout to the respective buffer and emits the signal 699 * child process's stdout to the respective buffer and emits the signal
696 * "@ref receivedStderr" 700 * "@ref receivedStderr"
697 */ 701 */
698 int childError(int fdno); 702 int childError( int fdno );
699 703
700 // information about the data that has to be sent to the child: 704 // information about the data that has to be sent to the child:
701 705
702 const char *input_data; // the buffer holding the data 706 const char *input_data; // the buffer holding the data
703 int input_sent; // # of bytes already transmitted 707 int input_sent; // # of bytes already transmitted
704 int input_total; // total length of input_data 708 int input_total; // total length of input_data
@@ -706,13 +710,12 @@ protected:
706 /** 710 /**
707 * @ref OProcessController is a friend of OProcess because it has to have 711 * @ref OProcessController is a friend of OProcess because it has to have
708 * access to various data members. 712 * access to various data members.
709 */ 713 */
710 friend class OProcessController; 714 friend class OProcessController;
711 715
712
713private: 716private:
714 /** 717 /**
715 * Searches for a valid shell. 718 * Searches for a valid shell.
716 * Here is the algorithm used for finding an executable shell: 719 * Here is the algorithm used for finding an executable shell:
717 * 720 *
718 * @li Try the executable pointed to by the "SHELL" environment 721 * @li Try the executable pointed to by the "SHELL" environment
@@ -726,22 +729,19 @@ private:
726 QCString searchShell(); 729 QCString searchShell();
727 730
728 /** 731 /**
729 * Used by @ref searchShell in order to find out whether the shell found 732 * Used by @ref searchShell in order to find out whether the shell found
730 * is actually executable at all. 733 * is actually executable at all.
731 */ 734 */
732 bool isExecutable(const QCString &filename); 735 bool isExecutable( const QCString &filename );
733 736
734 // Disallow assignment and copy-construction 737 // Disallow assignment and copy-construction
735 OProcess( const OProcess& ); 738 OProcess( const OProcess& );
736 OProcess& operator= ( const OProcess& ); 739 OProcess& operator= ( const OProcess& );
737 740
738private: 741private:
739 void init ( ); 742 void init ( );
740
741 OProcessPrivate *d; 743 OProcessPrivate *d;
742}; 744};
743 745
744
745
746#endif 746#endif
747 747