summaryrefslogtreecommitdiffabout
path: root/microkde
Side-by-side diff
Diffstat (limited to 'microkde') (more/less context) (ignore whitespace changes)
-rw-r--r--microkde/microkde.pro7
-rw-r--r--microkde/oprocess.cpp1
2 files changed, 7 insertions, 1 deletions
diff --git a/microkde/microkde.pro b/microkde/microkde.pro
index 21da158..6e75442 100644
--- a/microkde/microkde.pro
+++ b/microkde/microkde.pro
@@ -1,174 +1,179 @@
TEMPLATE = lib
CONFIG += qt warn_on
#INCLUDEPATH += $(QTDIR)/include .
#DEPENDPATH += $(QTDIR)/include
INCLUDEPATH += . ../ ../kabc ./kdecore ./kdeui ./kio/kfile ./kio/kio
#LIBS += -lqtcompat
TARGET = microkde
DESTDIR= ../bin
DEFINES += DESKTOP_VERSION KDE_QT_ONLY
unix : {
OBJECTS_DIR = obj/unix
MOC_DIR = moc/unix
}
win32: {
DEFINES += _WIN32_
OBJECTS_DIR = obj/win
MOC_DIR = moc/win
}
include( ../variables.pri )
HEADERS = \
qlayoutengine_p.h \
KDGanttMinimizeSplitter.h \
kapplication.h \
kaudioplayer.h \
kcalendarsystem.h \
kcalendarsystemgregorian.h \
kcolorbutton.h \
kcolordialog.h \
kcombobox.h \
kconfig.h \
kdatetbl.h \
kdebug.h \
kdialog.h \
kdialogbase.h \
keditlistbox.h \
kemailsettings.h \
kfiledialog.h \
kfontdialog.h \
kglobal.h \
kglobalsettings.h \
kiconloader.h \
klineedit.h \
klineeditdlg.h \
kmessagebox.h \
knotifyclient.h \
kprinter.h \
kprocess.h \
krestrictedline.h \
krun.h \
ksimpleconfig.h \
kstaticdeleter.h \
ksystemtray.h \
ktempfile.h \
ktextedit.h \
kunload.h \
kurl.h \
+oprocctrl.h \
+oprocess.h \
+osmartpointer.h \
kdeui/kguiitem.h \
kdeui/kcmodule.h \
kdeui/kbuttonbox.h \
kdeui/klistbox.h \
kdeui/klistview.h \
kdeui/kjanuswidget.h \
kdeui/kseparator.h \
kdeui/knuminput.h \
kdeui/knumvalidator.h \
kdeui/ksqueezedtextlabel.h \
kio/job.h \
kio/kio/kdirwatch.h \
kio/kio/kdirwatch_p.h \
kio/kfile/kurlrequester.h \
kresources/resource.h \
kresources/factory.h \
kresources/managerimpl.h \
kresources/manager.h \
kresources/selectdialog.h \
kresources/configpage.h \
kresources/configwidget.h \
kresources/configdialog.h \
kresources/kcmkresources.h \
kdecore/kmdcodec.h \
kdecore/kconfigbase.h \
kdecore/klocale.h \
kdecore/kcatalogue.h \
kdecore/ksharedptr.h \
kdecore/kshell.h \
kdecore/kstandarddirs.h \
kdecore/kstringhandler.h \
kdecore/kshortcut.h \
kutils/kcmultidialog.h \
kdeui/kxmlguiclient.h \
kdeui/kstdaction.h \
kdeui/kmainwindow.h \
kdeui/ktoolbar.h \
kdeui/ktoolbarbutton.h \
kdeui/ktoolbarhandler.h \
kdeui/kaction.h \
kdeui/kactionclasses.h \
kdeui/kactioncollection.h \
kdecore/kprefs.h \
kdecore/klibloader.h \
kidmanager.h
# kdecore/klibloader.h \
SOURCES = \
KDGanttMinimizeSplitter.cpp \
kapplication.cpp \
kcalendarsystem.cpp \
kcalendarsystemgregorian.cpp \
kcolorbutton.cpp \
kcolordialog.cpp \
kconfig.cpp \
kdatetbl.cpp \
kdialog.cpp \
kdialogbase.cpp \
keditlistbox.cpp \
kemailsettings.cpp \
kfontdialog.cpp \
kfiledialog.cpp \
kglobal.cpp \
kglobalsettings.cpp \
kiconloader.cpp \
kmessagebox.cpp \
ktextedit.cpp \
kprocess.cpp \
krun.cpp \
ksystemtray.cpp \
ktempfile.cpp \
kurl.cpp \
kdecore/kcatalogue.cpp \
kdecore/klocale.cpp \
kdecore/kmdcodec.cpp \
kdecore/kshell.cpp \
kdecore/kstandarddirs.cpp \
kdecore/kstringhandler.cpp \
kdeui/kbuttonbox.cpp \
kdeui/kcmodule.cpp \
kdeui/kguiitem.cpp \
kdeui/kjanuswidget.cpp \
kdeui/klistbox.cpp \
kdeui/klistview.cpp \
kdeui/knuminput.cpp \
kdeui/knumvalidator.cpp \
kdeui/kseparator.cpp \
kdeui/ksqueezedtextlabel.cpp \
kio/kio/kdirwatch.cpp \
kio/kfile/kurlrequester.cpp \
kresources/configpage.cpp \
kresources/configdialog.cpp \
kresources/configwidget.cpp \
kresources/factory.cpp \
kresources/kcmkresources.cpp \
kresources/managerimpl.cpp \
kresources/resource.cpp \
kresources/selectdialog.cpp \
kutils/kcmultidialog.cpp \
kdeui/kaction.cpp \
kdeui/kactionclasses.cpp \
kdeui/kactioncollection.cpp \
kdeui/kmainwindow.cpp \
kdeui/ktoolbar.cpp \
kdeui/ktoolbarbutton.cpp \
kdeui/ktoolbarhandler.cpp \
kdeui/kstdaction.cpp \
kdeui/kxmlguiclient.cpp \
kdecore/kprefs.cpp \
kdecore/klibloader.cpp \
- kidmanager.cpp
+ kidmanager.cpp \
+oprocctrl.cpp \
+oprocess.cpp
diff --git a/microkde/oprocess.cpp b/microkde/oprocess.cpp
index 95e3e4b..a935792 100644
--- a/microkde/oprocess.cpp
+++ b/microkde/oprocess.cpp
@@ -1,424 +1,425 @@
/*
                This file is part of the Opie Project
            Copyright (C) 2002-2004 Holger Freyther <zecke@handhelds.org>
and The Opie Team <opie-devel@handhelds.org>
=. Based on KProcess (C) 1997 Christian Czezatke (e9025461@student.tuwien.ac.at)
.=l.
         .>+-=
_;:,     .>    :=|. This program is free software; you can
.> <`_,   >  .   <= redistribute it and/or modify it under
:`=1 )Y*s>-.--   : the terms of the GNU Library General Public
.="- .-=="i,     .._ License as published by the Free Software
- .   .-<_>     .<> Foundation; either version 2 of the License,
   ._= =}       : or (at your option) any later version.
  .%`+i>       _;_.
  .i_,=:_.      -<s. This program is distributed in the hope that
   +  .  -:.       = it will be useful, but WITHOUT ANY WARRANTY;
  : ..    .:,     . . . without even the implied warranty of
  =_        +     =;=|` MERCHANTABILITY or FITNESS FOR A
_.=:.       :    :=>`: PARTICULAR PURPOSE. See the GNU
..}^=.=       =       ; Library General Public License for more
++=   -.     .`     .: details.
:     =  ...= . :.=-
-.   .:....=;==+<; You should have received a copy of the GNU
-_. . .   )=.  = Library General Public License along with
  --        :-=` this library; see the file COPYING.LIB.
If not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include "oprocctrl.h"
/* OPIE */
#include <oprocess.h>
/* QT */
#include <qapplication.h>
#include <qdir.h>
#include <qmap.h>
+#include <qregexp.h>
#include <qsocketnotifier.h>
#include <qtextstream.h>
/* STD */
#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
#include <stdlib.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <unistd.h>
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifdef HAVE_INITGROUPS
#include <grp.h>
#endif
using namespace Opie::Core::Internal;
namespace Opie {
namespace Core {
namespace Internal {
class OProcessPrivate
{
public:
OProcessPrivate() : useShell( false )
{ }
bool useShell;
QMap<QString, QString> env;
QString wd;
QCString shell;
};
}
OProcess::OProcess( QObject *parent, const char *name )
: QObject( parent, name )
{
init ( );
}
OProcess::OProcess( const QString &arg0, QObject *parent, const char *name )
: QObject( parent, name )
{
init ( );
*this << arg0;
}
OProcess::OProcess( const QStringList &args, QObject *parent, const char *name )
: QObject( parent, name )
{
init ( );
*this << args;
}
void OProcess::init ( )
{
run_mode = NotifyOnExit;
runs = false;
pid_ = 0;
status = 0;
keepPrivs = false;
innot = 0;
outnot = 0;
errnot = 0;
communication = NoCommunication;
input_data = 0;
input_sent = 0;
input_total = 0;
d = 0;
if ( 0 == OProcessController::theOProcessController )
{
( void ) new OProcessController();
CHECK_PTR( OProcessController::theOProcessController );
}
OProcessController::theOProcessController->addOProcess( this );
out[ 0 ] = out[ 1 ] = -1;
in[ 0 ] = in[ 1 ] = -1;
err[ 0 ] = err[ 1 ] = -1;
}
void OProcess::setEnvironment( const QString &name, const QString &value )
{
if ( !d )
d = new OProcessPrivate;
d->env.insert( name, value );
}
void OProcess::setWorkingDirectory( const QString &dir )
{
if ( !d )
d = new OProcessPrivate;
d->wd = dir;
}
void OProcess::setupEnvironment()
{
if ( d )
{
QMap<QString, QString>::Iterator it;
for ( it = d->env.begin(); it != d->env.end(); ++it )
setenv( QFile::encodeName( it.key() ).data(),
QFile::encodeName( it.data() ).data(), 1 );
if ( !d->wd.isEmpty() )
chdir( QFile::encodeName( d->wd ).data() );
}
}
void OProcess::setRunPrivileged( bool keepPrivileges )
{
keepPrivs = keepPrivileges;
}
bool OProcess::runPrivileged() const
{
return keepPrivs;
}
OProcess::~OProcess()
{
// destroying the OProcess instance sends a SIGKILL to the
// child process (if it is running) after removing it from the
// list of valid processes (if the process is not started as
// "DontCare")
OProcessController::theOProcessController->removeOProcess( this );
// this must happen before we kill the child
// TODO: block the signal while removing the current process from the process list
if ( runs && ( run_mode != DontCare ) )
kill( SIGKILL );
// Clean up open fd's and socket notifiers.
closeStdin();
closeStdout();
closeStderr();
// TODO: restore SIGCHLD and SIGPIPE handler if this is the last OProcess
delete d;
}
void OProcess::detach()
{
OProcessController::theOProcessController->removeOProcess( this );
runs = false;
pid_ = 0;
// Clean up open fd's and socket notifiers.
closeStdin();
closeStdout();
closeStderr();
}
bool OProcess::setExecutable( const QString& proc )
{
if ( runs )
return false;
if ( proc.isEmpty() )
return false;
if ( !arguments.isEmpty() )
arguments.remove( arguments.begin() );
arguments.prepend( QFile::encodeName( proc ) );
return true;
}
OProcess &OProcess::operator<<( const QStringList& args )
{
QStringList::ConstIterator it = args.begin();
for ( ; it != args.end() ; ++it )
arguments.append( QFile::encodeName( *it ) );
return *this;
}
OProcess &OProcess::operator<<( const QCString& arg )
{
return operator<< ( arg.data() );
}
OProcess &OProcess::operator<<( const char* arg )
{
arguments.append( arg );
return *this;
}
OProcess &OProcess::operator<<( const QString& arg )
{
arguments.append( QFile::encodeName( arg ) );
return *this;
}
void OProcess::clearArguments()
{
arguments.clear();
}
bool OProcess::start( RunMode runmode, Communication comm )
{
uint i;
uint n = arguments.count();
char **arglist;
if ( runs || ( 0 == n ) )
{
return false; // cannot start a process that is already running
// or if no executable has been assigned
}
run_mode = runmode;
status = 0;
QCString shellCmd;
if ( d && d->useShell )
{
if ( d->shell.isEmpty() )
{
qWarning( "Could not find a valid shell" );
return false;
}
arglist = static_cast<char **>( malloc( ( 4 ) * sizeof( char * ) ) );
for ( i = 0; i < n; i++ )
{
shellCmd += arguments[ i ];
shellCmd += " "; // CC: to separate the arguments
}
arglist[ 0 ] = d->shell.data();
arglist[ 1 ] = ( char * ) "-c";
arglist[ 2 ] = shellCmd.data();
arglist[ 3 ] = 0;
}
else
{
arglist = static_cast<char **>( malloc( ( n + 1 ) * sizeof( char * ) ) );
for ( i = 0; i < n; i++ )
arglist[ i ] = arguments[ i ].data();
arglist[ n ] = 0;
}
if ( !setupCommunication( comm ) )
qWarning( "Could not setup Communication!" );
// We do this in the parent because if we do it in the child process
// gdb gets confused when the application runs from gdb.
uid_t uid = getuid();
gid_t gid = getgid();
#ifdef HAVE_INITGROUPS
struct passwd *pw = getpwuid( uid );
#endif
int fd[ 2 ];
if ( 0 > pipe( fd ) )
{
fd[ 0 ] = fd[ 1 ] = 0; // Pipe failed.. continue
}
runs = true;
QApplication::flushX();
// WABA: Note that we use fork() and not vfork() because
// vfork() has unclear semantics and is not standardized.
pid_ = fork();
if ( 0 == pid_ )
{
if ( fd[ 0 ] )
close( fd[ 0 ] );
if ( !runPrivileged() )
{
setgid( gid );
#if defined( HAVE_INITGROUPS)
if ( pw )
initgroups( pw->pw_name, pw->pw_gid );
#endif
setuid( uid );
}
// The child process
if ( !commSetupDoneC() )
qWarning( "Could not finish comm setup in child!" );
setupEnvironment();
// Matthias
if ( run_mode == DontCare )
setpgid( 0, 0 );
// restore default SIGPIPE handler (Harri)
struct sigaction act;
sigemptyset( &( act.sa_mask ) );
sigaddset( &( act.sa_mask ), SIGPIPE );
act.sa_handler = SIG_DFL;
act.sa_flags = 0;
sigaction( SIGPIPE, &act, 0L );
// We set the close on exec flag.
// Closing of fd[1] indicates that the execvp succeeded!
if ( fd[ 1 ] )
fcntl( fd[ 1 ], F_SETFD, FD_CLOEXEC );
execvp( arglist[ 0 ], arglist );
char resultByte = 1;
if ( fd[ 1 ] )
write( fd[ 1 ], &resultByte, 1 );
_exit( -1 );
}
else if ( -1 == pid_ )
{
// forking failed
runs = false;
free( arglist );
return false;
}
else
{
if ( fd[ 1 ] )
close( fd[ 1 ] );
// the parent continues here
// Discard any data for stdin that might still be there
input_data = 0;
// Check whether client could be started.
if ( fd[ 0 ] )
for ( ;; )
{
char resultByte;
int n = ::read( fd[ 0 ], &resultByte, 1 );
if ( n == 1 )
{
// Error
runs = false;
close( fd[ 0 ] );
free( arglist );
pid_ = 0;
return false;
}
if ( n == -1 )
{
if ( ( errno == ECHILD ) || ( errno == EINTR ) )
continue; // Ignore
}
break; // success
}
if ( fd[ 0 ] )
close( fd[ 0 ] );
if ( !commSetupDoneP() ) // finish communication socket setup for the parent
qWarning( "Could not finish comm setup in parent!" );
if ( run_mode == Block )
{
commClose();
// The SIGCHLD handler of the process controller will catch
// the exit and set the status
while ( runs )
{
OProcessController::theOProcessController->
slotDoHousekeeping( 0 );
}
runs = FALSE;
emit processExited( this );
}
}
free( arglist );
return true;
}