1 | /* |
2 | This file is part of the KDE libraries |
3 | Copyright (c) 1999 Waldo Bastian <bastian@kde.org> |
4 | |
5 | This library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Library General Public |
7 | License version 2 as published by the Free Software Foundation. |
8 | |
9 | This library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | Library General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Library General Public License |
15 | along with this library; see the file COPYING.LIB. If not, write to |
16 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
17 | Boston, MA 02110-1301, USA. |
18 | */ |
19 | |
20 | #include <config.h> |
21 | |
22 | #include <unistd.h> |
23 | #include <fcntl.h> |
24 | |
25 | #include "klauncher.h" |
26 | #include <kcomponentdata.h> |
27 | #include "kcrash.h" |
28 | #include "kdebug.h" |
29 | #include <stdio.h> |
30 | #include <stdlib.h> |
31 | #include <signal.h> |
32 | #include <klocale.h> |
33 | #include <kde_file.h> |
34 | |
35 | #include "klauncher_cmds.h" |
36 | #include <QtCore/QCoreApplication> |
37 | |
38 | #ifndef USE_KPROCESS_FOR_KIOSLAVES |
39 | static int sigpipe[ 2 ]; |
40 | static void sig_handler(int sig_num) |
41 | { |
42 | // No recursion |
43 | KDE_signal( SIGHUP, SIG_IGN); |
44 | KDE_signal( SIGTERM, SIG_IGN); |
45 | fprintf(stderr, "klauncher: Exiting on signal %d\n" , sig_num); |
46 | char tmp = 'x'; |
47 | write( sigpipe[ 1 ], &tmp, 1 ); |
48 | } |
49 | #endif |
50 | |
51 | #if defined(Q_OS_DARWIN) || defined (Q_OS_MAC) |
52 | #include <kkernel_mac.h> |
53 | #endif |
54 | |
55 | extern "C" KDE_EXPORT int kdemain( int argc, char**argv ) |
56 | { |
57 | #ifndef Q_WS_WIN |
58 | // Started via kdeinit. |
59 | int launcherFd; |
60 | if (argc != 2 || memcmp(argv[1], "--fd=" , 5) || !(launcherFd = atoi(argv[1] + 5))) |
61 | { |
62 | fprintf(stderr, "%s" , i18n("klauncher: This program is not supposed to be started manually.\n" |
63 | "klauncher: It is started automatically by kdeinit4.\n" ).toLocal8Bit().data()); |
64 | return 1; |
65 | } |
66 | #endif |
67 | |
68 | #if defined(Q_OS_DARWIN) || defined (Q_OS_MAC) |
69 | mac_initialize_dbus(); |
70 | #endif |
71 | |
72 | KComponentData componentData("klauncher" , "kdelibs4" ); |
73 | KGlobal::locale(); |
74 | |
75 | // WABA: Make sure not to enable session management. |
76 | putenv(strdup("SESSION_MANAGER=" )); |
77 | |
78 | // We need a QCoreApplication to get a DBus event loop |
79 | QCoreApplication app(argc, argv); |
80 | app.setApplicationName( componentData.componentName() ); |
81 | |
82 | int maxTry = 3; |
83 | while(true) |
84 | { |
85 | QString service(QLatin1String("org.kde.klauncher" )); // same as ktoolinvocation.cpp |
86 | if (!QDBusConnection::sessionBus().isConnected()) { |
87 | kWarning() << "No DBUS session-bus found. Check if you have started the DBUS server." ; |
88 | return 1; |
89 | } |
90 | QDBusReply<QDBusConnectionInterface::RegisterServiceReply> reply = |
91 | QDBusConnection::sessionBus().interface()->registerService(service); |
92 | if (!reply.isValid()) |
93 | { |
94 | kWarning() << "DBUS communication problem!" ; |
95 | return 1; |
96 | } |
97 | if (reply == QDBusConnectionInterface::ServiceRegistered) |
98 | break; |
99 | |
100 | if (--maxTry == 0) |
101 | { |
102 | kWarning() << "Another instance of klauncher is already running!" ; |
103 | return 1; |
104 | } |
105 | |
106 | // Wait a bit... |
107 | kWarning() << "Waiting for already running klauncher to exit." ; |
108 | sleep(1); |
109 | |
110 | // Try again... |
111 | } |
112 | |
113 | #ifndef USE_KPROCESS_FOR_KIOSLAVES |
114 | KLauncher *launcher = new KLauncher(launcherFd); |
115 | #else |
116 | KLauncher *launcher = new KLauncher(); |
117 | #endif |
118 | QDBusConnection::sessionBus().registerObject(QString::fromLatin1("/" ), launcher); |
119 | |
120 | #ifndef USE_KPROCESS_FOR_KIOSLAVES |
121 | if (pipe(sigpipe) != 0) { |
122 | perror("klauncher: pipe failed." ); |
123 | return 1; |
124 | } |
125 | QSocketNotifier* signotif = new QSocketNotifier( sigpipe[ 0 ], QSocketNotifier::Read, launcher ); |
126 | QObject::connect( signotif, SIGNAL(activated(int)), launcher, SLOT(destruct())); |
127 | KCrash::setEmergencySaveFunction(sig_handler); |
128 | KDE_signal( SIGHUP, sig_handler); |
129 | KDE_signal( SIGPIPE, SIG_IGN); |
130 | KDE_signal( SIGTERM, sig_handler); |
131 | #endif |
132 | |
133 | return app.exec(); |
134 | } |
135 | |