-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,90 +1,92 @@ | |||
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 ) |
@@ -868,48 +870,76 @@ QString OProcess::quote( const QString &arg ) | |||
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 | |||
@@ -416,96 +416,101 @@ public: | |||
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 |