• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KInit

kinit_win.cpp

Go to the documentation of this file.
00001 /*
00002  * This file is part of the KDE libraries
00003  * Copyright (c) 1999-2000 Waldo Bastian <bastian@kde.org>
00004  *                 (c) 1999 Mario Weilguni <mweilguni@sime.com>
00005  *                 (c) 2001 Lubos Lunak <l.lunak@kde.org>
00006  *                 (c) 2006 Ralf Habacker <ralf.habacker@freenet.de>
00007  *
00008  * This library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Library General Public
00010  * License version 2 as published by the Free Software Foundation.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the GNU
00015  * Library General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Library General Public License
00018  * along with this library; see the file COPYING.LIB.    If not, write to
00019  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020  * Boston, MA 02110-1301, USA.
00021  */
00022 
00023 #include <config.h>
00024 
00025 
00026 #include <errno.h>
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030 
00031 #include <windows.h>
00032 #include <psapi.h>
00033 
00034 
00035 #include <QtCore/QProcess>
00036 #include <QtCore/QFileInfo>
00037 #include <QtDBus/QtDBus>
00038 
00039 #include <kcomponentdata.h>
00040 #include <kstandarddirs.h>
00041 #include <kapplication.h>
00042 #include <kdeversion.h>
00043 
00044 //#define ENABLE_SUICIDE 
00045 //#define ENABLE_EXIT
00046 
00047 #define KDED_EXENAME "kded4"
00048 
00049 static KComponentData *s_instance = 0;
00050 
00051 // print verbose messages
00052 int verbose=0;
00053 
00055 QList<QProcess*> startedProcesses;
00056 
00057 class ProcessListEntry {
00058     public:
00059        ProcessListEntry(HANDLE _handle,char *_path, int _pid ) 
00060        {    
00061            QFileInfo p(_path);
00062            path = p.absolutePath();
00063            name = p.baseName();
00064            handle = _handle; 
00065            pid = _pid; 
00066        }
00067        QString name;
00068        QString path;
00069        int pid;
00070        HANDLE handle;
00071        friend QDebug operator <<(QDebug out, const ProcessListEntry &c);
00072 };
00073 
00074 QDebug operator <<(QDebug out, const ProcessListEntry &c)
00075 {
00076     out << "(ProcessListEntry" 
00077         << "name" << c.name
00078         << "path" << c.path
00079         << "pid" << c.pid
00080         << "handle" << c.handle
00081         << ")";
00082     return out;
00083 }    
00084 
00088 class ProcessList {
00089     public:
00090        ProcessList() {initProcessList(); }
00091        ~ProcessList();
00092        ProcessListEntry *hasProcessInList(const QString &name);
00093        bool terminateProcess(const QString &name);
00094        QList<ProcessListEntry *> &list() { return processList; }
00095     private:
00096        void initProcessList();
00097        void getProcessNameAndID( DWORD processID );
00098        QList<ProcessListEntry *> processList;
00099 };
00100 
00101 
00102 void ProcessList::getProcessNameAndID( DWORD processID )
00103 {
00104     char szProcessName[MAX_PATH];
00105 
00106     // Get a handle to the process.
00107 
00108     HANDLE hProcess = OpenProcess( SYNCHRONIZE|PROCESS_QUERY_INFORMATION |
00109                                    PROCESS_VM_READ | PROCESS_TERMINATE,
00110                                    false, processID );
00111 
00112     // Get the process name.
00113     int ret;
00114 
00115     if (NULL != hProcess )
00116     {
00117        HMODULE hMod;
00118        DWORD cbNeeded;
00119 
00120        if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod),
00121               &cbNeeded) )
00122        {
00123             ret = GetModuleFileNameExA( hProcess, hMod, szProcessName,
00124                                            sizeof(szProcessName)/sizeof(TCHAR) );
00125        }
00126     }
00127     if (ret > 0)
00128     {
00129         processList << new ProcessListEntry(hProcess,szProcessName,processID );
00130     }
00131 }
00132 
00133 
00137 void ProcessList::initProcessList()
00138 {
00139     // Get the list of process identifiers.
00140 
00141     DWORD aProcesses[1024], cbNeeded, cProcesses;
00142     unsigned int i;
00143 
00144     if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
00145         return;
00146 
00147     // Calculate how many process identifiers were returned.
00148 
00149     cProcesses = cbNeeded / sizeof(DWORD);
00150 
00151     // Print the name and process identifier for each process.
00152 
00153     for ( i = 0; i < cProcesses; i++ )
00154         if( aProcesses[i] != 0 )
00155             getProcessNameAndID( aProcesses[i] );
00156 }
00157 
00158 
00159 ProcessList::~ProcessList()
00160 {
00161     ProcessListEntry *ple;
00162     foreach(ple,processList) {
00163         CloseHandle(ple->handle);
00164         delete ple;
00165     }
00166 }
00167 
00171 ProcessListEntry *ProcessList::hasProcessInList(const QString &name)
00172 {
00173     ProcessListEntry *ple;
00174     foreach(ple,processList) {
00175         if (ple->name == name || ple->name == name + ".exe") {
00176             return ple;
00177         }
00178     }
00179     return NULL;
00180 }
00181 
00185 bool ProcessList::terminateProcess(const QString &name)
00186 {
00187     ProcessListEntry *p = hasProcessInList(name);
00188     if (!p)
00189         return false;
00190     return TerminateProcess(p->handle,0) ? true : false;
00191 }
00192 
00193 // internal launch function
00194 int launch(const QString &cmd)
00195 {
00196     QProcess *proc = new QProcess();
00197     proc->start(cmd);
00198     proc->waitForStarted();
00199     startedProcesses << proc;
00200     _PROCESS_INFORMATION* _pid = proc->pid();
00201     int pid = _pid ? _pid->dwProcessId : 0;
00202     if (verbose) {
00203         fprintf(stderr,"%s",proc->readAllStandardError().constData());
00204         fprintf(stderr,"%s",proc->readAllStandardOutput().constData());
00205     }
00206     if (pid) {
00207        if (verbose)
00208            fprintf(stderr, "kdeinit4: Launched %s, pid = %ld\n", qPrintable(cmd),(long) pid);
00209     }
00210     else {
00211        if (verbose)
00212            fprintf(stderr, "kdeinit4: could not launch %s, exiting",qPrintable(cmd));
00213     }
00214     return pid;
00215 }
00216 
00218 bool checkIfRegisteredInDBus(const QString &name, int _timeout=10)
00219 {
00220     int timeout = _timeout * 5;
00221     while(timeout) {
00222         if ( QDBusConnection::sessionBus().interface()->isServiceRegistered( name ) )
00223             break;
00224         Sleep(200);
00225         timeout--;
00226     }
00227         if (!timeout) {
00228             if (verbose)
00229                 fprintf(stderr,"not registered %s in dbus after %d secs\n",qPrintable(name),_timeout);
00230             return false;
00231         }
00232         if (verbose)
00233             fprintf(stderr,"%s is registered in dbus\n",qPrintable(name));
00234     return true;
00235 }
00236 
00237 void listAllRunningKDEProcesses(ProcessList &processList)
00238 {
00239     ProcessListEntry *ple;
00240     QString installPrefix = KStandardDirs::installPath("kdedir");
00241 
00242     foreach(ple,processList.list()) 
00243     {
00244         if (ple->path.toLower().startsWith(installPrefix.toLower()))
00245             fprintf(stderr,"path: %s name: %s pid: %u\n", ple->path.toLatin1().data(), ple->name.toLatin1().data(), ple->pid);
00246     }
00247 }
00248 
00249 void terminateAllRunningKDEProcesses(ProcessList &processList)
00250 {
00251     ProcessListEntry *ple;
00252     QString installPrefix = KStandardDirs::installPath("kdedir");
00253 
00254     foreach(ple,processList.list()) 
00255     {
00256         if (ple->path.toLower().startsWith(installPrefix.toLower())) 
00257         {
00258             if (verbose)
00259                 fprintf(stderr,"terminating path: %s name: %s pid: %u\n", ple->path.toLatin1().data(), ple->name.toLatin1().data(), ple->pid);
00260             processList.terminateProcess(ple->name);
00261         }
00262     }
00263 }
00264 
00265 void listAllNamedAppsInDBus()
00266 {
00267     QDBusConnection connection = QDBusConnection::sessionBus();
00268     QDBusConnectionInterface *bus = connection.interface();
00269     const QStringList services = bus->registeredServiceNames();
00270     foreach(const QString &service, services) {
00271         if (service.startsWith("org.freedesktop.DBus") || service.startsWith(':'))
00272             continue;
00273         fprintf(stderr, "%s \n", service.toLatin1().data());
00274     }
00275 }
00276 
00277 void quitApplicationsOverDBus()
00278 {
00279     QDBusConnection connection = QDBusConnection::sessionBus();
00280     QDBusConnectionInterface *bus = connection.interface();
00281     const QStringList services = bus->registeredServiceNames();
00282     foreach(const QString &service, services) {
00283         if (service.startsWith("org.freedesktop.DBus") || service.startsWith(':'))
00284             continue;
00285         QDBusInterface *iface = new QDBusInterface(service,
00286                                QLatin1String("/MainApplication"),
00287 //  see http://lists.kde.org/?l=kde-core-devel&m=121641642911291&w=2
00288 #if QT_VERSION < 0x040402
00289                                QLatin1String(""),
00290 #else                             
00291                                QLatin1String("org.kde.KApplication"),
00292 #endif
00293                                connection);
00294         if (!iface->isValid()) {
00295             if (verbose)
00296                 fprintf(stderr, "invalid interface of service %s\n", service.toLatin1().data());
00297             continue;
00298         }
00299         iface->call("quit");
00300         if (iface->lastError().isValid()) {
00301             if (verbose)
00302                 fprintf(stderr,"killing %s with result\n", iface->lastError().message().toLatin1().data());
00303         }
00304         delete iface;
00305     }
00306 }
00307 
00308 int main(int argc, char **argv, char **envp)
00309 {
00310     pid_t pid;
00311     bool launch_dbus = true;
00312     bool launch_klauncher = true;
00313     bool launch_kded = true;
00314     bool suicide = false;
00315     bool listProcesses = false;
00316     bool killProcesses = false;
00317     bool listAppsInDBus = false;
00318     bool quitAppsOverDBus = false;
00319     bool shutdown = false;
00320 
00322     char **safe_argv = (char **) malloc( sizeof(char *) * argc);
00323     for(int i = 0; i < argc; i++)
00324     {
00325         safe_argv[i] = strcpy((char*)malloc(strlen(argv[i])+1), argv[i]);
00326         if (strcmp(safe_argv[i], "--no-dbus") == 0)
00327             launch_dbus = false;
00328         if (strcmp(safe_argv[i], "--no-klauncher") == 0)
00329             launch_klauncher = false;
00330         if (strcmp(safe_argv[i], "--no-kded") == 0)
00331             launch_kded = false;
00332         if (strcmp(safe_argv[i], "--suicide") == 0)
00333             suicide = true;
00334 #ifdef ENABLE_EXIT
00335         if (strcmp(safe_argv[i], "--exit") == 0)
00336             keep_running = 0;
00337 #endif            
00338         if (strcmp(safe_argv[i], "--verbose") == 0)
00339             verbose = 1;
00340         if (strcmp(safe_argv[i], "--version") == 0) 
00341         { 
00342             printf("Qt: %s\n",qVersion()); 
00343             printf("KDE: %s\n", KDE_VERSION_STRING); 
00344             exit(0);
00345         } 
00346         if (strcmp(safe_argv[i], "--help") == 0)
00347         {
00348            printf("Usage: kdeinit4 [options]\n");
00349 #ifdef ENABLE_EXIT
00350            printf("   --exit                     Terminate when kded has run\n");
00351 #endif
00352            printf("   --help                     this help page\n");
00353            printf("   --list                     list kde processes\n");
00354            printf("   --list-dbus-apps           list all applications registered in dbus\n");
00355            printf("   --quit-over-dbus           quit all application registered in dbus\n");
00356            printf("   --no-dbus                  do not start dbus-daemon\n");
00357            printf("   --no-klauncher             do not start klauncher\n");
00358            printf("   --no-kded                  do not start kded\n");
00359            printf("   --shutdown                 safe shutdown of all running kde processes\n");
00360            printf("                              first over dbus, then using hard kill\n");
00361 #ifdef ENABLE_SUICIDE
00362            printf("    --suicide                 terminate when no KDE applications are left running\n");
00363 #endif
00364            printf("   --terminate                hard kill of *all* running kde processes\n");
00365            printf("   --verbose                  print verbose messages\n");
00366        printf("   --version                  Show version information\n");
00367            exit(0);
00368         }
00369         if (strcmp(safe_argv[i], "--list") == 0)
00370             listProcesses = true;
00371         if (strcmp(safe_argv[i], "--shutdown") == 0)
00372             shutdown = true;
00373         if (strcmp(safe_argv[i], "--terminate") == 0 || strcmp(safe_argv[i], "--kill") == 0)
00374             killProcesses = true;
00375         if (strcmp(safe_argv[i], "--list-dbus-apps") == 0)
00376             listAppsInDBus = true;
00377         if (strcmp(safe_argv[i], "--quit-over-dbus") == 0)
00378             quitAppsOverDBus = true;
00379     }
00380 
00381     ProcessList processList;
00382 
00383     if (listProcesses) {
00384         listAllRunningKDEProcesses(processList);
00385         return 0;
00386     }
00387     else if (killProcesses) {
00388         terminateAllRunningKDEProcesses(processList);
00389         return 0;
00390     }
00391     else if (listAppsInDBus) {
00392         listAllNamedAppsInDBus();
00393         return 0;
00394     }
00395     else if (quitAppsOverDBus) {
00396         quitApplicationsOverDBus();
00397         return 0;
00398     }
00399     else if (shutdown) {
00400         quitApplicationsOverDBus();
00401         Sleep(2000);
00402         terminateAllRunningKDEProcesses(processList);
00403     }
00404     
00406     s_instance = new KComponentData("kdeinit4", QByteArray(), KComponentData::SkipMainComponentRegistration);
00407 
00408     if (launch_dbus && !processList.hasProcessInList("dbus-daemon"))
00409     {
00410           pid = launch("dbus-launch.exe");
00411           if (!pid)
00412               pid = launch("dbus-launch.bat");
00413           if (!pid)
00414               exit(1);
00415     }
00416 
00417     if (launch_klauncher && !processList.hasProcessInList("klauncher"))
00418     {
00419           pid = launch("klauncher");
00420           if (!pid || !checkIfRegisteredInDBus("org.kde.klauncher",10))
00421               exit(1);
00422     }
00423 
00424 
00425     if (launch_kded && !processList.hasProcessInList(KDED_EXENAME))
00426     {
00427         pid = launch(KDED_EXENAME);
00428         if (!pid || !checkIfRegisteredInDBus("org.kde.kded",10))
00429             exit(1);
00430     }
00431 
00432     for(int i = 1; i < argc; i++)
00433     {
00434         if (safe_argv[i][0] == '+')
00435         {
00436             pid = launch(safe_argv[i]+1);
00437         }
00438         else if (safe_argv[i][0] == '-')
00439         {
00440             // Ignore
00441         }
00442         else
00443         {
00444             pid = launch( safe_argv[i]);
00445         }
00446     }
00447 
00449     for(int i = 0; i < argc; i++)
00450     {
00451           free(safe_argv[i]);
00452     }
00453     free (safe_argv);
00454 
00456 #ifdef ENABLE_SUICIDE
00457     if (suicide) {
00458         QProcess *proc;
00459         int can_exit=1;
00460         do {
00461            foreach(proc,startedProcesses) {
00462              if (proc->state() != QProcess::NotRunning)
00463                 can_exit = 0;
00464            }
00465            if (!can_exit)
00466              Sleep(2000);
00467         } while(!can_exit);
00468         return 0;
00469     }
00470 #endif    
00471     return 0;
00472 }

KInit

Skip menu "KInit"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal