author | mickeyl <mickeyl> | 2004-01-13 19:51:42 (UTC) |
---|---|---|
committer | mickeyl <mickeyl> | 2004-01-13 19:51:42 (UTC) |
commit | e117e8427cd8bcd0ab1a74abdc5cd4ab12654194 (patch) (unidiff) | |
tree | f013f4f92cceefd20fb519f7e9a4d23f00fadac5 | |
parent | 81b48fa5be4806e3afa64a0d1fa254fbdf9b7315 (diff) | |
download | opie-e117e8427cd8bcd0ab1a74abdc5cd4ab12654194.zip opie-e117e8427cd8bcd0ab1a74abdc5cd4ab12654194.tar.gz opie-e117e8427cd8bcd0ab1a74abdc5cd4ab12654194.tar.bz2 |
- add the static method int OProcess::processPID(const QString&)
- add an example program for dealing with OProcess. This should be enhanced...
-rw-r--r-- | libopie2/examples/opiecore/opiecore.pro | 2 | ||||
-rw-r--r-- | libopie2/examples/opiecore/oprocessdemo/.cvsignore | 6 | ||||
-rw-r--r-- | libopie2/examples/opiecore/oprocessdemo/oprocessdemo.cpp | 11 | ||||
-rw-r--r-- | libopie2/examples/opiecore/oprocessdemo/oprocessdemo.pro | 12 | ||||
-rw-r--r-- | libopie2/opiecore/oprocess.cpp | 30 | ||||
-rw-r--r-- | libopie2/opiecore/oprocess.h | 5 |
6 files changed, 65 insertions, 1 deletions
diff --git a/libopie2/examples/opiecore/opiecore.pro b/libopie2/examples/opiecore/opiecore.pro index 8f3aedc..ec14be0 100644 --- a/libopie2/examples/opiecore/opiecore.pro +++ b/libopie2/examples/opiecore/opiecore.pro | |||
@@ -1,3 +1,3 @@ | |||
1 | TEMPLATE = subdirs | 1 | TEMPLATE = subdirs |
2 | unix:SUBDIRS = odebugdemo oconfigdemo oglobalsettingsdemo | 2 | unix:SUBDIRS = odebugdemo oconfigdemo oglobalsettingsdemo oprocessdemo |
3 | 3 | ||
diff --git a/libopie2/examples/opiecore/oprocessdemo/.cvsignore b/libopie2/examples/opiecore/oprocessdemo/.cvsignore new file mode 100644 index 0000000..8f7300c --- a/dev/null +++ b/libopie2/examples/opiecore/oprocessdemo/.cvsignore | |||
@@ -0,0 +1,6 @@ | |||
1 | Makefile* | ||
2 | moc* | ||
3 | *moc | ||
4 | *.o | ||
5 | ~* | ||
6 | |||
diff --git a/libopie2/examples/opiecore/oprocessdemo/oprocessdemo.cpp b/libopie2/examples/opiecore/oprocessdemo/oprocessdemo.cpp new file mode 100644 index 0000000..0abf53e --- a/dev/null +++ b/libopie2/examples/opiecore/oprocessdemo/oprocessdemo.cpp | |||
@@ -0,0 +1,11 @@ | |||
1 | #include <opie2/oprocess.h> | ||
2 | #include <iostream.h> | ||
3 | |||
4 | int main( int argc, char** argv ) | ||
5 | { | ||
6 | printf( "my own PID seems to be '%d'\n", OProcess::processPID( "oprocessdemo" ) ); | ||
7 | printf( "the PID of process 'Mickey' seems to be '%d'\n\n", OProcess::processPID( "Mickey" ) ); | ||
8 | |||
9 | return 0; | ||
10 | } | ||
11 | |||
diff --git a/libopie2/examples/opiecore/oprocessdemo/oprocessdemo.pro b/libopie2/examples/opiecore/oprocessdemo/oprocessdemo.pro new file mode 100644 index 0000000..72dac7f --- a/dev/null +++ b/libopie2/examples/opiecore/oprocessdemo/oprocessdemo.pro | |||
@@ -0,0 +1,12 @@ | |||
1 | TEMPLATE = app | ||
2 | CONFIG = qt warn_on debug | ||
3 | HEADERS = | ||
4 | SOURCES = oprocessdemo.cpp | ||
5 | INCLUDEPATH += $(OPIEDIR)/include | ||
6 | DEPENDPATH += $(OPIEDIR)/include | ||
7 | LIBS += -lopiecore2 | ||
8 | TARGET = oprocessdemo | ||
9 | |||
10 | include ( $(OPIEDIR)/include.pro ) | ||
11 | |||
12 | |||
diff --git a/libopie2/opiecore/oprocess.cpp b/libopie2/opiecore/oprocess.cpp index f1a5f3b..5cfcf32 100644 --- a/libopie2/opiecore/oprocess.cpp +++ b/libopie2/opiecore/oprocess.cpp | |||
@@ -1,138 +1,140 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of the Opie Project | 2 | This file is part of the Opie Project |
3 | Copyright (C) 2002-2004 Holger Freyther <zecke@handhelds.org> | 3 | Copyright (C) 2002-2004 Holger Freyther <zecke@handhelds.org> |
4 | and The Opie Team <opie-devel@handhelds.org> | 4 | and 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 | #include "oprocctrl.h" | 31 | #include "oprocctrl.h" |
32 | 32 | ||
33 | /* OPIE */ | 33 | /* OPIE */ |
34 | #include <opie2/oprocess.h> | 34 | #include <opie2/oprocess.h> |
35 | 35 | ||
36 | /* QT */ | 36 | /* QT */ |
37 | 37 | ||
38 | #include <qapplication.h> | 38 | #include <qapplication.h> |
39 | #include <qdir.h> | ||
39 | #include <qfile.h> | 40 | #include <qfile.h> |
40 | #include <qmap.h> | 41 | #include <qmap.h> |
41 | #include <qregexp.h> | 42 | #include <qregexp.h> |
42 | #include <qsocketnotifier.h> | 43 | #include <qsocketnotifier.h> |
44 | #include <qtextstream.h> | ||
43 | 45 | ||
44 | /* STD */ | 46 | /* STD */ |
45 | #include <errno.h> | 47 | #include <errno.h> |
46 | #include <fcntl.h> | 48 | #include <fcntl.h> |
47 | #include <pwd.h> | 49 | #include <pwd.h> |
48 | #include <stdlib.h> | 50 | #include <stdlib.h> |
49 | #include <signal.h> | 51 | #include <signal.h> |
50 | #include <stdio.h> | 52 | #include <stdio.h> |
51 | #include <string.h> | 53 | #include <string.h> |
52 | #include <sys/time.h> | 54 | #include <sys/time.h> |
53 | #include <sys/types.h> | 55 | #include <sys/types.h> |
54 | #include <sys/stat.h> | 56 | #include <sys/stat.h> |
55 | #include <sys/socket.h> | 57 | #include <sys/socket.h> |
56 | #include <unistd.h> | 58 | #include <unistd.h> |
57 | #ifdef HAVE_SYS_SELECT_H | 59 | #ifdef HAVE_SYS_SELECT_H |
58 | #include <sys/select.h> | 60 | #include <sys/select.h> |
59 | #endif | 61 | #endif |
60 | #ifdef HAVE_INITGROUPS | 62 | #ifdef HAVE_INITGROUPS |
61 | #include <grp.h> | 63 | #include <grp.h> |
62 | #endif | 64 | #endif |
63 | 65 | ||
64 | class OProcessPrivate | 66 | class OProcessPrivate |
65 | { | 67 | { |
66 | public: | 68 | public: |
67 | OProcessPrivate() : useShell( false ) | 69 | OProcessPrivate() : useShell( false ) |
68 | { } | 70 | { } |
69 | 71 | ||
70 | bool useShell; | 72 | bool useShell; |
71 | QMap<QString, QString> env; | 73 | QMap<QString, QString> env; |
72 | QString wd; | 74 | QString wd; |
73 | QCString shell; | 75 | QCString shell; |
74 | }; | 76 | }; |
75 | 77 | ||
76 | 78 | ||
77 | OProcess::OProcess( QObject *parent, const char *name ) | 79 | OProcess::OProcess( QObject *parent, const char *name ) |
78 | : QObject( parent, name ) | 80 | : QObject( parent, name ) |
79 | { | 81 | { |
80 | init ( ); | 82 | init ( ); |
81 | } | 83 | } |
82 | 84 | ||
83 | OProcess::OProcess( const QString &arg0, QObject *parent, const char *name ) | 85 | OProcess::OProcess( const QString &arg0, QObject *parent, const char *name ) |
84 | : QObject( parent, name ) | 86 | : QObject( parent, name ) |
85 | { | 87 | { |
86 | init ( ); | 88 | init ( ); |
87 | *this << arg0; | 89 | *this << arg0; |
88 | } | 90 | } |
89 | 91 | ||
90 | OProcess::OProcess( const QStringList &args, QObject *parent, const char *name ) | 92 | OProcess::OProcess( const QStringList &args, QObject *parent, const char *name ) |
91 | : QObject( parent, name ) | 93 | : QObject( parent, name ) |
92 | { | 94 | { |
93 | init ( ); | 95 | init ( ); |
94 | *this << args; | 96 | *this << args; |
95 | } | 97 | } |
96 | 98 | ||
97 | void OProcess::init ( ) | 99 | void OProcess::init ( ) |
98 | { | 100 | { |
99 | run_mode = NotifyOnExit; | 101 | run_mode = NotifyOnExit; |
100 | runs = false; | 102 | runs = false; |
101 | pid_ = 0; | 103 | pid_ = 0; |
102 | status = 0; | 104 | status = 0; |
103 | keepPrivs = false; | 105 | keepPrivs = false; |
104 | innot = 0; | 106 | innot = 0; |
105 | outnot = 0; | 107 | outnot = 0; |
106 | errnot = 0; | 108 | errnot = 0; |
107 | communication = NoCommunication; | 109 | communication = NoCommunication; |
108 | input_data = 0; | 110 | input_data = 0; |
109 | input_sent = 0; | 111 | input_sent = 0; |
110 | input_total = 0; | 112 | input_total = 0; |
111 | d = 0; | 113 | d = 0; |
112 | 114 | ||
113 | if ( 0 == OProcessController::theOProcessController ) | 115 | if ( 0 == OProcessController::theOProcessController ) |
114 | { | 116 | { |
115 | ( void ) new OProcessController(); | 117 | ( void ) new OProcessController(); |
116 | CHECK_PTR( OProcessController::theOProcessController ); | 118 | CHECK_PTR( OProcessController::theOProcessController ); |
117 | } | 119 | } |
118 | 120 | ||
119 | OProcessController::theOProcessController->addOProcess( this ); | 121 | OProcessController::theOProcessController->addOProcess( this ); |
120 | out[ 0 ] = out[ 1 ] = -1; | 122 | out[ 0 ] = out[ 1 ] = -1; |
121 | in[ 0 ] = in[ 1 ] = -1; | 123 | in[ 0 ] = in[ 1 ] = -1; |
122 | err[ 0 ] = err[ 1 ] = -1; | 124 | err[ 0 ] = err[ 1 ] = -1; |
123 | } | 125 | } |
124 | 126 | ||
125 | void OProcess::setEnvironment( const QString &name, const QString &value ) | 127 | void OProcess::setEnvironment( const QString &name, const QString &value ) |
126 | { | 128 | { |
127 | if ( !d ) | 129 | if ( !d ) |
128 | d = new OProcessPrivate; | 130 | d = new OProcessPrivate; |
129 | d->env.insert( name, value ); | 131 | d->env.insert( name, value ); |
130 | } | 132 | } |
131 | 133 | ||
132 | void OProcess::setWorkingDirectory( const QString &dir ) | 134 | void OProcess::setWorkingDirectory( const QString &dir ) |
133 | { | 135 | { |
134 | if ( !d ) | 136 | if ( !d ) |
135 | d = new OProcessPrivate; | 137 | d = new OProcessPrivate; |
136 | d->wd = dir; | 138 | d->wd = dir; |
137 | } | 139 | } |
138 | 140 | ||
@@ -820,96 +822,124 @@ void OProcess::commClose() | |||
820 | 822 | ||
821 | if ( b_err && FD_ISSET( err[ 0 ], &rfds ) ) | 823 | if ( b_err && FD_ISSET( err[ 0 ], &rfds ) ) |
822 | { | 824 | { |
823 | int ret = 1; | 825 | int ret = 1; |
824 | while ( ret > 0 ) | 826 | while ( ret > 0 ) |
825 | ret = childError( err[ 0 ] ); | 827 | ret = childError( err[ 0 ] ); |
826 | if ( ( ret == -1 && errno != EAGAIN ) || ret == 0 ) | 828 | if ( ( ret == -1 && errno != EAGAIN ) || ret == 0 ) |
827 | b_err = false; | 829 | b_err = false; |
828 | } | 830 | } |
829 | } | 831 | } |
830 | } | 832 | } |
831 | 833 | ||
832 | if ( b_in ) | 834 | if ( b_in ) |
833 | { | 835 | { |
834 | communication = ( Communication ) ( communication & ~Stdin ); | 836 | communication = ( Communication ) ( communication & ~Stdin ); |
835 | close( in[ 1 ] ); | 837 | close( in[ 1 ] ); |
836 | } | 838 | } |
837 | if ( b_out ) | 839 | if ( b_out ) |
838 | { | 840 | { |
839 | communication = ( Communication ) ( communication & ~Stdout ); | 841 | communication = ( Communication ) ( communication & ~Stdout ); |
840 | close( out[ 0 ] ); | 842 | close( out[ 0 ] ); |
841 | } | 843 | } |
842 | if ( b_err ) | 844 | if ( b_err ) |
843 | { | 845 | { |
844 | communication = ( Communication ) ( communication & ~Stderr ); | 846 | communication = ( Communication ) ( communication & ~Stderr ); |
845 | close( err[ 0 ] ); | 847 | close( err[ 0 ] ); |
846 | } | 848 | } |
847 | } | 849 | } |
848 | } | 850 | } |
849 | 851 | ||
850 | void OProcess::setUseShell( bool useShell, const char *shell ) | 852 | void OProcess::setUseShell( bool useShell, const char *shell ) |
851 | { | 853 | { |
852 | if ( !d ) | 854 | if ( !d ) |
853 | d = new OProcessPrivate; | 855 | d = new OProcessPrivate; |
854 | d->useShell = useShell; | 856 | d->useShell = useShell; |
855 | d->shell = shell; | 857 | d->shell = shell; |
856 | if ( d->shell.isEmpty() ) | 858 | if ( d->shell.isEmpty() ) |
857 | d->shell = searchShell(); | 859 | d->shell = searchShell(); |
858 | } | 860 | } |
859 | 861 | ||
860 | QString OProcess::quote( const QString &arg ) | 862 | QString OProcess::quote( const QString &arg ) |
861 | { | 863 | { |
862 | QString res = arg; | 864 | QString res = arg; |
863 | res.replace( QRegExp( QString::fromLatin1( "\'" ) ), | 865 | res.replace( QRegExp( QString::fromLatin1( "\'" ) ), |
864 | QString::fromLatin1( "'\"'\"'" ) ); | 866 | QString::fromLatin1( "'\"'\"'" ) ); |
865 | res.prepend( '\'' ); | 867 | res.prepend( '\'' ); |
866 | res.append( '\'' ); | 868 | res.append( '\'' ); |
867 | return res; | 869 | return res; |
868 | } | 870 | } |
869 | 871 | ||
870 | QCString OProcess::searchShell() | 872 | QCString OProcess::searchShell() |
871 | { | 873 | { |
872 | QCString tmpShell = QCString( getenv( "SHELL" ) ).stripWhiteSpace(); | 874 | QCString tmpShell = QCString( getenv( "SHELL" ) ).stripWhiteSpace(); |
873 | if ( !isExecutable( tmpShell ) ) | 875 | if ( !isExecutable( tmpShell ) ) |
874 | { | 876 | { |
875 | tmpShell = "/bin/sh"; | 877 | tmpShell = "/bin/sh"; |
876 | } | 878 | } |
877 | 879 | ||
878 | return tmpShell; | 880 | return tmpShell; |
879 | } | 881 | } |
880 | 882 | ||
881 | bool OProcess::isExecutable( const QCString &filename ) | 883 | bool OProcess::isExecutable( const QCString &filename ) |
882 | { | 884 | { |
883 | struct stat fileinfo; | 885 | struct stat fileinfo; |
884 | 886 | ||
885 | if ( filename.isEmpty() ) | 887 | if ( filename.isEmpty() ) |
886 | return false; | 888 | return false; |
887 | 889 | ||
888 | // CC: we've got a valid filename, now let's see whether we can execute that file | 890 | // CC: we've got a valid filename, now let's see whether we can execute that file |
889 | 891 | ||
890 | if ( -1 == stat( filename.data(), &fileinfo ) ) | 892 | if ( -1 == stat( filename.data(), &fileinfo ) ) |
891 | return false; | 893 | return false; |
892 | // CC: return false if the file does not exist | 894 | // CC: return false if the file does not exist |
893 | 895 | ||
894 | // CC: anyway, we cannot execute directories, block/character devices, fifos or sockets | 896 | // CC: anyway, we cannot execute directories, block/character devices, fifos or sockets |
895 | if ( ( S_ISDIR( fileinfo.st_mode ) ) || | 897 | if ( ( S_ISDIR( fileinfo.st_mode ) ) || |
896 | ( S_ISCHR( fileinfo.st_mode ) ) || | 898 | ( S_ISCHR( fileinfo.st_mode ) ) || |
897 | ( S_ISBLK( fileinfo.st_mode ) ) || | 899 | ( S_ISBLK( fileinfo.st_mode ) ) || |
898 | #ifdef S_ISSOCK | 900 | #ifdef S_ISSOCK |
899 | // CC: SYSVR4 systems don't have that macro | 901 | // CC: SYSVR4 systems don't have that macro |
900 | ( S_ISSOCK( fileinfo.st_mode ) ) || | 902 | ( S_ISSOCK( fileinfo.st_mode ) ) || |
901 | #endif | 903 | #endif |
902 | ( S_ISFIFO( fileinfo.st_mode ) ) || | 904 | ( S_ISFIFO( fileinfo.st_mode ) ) || |
903 | ( S_ISDIR( fileinfo.st_mode ) ) ) | 905 | ( S_ISDIR( fileinfo.st_mode ) ) ) |
904 | { | 906 | { |
905 | return false; | 907 | return false; |
906 | } | 908 | } |
907 | 909 | ||
908 | // CC: now check for permission to execute the file | 910 | // CC: now check for permission to execute the file |
909 | if ( access( filename.data(), X_OK ) != 0 ) | 911 | if ( access( filename.data(), X_OK ) != 0 ) |
910 | return false; | 912 | return false; |
911 | 913 | ||
912 | // CC: we've passed all the tests... | 914 | // CC: we've passed all the tests... |
913 | return true; | 915 | return true; |
914 | } | 916 | } |
915 | 917 | ||
918 | int OProcess::processPID( const QString& process ) | ||
919 | { | ||
920 | QString line; | ||
921 | QDir d = QDir( "/proc" ); | ||
922 | QStringList dirs = d.entryList( QDir::Dirs ); | ||
923 | QStringList::Iterator it; | ||
924 | for ( it = dirs.begin(); it != dirs.end(); ++it ) | ||
925 | { | ||
926 | //qDebug( "next entry: %s", (const char*) *it ); | ||
927 | QFile file( "/proc/"+*it+"/cmdline" ); | ||
928 | file.open( IO_ReadOnly ); | ||
929 | if ( !file.isOpen() ) continue; | ||
930 | QTextStream t( &file ); | ||
931 | line = t.readLine(); | ||
932 | //qDebug( "cmdline = %s", (const char*) line ); | ||
933 | if ( line.contains( process ) ) break; //FIXME: That may find also other process, if the name is not long enough ;) | ||
934 | } | ||
935 | if ( line.contains( process ) ) | ||
936 | { | ||
937 | //qDebug( "found process id #%d", (*it).toInt() ); | ||
938 | return (*it).toInt(); | ||
939 | } | ||
940 | else | ||
941 | { | ||
942 | //qDebug( "process '%s' not found", (const char*) process ); | ||
943 | return -1; | ||
944 | } | ||
945 | } | ||
diff --git a/libopie2/opiecore/oprocess.h b/libopie2/opiecore/oprocess.h index 352485b..1a2472d 100644 --- a/libopie2/opiecore/oprocess.h +++ b/libopie2/opiecore/oprocess.h | |||
@@ -368,192 +368,197 @@ public: | |||
368 | 368 | ||
369 | void flushStdin(); | 369 | void flushStdin(); |
370 | 370 | ||
371 | /** | 371 | /** |
372 | * 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 |
373 | * closed indicating an "EOF" to the child. | 373 | * closed indicating an "EOF" to the child. |
374 | * | 374 | * |
375 | * @return @p false if no communication to the process's stdin | 375 | * @return @p false if no communication to the process's stdin |
376 | * had been specified in the call to @ref start(). | 376 | * had been specified in the call to @ref start(). |
377 | */ | 377 | */ |
378 | bool closeStdin(); | 378 | bool closeStdin(); |
379 | 379 | ||
380 | /** | 380 | /** |
381 | * This causes the stdout file descriptor of the child process to be | 381 | * This causes the stdout file descriptor of the child process to be |
382 | * closed. | 382 | * closed. |
383 | * | 383 | * |
384 | * @return @p false if no communication to the process's stdout | 384 | * @return @p false if no communication to the process's stdout |
385 | * had been specified in the call to @ref start(). | 385 | * had been specified in the call to @ref start(). |
386 | */ | 386 | */ |
387 | bool closeStdout(); | 387 | bool closeStdout(); |
388 | 388 | ||
389 | /** | 389 | /** |
390 | * This causes the stderr file descriptor of the child process to be | 390 | * This causes the stderr file descriptor of the child process to be |
391 | * closed. | 391 | * closed. |
392 | * | 392 | * |
393 | * @return @p false if no communication to the process's stderr | 393 | * @return @p false if no communication to the process's stderr |
394 | * had been specified in the call to @ref start(). | 394 | * had been specified in the call to @ref start(). |
395 | */ | 395 | */ |
396 | bool closeStderr(); | 396 | bool closeStderr(); |
397 | 397 | ||
398 | /** | 398 | /** |
399 | * Lets you see what your arguments are for debugging. | 399 | * Lets you see what your arguments are for debugging. |
400 | */ | 400 | */ |
401 | 401 | ||
402 | const QValueList<QCString> &args() | 402 | const QValueList<QCString> &args() |
403 | { | 403 | { |
404 | return arguments; | 404 | return arguments; |
405 | } | 405 | } |
406 | 406 | ||
407 | /** | 407 | /** |
408 | * Controls whether the started process should drop any | 408 | * Controls whether the started process should drop any |
409 | * setuid/segid privileges or whether it should keep them | 409 | * setuid/segid privileges or whether it should keep them |
410 | * | 410 | * |
411 | * The default is @p false : drop privileges | 411 | * The default is @p false : drop privileges |
412 | */ | 412 | */ |
413 | void setRunPrivileged( bool keepPrivileges ); | 413 | void setRunPrivileged( bool keepPrivileges ); |
414 | 414 | ||
415 | /** | 415 | /** |
416 | * Returns whether the started process will drop any | 416 | * Returns whether the started process will drop any |
417 | * setuid/segid privileges or whether it will keep them | 417 | * setuid/segid privileges or whether it will keep them |
418 | */ | 418 | */ |
419 | bool runPrivileged() const; | 419 | bool runPrivileged() const; |
420 | 420 | ||
421 | /** | 421 | /** |
422 | * Modifies the environment of the process to be started. | 422 | * Modifies the environment of the process to be started. |
423 | * This function must be called before starting the process. | 423 | * This function must be called before starting the process. |
424 | */ | 424 | */ |
425 | void setEnvironment( const QString &name, const QString &value ); | 425 | void setEnvironment( const QString &name, const QString &value ); |
426 | 426 | ||
427 | /** | 427 | /** |
428 | * Changes the current working directory (CWD) of the process | 428 | * Changes the current working directory (CWD) of the process |
429 | * to be started. | 429 | * 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 setWorkingDirectory( const QString &dir ); | 432 | void setWorkingDirectory( const QString &dir ); |
433 | 433 | ||
434 | /** | 434 | /** |
435 | * Specify whether to start the command via a shell or directly. | 435 | * Specify whether to start the command via a shell or directly. |
436 | * The default is to start the command directly. | 436 | * The default is to start the command directly. |
437 | * 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 |
438 | * if shell is empty, the standard shell is used. | 438 | * if shell is empty, the standard shell is used. |
439 | * @p quote A flag indicating whether to quote the arguments. | 439 | * @p quote A flag indicating whether to quote the arguments. |
440 | * | 440 | * |
441 | * 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. |
442 | * are properly quoted when passed as argument. | 442 | * are properly quoted when passed as argument. |
443 | * @see quote() | 443 | * @see quote() |
444 | */ | 444 | */ |
445 | void setUseShell( bool useShell, const char *shell = 0 ); | 445 | void setUseShell( bool useShell, const char *shell = 0 ); |
446 | 446 | ||
447 | /** | 447 | /** |
448 | * 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 |
449 | * the shell processes it properly. This is e. g. necessary for | 449 | * the shell processes it properly. This is e. g. necessary for |
450 | * user-provided file names which may contain spaces or quotes. | 450 | * user-provided file names which may contain spaces or quotes. |
451 | * It also prevents expansion of wild cards and environment variables. | 451 | * It also prevents expansion of wild cards and environment variables. |
452 | */ | 452 | */ |
453 | static QString quote( const QString &arg ); | 453 | static QString quote( const QString &arg ); |
454 | 454 | ||
455 | /** | 455 | /** |
456 | * Detaches OProcess from child process. All communication is closed. | 456 | * Detaches OProcess from child process. All communication is closed. |
457 | * No exit notification is emitted any more for the child process. | 457 | * No exit notification is emitted any more for the child process. |
458 | * Deleting the OProcess will no longer kill the child process. | 458 | * Deleting the OProcess will no longer kill the child process. |
459 | * Note that the current process remains the parent process of the | 459 | * Note that the current process remains the parent process of the |
460 | * child process. | 460 | * child process. |
461 | */ | 461 | */ |
462 | void detach(); | 462 | void detach(); |
463 | 463 | ||
464 | /** | ||
465 | * @return the PID of @a process, or -1 if the process is not running | ||
466 | */ | ||
467 | static int processPID( const QString& process ); | ||
468 | |||
464 | signals: | 469 | signals: |
465 | 470 | ||
466 | /** | 471 | /** |
467 | * Emitted after the process has terminated when | 472 | * Emitted after the process has terminated when |
468 | * the process was run in the @p NotifyOnExit (==default option to | 473 | * the process was run in the @p NotifyOnExit (==default option to |
469 | * @ref start()) or the @ref Block mode. | 474 | * @ref start()) or the @ref Block mode. |
470 | **/ | 475 | **/ |
471 | void processExited( OProcess *proc ); | 476 | void processExited( OProcess *proc ); |
472 | 477 | ||
473 | 478 | ||
474 | /** | 479 | /** |
475 | * Emitted, when output from the child process has | 480 | * Emitted, when output from the child process has |
476 | * been received on stdout. | 481 | * been received on stdout. |
477 | * | 482 | * |
478 | * To actually get | 483 | * To actually get |
479 | * these signals, the respective communication link (stdout/stderr) | 484 | * these signals, the respective communication link (stdout/stderr) |
480 | * has to be turned on in @ref start(). | 485 | * has to be turned on in @ref start(). |
481 | * | 486 | * |
482 | * @param buffer The data received. | 487 | * @param buffer The data received. |
483 | * @param buflen The number of bytes that are available. | 488 | * @param buflen The number of bytes that are available. |
484 | * | 489 | * |
485 | * You should copy the information contained in @p buffer to your private | 490 | * You should copy the information contained in @p buffer to your private |
486 | * data structures before returning from this slot. | 491 | * data structures before returning from this slot. |
487 | **/ | 492 | **/ |
488 | void receivedStdout( OProcess *proc, char *buffer, int buflen ); | 493 | void receivedStdout( OProcess *proc, char *buffer, int buflen ); |
489 | 494 | ||
490 | /** | 495 | /** |
491 | * Emitted when output from the child process has | 496 | * Emitted when output from the child process has |
492 | * been received on stdout. | 497 | * been received on stdout. |
493 | * | 498 | * |
494 | * To actually get these signals, the respective communications link | 499 | * To actually get these signals, the respective communications link |
495 | * (stdout/stderr) has to be turned on in @ref start() and the | 500 | * (stdout/stderr) has to be turned on in @ref start() and the |
496 | * @p NoRead flag should have been passed. | 501 | * @p NoRead flag should have been passed. |
497 | * | 502 | * |
498 | * You will need to explicitly call resume() after your call to start() | 503 | * You will need to explicitly call resume() after your call to start() |
499 | * to begin processing data from the child process's stdout. This is | 504 | * to begin processing data from the child process's stdout. This is |
500 | * to ensure that this signal is not emitted when no one is connected | 505 | * to ensure that this signal is not emitted when no one is connected |
501 | * to it, otherwise this signal will not be emitted. | 506 | * to it, otherwise this signal will not be emitted. |
502 | * | 507 | * |
503 | * The data still has to be read from file descriptor @p fd. | 508 | * The data still has to be read from file descriptor @p fd. |
504 | **/ | 509 | **/ |
505 | void receivedStdout( int fd, int &len ); | 510 | void receivedStdout( int fd, int &len ); |
506 | 511 | ||
507 | 512 | ||
508 | /** | 513 | /** |
509 | * Emitted, when output from the child process has | 514 | * Emitted, when output from the child process has |
510 | * been received on stderr. | 515 | * been received on stderr. |
511 | * To actually get | 516 | * To actually get |
512 | * these signals, the respective communication link (stdout/stderr) | 517 | * these signals, the respective communication link (stdout/stderr) |
513 | * has to be turned on in @ref start(). | 518 | * has to be turned on in @ref start(). |
514 | * | 519 | * |
515 | * @param buffer The data received. | 520 | * @param buffer The data received. |
516 | * @param buflen The number of bytes that are available. | 521 | * @param buflen The number of bytes that are available. |
517 | * | 522 | * |
518 | * You should copy the information contained in @p buffer to your private | 523 | * You should copy the information contained in @p buffer to your private |
519 | * data structures before returning from this slot. | 524 | * data structures before returning from this slot. |
520 | */ | 525 | */ |
521 | void receivedStderr( OProcess *proc, char *buffer, int buflen ); | 526 | void receivedStderr( OProcess *proc, char *buffer, int buflen ); |
522 | 527 | ||
523 | /** | 528 | /** |
524 | * Emitted after all the data that has been | 529 | * Emitted after all the data that has been |
525 | * specified by a prior call to @ref writeStdin() has actually been | 530 | * specified by a prior call to @ref writeStdin() has actually been |
526 | * written to the child process. | 531 | * written to the child process. |
527 | **/ | 532 | **/ |
528 | void wroteStdin( OProcess *proc ); | 533 | void wroteStdin( OProcess *proc ); |
529 | 534 | ||
530 | protected slots: | 535 | protected slots: |
531 | 536 | ||
532 | /** | 537 | /** |
533 | * This slot gets activated when data from the child's stdout arrives. | 538 | * This slot gets activated when data from the child's stdout arrives. |
534 | * It usually calls "childOutput" | 539 | * It usually calls "childOutput" |
535 | */ | 540 | */ |
536 | void slotChildOutput( int fdno ); | 541 | void slotChildOutput( int fdno ); |
537 | 542 | ||
538 | /** | 543 | /** |
539 | * This slot gets activated when data from the child's stderr arrives. | 544 | * This slot gets activated when data from the child's stderr arrives. |
540 | * It usually calls "childError" | 545 | * It usually calls "childError" |
541 | */ | 546 | */ |
542 | void slotChildError( int fdno ); | 547 | void slotChildError( int fdno ); |
543 | /* | 548 | /* |
544 | Slot functions for capturing stdout and stderr of the child | 549 | Slot functions for capturing stdout and stderr of the child |
545 | */ | 550 | */ |
546 | 551 | ||
547 | /** | 552 | /** |
548 | * Called when another bulk of data can be sent to the child's | 553 | * Called when another bulk of data can be sent to the child's |
549 | * stdin. If there is no more data to be sent to stdin currently | 554 | * stdin. If there is no more data to be sent to stdin currently |
550 | * available, this function must disable the QSocketNotifier "innot". | 555 | * available, this function must disable the QSocketNotifier "innot". |
551 | */ | 556 | */ |
552 | void slotSendData( int dummy ); | 557 | void slotSendData( int dummy ); |
553 | 558 | ||
554 | protected: | 559 | protected: |
555 | 560 | ||
556 | /** | 561 | /** |
557 | * Sets up the environment according to the data passed via | 562 | * Sets up the environment according to the data passed via |
558 | * setEnvironment(...) | 563 | * setEnvironment(...) |
559 | */ | 564 | */ |