22 #define QT_NO_CAST_FROM_ASCII
25 #include <config-kdeinit.h>
27 #include <sys/types.h>
29 #include <sys/resource.h>
31 #include <sys/socket.h>
34 #ifdef HAVE_SYS_SELECT_H
35 #include <sys/select.h>
49 #include <QtCore/QLibrary>
50 #include <QtCore/QString>
51 #include <QtCore/QFile>
52 #include <QtCore/QDate>
53 #include <QtCore/QFileInfo>
54 #include <QtCore/QRegExp>
55 #include <QtGui/QFont>
58 #include <kdemacros.h>
60 #include <kglobalsettings.h>
63 #include <kapplication.h>
70 #include <sys/prctl.h>
72 #define PR_SET_NAME 15
80 #include <kdeversion.h>
86 #include <X11/Xatom.h>
88 #include <kstartupinfo.h>
95 #ifdef __KDE_HAVE_GCC_VISIBILITY
112 #define MAX_SOCK_FILE 255
116 #define DISPLAY "DISPLAY"
117 #elif defined(Q_WS_QWS)
118 #define DISPLAY "QWS_DISPLAY"
119 #elif defined(Q_WS_MACX)
120 #define DISPLAY "MAC_DISPLAY"
121 #elif defined(Q_WS_WIN)
122 #define DISPLAY "WIN_DISPLAY"
124 #error Use QT/X11 or QT/Embedded
167 #ifdef KDEINIT_OOM_PROTECT
168 static int oom_pipe = -1;
180 int maxfd = FD_SETSIZE;
182 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
184 for (
int fd = 3;
fd < maxfd; ++
fd)
186 #ifdef KDEINIT_OOM_PROTECT
199 while (
struct child *child = children) {
201 children = child->next;
205 if (
d.deadpipe[0] != -1)
207 close(
d.deadpipe[0]);
211 if (
d.deadpipe[1] != -1)
213 close(
d.deadpipe[1]);
217 if (
d.initpipe[0] != -1)
219 close(
d.initpipe[0]);
223 if (
d.initpipe[1] != -1)
225 close(
d.initpipe[1]);
229 if (
d.launcher[0] != -1)
231 close(
d.launcher[0]);
239 if (
d.accepted_fd != -1)
241 close(
d.accepted_fd);
257 KDE_signal(SIGCHLD, SIG_DFL);
258 KDE_signal(SIGPIPE, SIG_DFL);
264 struct child *child, **childptr = &
children;
266 while ((child = *childptr))
268 if (child->pid == exit_pid)
272 long request_data[2];
275 request_data[0] = exit_pid;
277 write(child->sock, &request_header,
sizeof(request_header));
278 write(child->sock, request_data, request_header.
arg_length);
281 *childptr = child->next;
286 childptr = &child->next;
293 fprintf( stderr,
"%s\n", errorMsg.toLocal8Bit().data() );
294 QByteArray utf8ErrorMsg = errorMsg.toUtf8();
296 write(
d.fd[1], &
d.result, 1);
297 int l = utf8ErrorMsg.length();
298 write(
d.fd[1], &l,
sizeof(
int));
299 write(
d.fd[1], utf8ErrorMsg.data(), l);
306 if( tty == NULL || *tty ==
'\0' )
308 int fd = KDE_open( tty, O_WRONLY );
311 perror(
"kdeinit4: could not open() tty" );
314 if( dup2( fd, STDOUT_FILENO ) < 0 )
316 perror(
"kdeinit4: could not dup2() stdout tty" );
318 if( dup2( fd, STDERR_FILENO ) < 0 )
320 perror(
"kdeinit4: could not dup2() stderr tty" );
329 #ifdef Q_WS_X11 // Only X11 supports multiple desktops
330 Atom net_current_desktop = XInternAtom( disp,
"_NET_CURRENT_DESKTOP", False );
333 unsigned char *data_ret;
334 unsigned long nitems_ret, unused;
335 if( XGetWindowProperty( disp, DefaultRootWindow( disp ), net_current_desktop,
336 0l, 1l, False, XA_CARDINAL, &type_ret, &format_ret, &nitems_ret, &unused, &data_ret )
339 if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 1)
340 desktop = *((
long *) data_ret) + 1;
342 XFree ((
char*) data_ret);
349 const char*
get_env_var(
const char* var,
int envc,
const char* envs )
353 const char* env_l = envs;
354 int ln = strlen( var );
355 for (
int i = 0; i < envc; i++)
357 if( strncmp( env_l, var, ln ) == 0 )
359 while(*env_l != 0) env_l++;
368 int envc,
const char* envs )
377 KStartupInfoData data;
379 data.setDesktop( desktop );
380 data.setBin(QFile::decodeName(bin));
393 KStartupInfoData data;
407 const QRegExp pathSepRegExp(QString::fromLatin1(
"[:\b]"));
410 const char* path =
get_env_var(
"PATH=", envc, envs );
412 paths = QFile::decodeName(path).split(pathSepRegExp);
414 paths = QString::fromLocal8Bit(qgetenv(
"PATH")).split(pathSepRegExp, QString::KeepEmptyParts);
417 s_instance->
dirs()->
findExe(QFile::decodeName(exec), paths.join(QLatin1String(
":")));
418 if (avoid_loops && !execpath.isEmpty()) {
419 const int pos = execpath.lastIndexOf(QLatin1Char(
'/'));
420 const QString bin_path = execpath.left(pos);
421 for( QStringList::Iterator it = paths.begin();
424 if( *it == bin_path || *it == bin_path + QLatin1Char(
'/')) {
429 execpath = s_instance->
dirs()->
findExe(QFile::decodeName(exec), paths.join(QLatin1String(
":")));
431 return QFile::encodeName(execpath);
434 #ifdef KDEINIT_OOM_PROTECT
435 static void oom_protect_sighandler(
int ) {
441 struct sigaction act, oldact;
442 act.sa_handler = oom_protect_sighandler;
444 sigemptyset( &act.sa_mask );
445 sigaction( SIGUSR1, &act, &oldact );
446 sigset_t sigs, oldsigs;
447 sigemptyset( &sigs );
448 sigaddset( &sigs, SIGUSR1 );
449 sigprocmask( SIG_BLOCK, &sigs, &oldsigs );
450 pid_t pid = getpid();
451 if( write( oom_pipe, &pid,
sizeof( pid_t )) > 0 ) {
452 sigsuspend( &oldsigs );
455 fprintf( stderr,
"Failed to reset OOM protection: %d\n", pid );
458 sigprocmask( SIG_SETMASK, &oldsigs, NULL );
459 sigaction( SIGUSR1, &oldact, NULL );
468 static pid_t
launch(
int argc,
const char *_name,
const char *args,
469 const char *cwd=0,
int envc=0,
const char *envs=0,
470 bool reset_env =
false,
471 const char *tty=0,
bool avoid_loops =
false,
472 const char* startup_id_str =
"0" )
480 if (_name[0] !=
'/') {
482 lib = QFile::decodeName(name);
484 KLibrary klib(QLatin1String(
"libkdeinit4_") + lib, *s_instance );
486 if( libpath.isEmpty()) {
493 lib = QFile::decodeName(name);
494 name = name.mid(name.lastIndexOf(
'/') + 1);
496 if (lib.endsWith(QLatin1String(
".so")))
501 if( lib.contains( QLatin1String(
"/lib" KDELIBSUFF
"/kde4/libexec/" ))) {
502 libpath =
QString( lib ).replace( QLatin1String(
"/lib" KDELIBSUFF
"/kde4/libexec/" ),
503 QLatin1String(
"/lib" KDELIBSUFF
"/libkdeinit4_")) + QLatin1String(
".so");
504 }
else if( lib.contains( QLatin1String(
"/bin/" ))) {
505 libpath =
QString( lib ).replace( QLatin1String(
"/bin/" ),
506 QLatin1String(
"/lib" KDELIBSUFF
"/libkdeinit4_")) + QLatin1String(
".so");
509 if (!QFile::exists(libpath)) {
516 fprintf(stderr,
"kdeinit4: preparing to launch %s\n", libpath.isEmpty()
517 ? execpath.constData() : libpath.toUtf8().constData());
525 perror(
"kdeinit4: pipe() failed");
527 d.errorMsg =
i18n(
"Unable to start new process.\n"
528 "The system may have reached the maximum number of open files possible or the maximum number of open files that you are allowed to use has been reached.").toUtf8();
534 KStartupInfoId startup_id;
535 startup_id.initId( startup_id_str );
536 if( !startup_id.none())
541 const QByteArray docPath = QFile::encodeName(KGlobalSettings::documentPath());
550 perror(
"kdeinit4: fork() failed");
552 d.errorMsg =
i18n(
"Unable to create new process.\n"
553 "The system may have reached the maximum number of processes possible or the maximum number of processes that you are allowed to use has been reached.").toUtf8();
574 (void)chdir(docPath.constData());
581 QList<QByteArray> unset_envs;
582 for(
int tmp_env_count = 0;
585 unset_envs.append(
environ[ tmp_env_count ] );
586 foreach(
const QByteArray &tmp, unset_envs)
588 int pos = tmp.indexOf(
'=' );
590 unsetenv( tmp.left( pos ));
594 for (
int i = 0; i < envc; i++)
596 putenv((
char *)envs);
597 while(*envs != 0) envs++;
602 if( startup_id.none())
603 KStartupInfo::resetStartupEnv();
605 startup_id.setupStartupEnv();
609 QByteArray procTitle;
610 d.argv = (
char **) malloc(
sizeof(
char *) * (argc+1));
611 d.argv[0] = (
char *) _name;
614 if (!argvexe.isEmpty()) {
615 QByteArray cstr = argvexe.toLocal8Bit();
616 kDebug(7016) <<
"kdeinit4: launch() setting argv: " << cstr.data();
617 d.argv[0] = strdup(cstr.data());
620 for (
int i = 1; i < argc; i++)
622 d.argv[i] = (
char *) args;
624 procTitle += (
char *) args;
625 while(*args != 0) args++;
630 #ifndef SKIP_PROCTITLE
634 r = prctl(
PR_SET_NAME, (
unsigned long) name.data(), 0, 0, 0);
636 proctitle_set(
"%s [kdeinit]%s", name.data(), procTitle.data() ? procTitle.data() :
"" );
638 proctitle_set(
"kdeinit4: %s%s", name.data(), procTitle.data() ? procTitle.data() :
"" );
640 proctitle_set(
"kdeinit4: %s%s", name.data(), procTitle.data() ? procTitle.data() :
"" );
645 if (libpath.isEmpty() && execpath.isEmpty())
652 if ( !qgetenv(
"KDE_IS_PRELINKED").isEmpty() && !execpath.isEmpty())
657 if ( !libpath.isEmpty() )
659 if (!l.load() || !l.isLoaded() )
661 QString ltdlError (l.errorString());
662 if (execpath.isEmpty())
671 fprintf(stderr,
"Could not open library %s: %s\n", qPrintable(lib),
672 qPrintable(ltdlError) );
679 write(
d.fd[1], &
d.result, 1);
683 fcntl(
d.fd[1], F_SETFD, FD_CLOEXEC);
687 QByteArray executable = execpath;
689 if (!bundlepath.isEmpty())
690 executable = QFile::encodeName(bundlepath);
693 if (!executable.isEmpty())
694 execvp(executable,
d.argv);
697 write(
d.fd[1], &
d.result, 1);
702 void * sym = l.resolve(
"kdeinitmain");
705 sym = l.resolve(
"kdemain" );
708 QString ltdlError = l.errorString();
709 fprintf(stderr,
"Could not find kdemain: %s\n", qPrintable(ltdlError) );
717 write(
d.fd[1], &
d.result, 1);
720 d.func = (int (*)(int,
char *[])) sym;
723 fprintf(stderr,
"kdeinit4: Suspending process\n"
724 "kdeinit4: 'gdb kdeinit4 %d' to debug\n"
725 "kdeinit4: 'kill -SIGCONT %d' to continue\n",
727 kill(getpid(), SIGSTOP);
734 exit(
d.func(argc,
d.argv));
744 d.n = read(
d.fd[0], &
d.result, 1);
758 d.n = read(
d.fd[0], &l,
sizeof(
int));
759 if (
d.n ==
sizeof(
int))
763 d.n = read(
d.fd[0], tmp.data(), l);
774 if (errno == ECHILD) {
777 if (errno == EINTR || errno == EAGAIN) {
786 fprintf(stderr,
"kdeinit4: (%s %s) Pipe closed unexpectedly", name.constData(), execpath.constData());
787 perror(
"kdeinit4: Pipe closed unexpectedly");
792 perror(
"kdeinit4: Error reading from pipe");
799 if( !startup_id.none())
801 if(
d.fork &&
d.result == 0 )
823 write(
d.deadpipe[1], &c, 1);
830 struct sigaction act;
833 if (pipe(
d.deadpipe) != 0)
835 perror(
"kdeinit4: Aborting. Can not create pipe");
839 options = fcntl(
d.deadpipe[0], F_GETFL);
842 perror(
"kdeinit4: Aborting. Can not make pipe non-blocking");
846 if (fcntl(
d.deadpipe[0], F_SETFL, options | O_NONBLOCK) == -1)
848 perror(
"kdeinit4: Aborting. Can not make pipe non-blocking");
858 sigemptyset(&(act.sa_mask));
859 sigaddset(&(act.sa_mask), SIGCHLD);
860 sigprocmask(SIG_UNBLOCK, &(act.sa_mask), 0L);
861 act.sa_flags = SA_NOCLDSTOP;
867 act.sa_flags |= SA_RESTART;
869 sigaction( SIGCHLD, &act, 0L);
871 act.sa_handler=SIG_IGN;
872 sigemptyset(&(act.sa_mask));
873 sigaddset(&(act.sa_mask), SIGPIPE);
874 sigprocmask(SIG_UNBLOCK, &(act.sa_mask), 0L);
876 sigaction( SIGPIPE, &act, 0L);
881 struct sockaddr_un sa;
882 kde_socklen_t socklen;
884 const QByteArray home_dir = qgetenv(
"HOME");
886 if (home_dir.isEmpty())
888 fprintf(stderr,
"kdeinit4: Aborting. $HOME not set!");
891 if (chdir(home_dir) != 0) {
892 fprintf(stderr,
"kdeinit4: Aborting. Couldn't enter '%s'!", home_dir.constData());
897 QByteArray path = home_dir;
898 QByteArray readOnly = qgetenv(
"KDE_HOME_READONLY");
899 if (
access(path.data(), R_OK|W_OK))
903 fprintf(stderr,
"kdeinit4: Aborting. $HOME directory (%s) does not exist.\n", path.data());
906 else if (readOnly.isEmpty())
908 fprintf(stderr,
"kdeinit4: Aborting. No write access to $HOME directory (%s).\n", path.data());
912 #if 0 // obsolete in kde4. Should we check writing to another file instead?
913 path = qgetenv(
"ICEAUTHORITY");
917 path +=
"/.ICEauthority";
919 if (
access(path.data(), R_OK|W_OK) && (errno != ENOENT))
921 fprintf(stderr,
"kdeinit4: Aborting. No write access to '%s'.\n", path.data());
934 struct sockaddr_un server;
940 s = socket(PF_UNIX, SOCK_STREAM, 0);
943 perror(
"socket() failed");
946 server.sun_family = AF_UNIX;
948 socklen =
sizeof(server);
950 if(connect(s, (
struct sockaddr *)&server, socklen) == 0)
952 fprintf(stderr,
"kdeinit4: Shutting down running client.\n");
956 write(s, &request_header,
sizeof(request_header));
966 d.wrapper = socket(PF_UNIX, SOCK_STREAM, 0);
969 perror(
"kdeinit4: Aborting. socket() failed");
973 options = fcntl(
d.wrapper, F_GETFL);
976 perror(
"kdeinit4: Aborting. Can not make socket non-blocking");
981 if (fcntl(
d.wrapper, F_SETFL, options | O_NONBLOCK) == -1)
983 perror(
"kdeinit4: Aborting. Can not make socket non-blocking");
990 socklen =
sizeof(sa);
991 memset(&sa, 0, socklen);
992 sa.sun_family = AF_UNIX;
994 if(bind(
d.wrapper, (
struct sockaddr *)&sa, socklen) != 0)
996 if (max_tries == 0) {
997 perror(
"kdeinit4: Aborting. bind() failed");
998 fprintf(stderr,
"Could not bind to socket '%s'\n",
sock_file);
1010 perror(
"kdeinit4: Aborting. Can not set permissions on socket");
1011 fprintf(stderr,
"Wrong permissions of socket '%s'\n",
sock_file);
1017 if(
listen(
d.wrapper, SOMAXCONN) < 0)
1019 perror(
"kdeinit4: Aborting. listen() failed");
1033 int bytes_left = len;
1034 while ( bytes_left > 0)
1036 result = read(sock, buffer, bytes_left);
1042 else if (result == 0)
1044 else if ((result == -1) && (errno != EINTR) && (errno != EAGAIN))
1052 if (socketpair(AF_UNIX, SOCK_STREAM, 0,
d.launcher) < 0) {
1053 perror(
"kdeinit4: socketpair() failed");
1057 strcpy(args,
"--fd=");
1058 sprintf(args + 5,
"%d",
d.launcher[1]);
1059 d.launcher_pid =
launch( 2,
"klauncher", args );
1060 close(
d.launcher[1]);
1062 fprintf(stderr,
"kdeinit4: Launched KLauncher, pid = %ld, result = %d\n",
1063 (
long)
d.launcher_pid,
d.result);
1072 fprintf(stderr,
"kdeinit4: Communication error with launcher. Exiting!\n");
1079 fprintf(stderr,
"kdeinit4: KLauncher died unexpectedly.\n");
1084 kill(
d.launcher_pid, SIGKILL);
1088 d.launcher_ok =
false;
1090 close(
d.launcher[0]);
1101 char *request_data = 0L;
1102 int result =
read_socket(sock, (
char *) &request_header,
sizeof(request_header));
1110 request_data = (
char *) malloc(request_header.
arg_length);
1123 d.launcher_ok =
true;
1136 memcpy( &l, request_data,
sizeof(
long ));
1138 const char *name = request_data +
sizeof(long);
1139 const char *args = name + strlen(name) + 1;
1140 const char *cwd = 0;
1142 const char *envs = 0;
1143 const char *tty = 0;
1144 int avoid_loops = 0;
1145 const char *startup_id_str =
"0";
1148 fprintf(stderr,
"kdeinit4: Got %s '%s' from %s.\n",
1153 const char *arg_n = args;
1154 for(
int i = 1; i < argc; i++)
1156 arg_n = arg_n + strlen(arg_n) + 1;
1162 cwd = arg_n; arg_n += strlen(cwd) + 1;
1167 memcpy( &l, arg_n,
sizeof(
long ));
1169 arg_n +=
sizeof(long);
1171 for(
int i = 0; i < envc; i++)
1173 arg_n = arg_n + strlen(arg_n) + 1;
1178 arg_n += strlen( tty ) + 1;
1185 memcpy( &l, arg_n,
sizeof(
long ));
1187 arg_n +=
sizeof( long );
1193 startup_id_str = arg_n;
1194 arg_n += strlen( startup_id_str ) + 1;
1197 if ((request_header.
arg_length > (arg_n - request_data)) &&
1201 cwd = arg_n; arg_n += strlen(cwd) + 1;
1204 if ((arg_n - request_data) != request_header.
arg_length)
1207 fprintf(stderr,
"kdeinit4: EXEC request has invalid format.\n");
1210 d.debug_wait =
false;
1215 QByteArray olddisplay = qgetenv(
DISPLAY);
1216 QByteArray kdedisplay = qgetenv(
"KDE_DISPLAY");
1217 bool reset_display = (! olddisplay.isEmpty() &&
1218 ! kdedisplay.isEmpty() &&
1219 olddisplay != kdedisplay);
1222 setenv(
DISPLAY, kdedisplay,
true);
1224 pid =
launch( argc, name, args, cwd, envc, envs,
1226 tty, avoid_loops, startup_id_str );
1228 if (reset_display) {
1229 unsetenv(
"KDE_DISPLAY");
1230 setenv(
DISPLAY, olddisplay,
true);
1233 if (pid && (
d.result == 0))
1236 response_header.
arg_length =
sizeof(response_data);
1237 response_data = pid;
1238 write(sock, &response_header,
sizeof(response_header));
1239 write(sock, &response_data, response_header.
arg_length);
1242 struct child *child = (
struct child *) malloc(
sizeof(
struct child));
1244 child->sock = dup(sock);
1250 int l =
d.errorMsg.length();
1254 write(sock, &response_header,
sizeof(response_header));
1256 write(sock,
d.errorMsg.data(), l);
1258 d.debug_wait =
false;
1262 const char *env_name;
1263 const char *env_value;
1264 env_name = request_data;
1265 env_value = env_name + strlen(env_name) + 1;
1268 fprintf(stderr,
"kdeinit4: Got SETENV '%s=%s' from %s.\n", env_name, env_value, who);
1272 (
int) (strlen(env_name) + strlen(env_value) + 2))
1275 fprintf(stderr,
"kdeinit4: SETENV request has invalid format.\n");
1280 setenv( env_name, env_value, 1);
1285 fprintf(stderr,
"kdeinit4: terminate KDE.\n");
1294 fprintf(stderr,
"kdeinit4: Got termination request (PID %ld).\n", (
long) getpid());
1296 if (
d.launcher_pid) {
1297 kill(
d.launcher_pid, SIGTERM);
1299 close(
d.launcher[0]);
1307 fprintf(stderr,
"kdeinit4: Closed sockets, but not exiting until all children terminate.\n");
1316 fprintf(stderr,
"kdeinit4: Debug wait activated.\n");
1318 d.debug_wait =
true;
1327 int max_sock =
d.deadpipe[0];
1328 if (
d.wrapper > max_sock)
1329 max_sock =
d.wrapper;
1330 if (
d.launcher[0] > max_sock)
1331 max_sock =
d.launcher[0];
1333 if (
X11fd > max_sock)
1349 while( read(
d.deadpipe[0], &c, 1) == 1)
1354 exit_pid = waitpid(-1, &exit_status, WNOHANG);
1358 fprintf(stderr,
"kdeinit4: PID %ld terminated.\n", (
long) exit_pid);
1360 if (waitForPid && (exit_pid == waitForPid))
1363 if( WIFEXITED( exit_status ))
1364 exit_status = WEXITSTATUS(exit_status);
1365 else if( WIFSIGNALED(exit_status))
1366 exit_status = 128 + WTERMSIG( exit_status );
1369 if (
d.wrapper < 0 && !children) {
1371 fprintf(stderr,
"kdeinit4: Last child terminated, exiting (PID %ld).\n",
1378 while( exit_pid > 0);
1384 if (
d.launcher[0] >= 0)
1385 FD_SET(
d.launcher[0], &rd_set);
1387 FD_SET(
d.wrapper, &rd_set);
1388 FD_SET(
d.deadpipe[0], &rd_set);
1393 result = select(max_sock, &rd_set, &wr_set, &e_set, 0);
1395 if (errno == EINTR || errno == EAGAIN)
1397 perror(
"kdeinit4: Aborting. select() failed");
1402 if (
d.wrapper >= 0 && FD_ISSET(
d.wrapper, &rd_set))
1404 struct sockaddr_un client;
1405 kde_socklen_t sClient =
sizeof(client);
1406 int sock = accept(
d.wrapper, (
struct sockaddr *)&client, &sClient);
1409 d.accepted_fd = sock;
1417 if (
d.launcher[0] >= 0 && FD_ISSET(
d.launcher[0], &rd_set))
1421 if (waitForPid ==
d.launcher_pid)
1429 XEvent event_return;
1441 QFile::decodeName(qgetenv(
"LTDL_LIBRARY_PATH")).split(QLatin1Char(
':'),QString::SkipEmptyParts);
1443 const QByteArray ldlibpath = qgetenv(
"DYLD_LIBRARY_PATH");
1445 const QByteArray ldlibpath = qgetenv(
"LD_LIBRARY_PATH");
1448 QFile::decodeName(ldlibpath).split(QLatin1Char(
':'),QString::SkipEmptyParts);
1450 QByteArray extra_path;
1452 for (QStringList::ConstIterator it = candidates.begin();
1453 it != candidates.end();
1457 if (ltdl_library_path.contains(d))
1459 if (ld_library_path.contains(d))
1461 if (d[d.length()-1] == QLatin1Char(
'/'))
1463 d.truncate(d.length()-1);
1464 if (ltdl_library_path.contains(d))
1466 if (ld_library_path.contains(d))
1469 if ((d == QLatin1String(
"/lib")) || (d == QLatin1String(
"/usr/lib")))
1472 QByteArray dir = QFile::encodeName(d);
1477 if ( !extra_path.isEmpty())
1485 QByteArray display = qgetenv(
DISPLAY);
1486 if (display.isEmpty())
1488 #if defined(Q_WS_X11) || defined(Q_WS_QWS)
1489 fprintf(stderr,
"kdeinit4: Aborting. $"DISPLAY" is not set.\n");
1494 if((i = display.lastIndexOf(
'.')) > display.lastIndexOf(
':') && i >= 0)
1495 display.truncate(i);
1497 display.replace(
':',
'_');
1499 display.replace(
'/',
'_');
1502 const QString socketFileName = QString::fromLatin1(
"kdeinit4_%1").arg(QLatin1String(display));
1506 fprintf(stderr,
"kdeinit4: Aborting. Socket name will be too long:\n");
1507 fprintf(stderr,
" '%s'\n", socketName.data());
1518 qWarning(
"kdeinit4: Fatal IO error: client killed" );
1530 kill(
d.launcher_pid, SIGTERM);
1532 kill(
d.kded_pid, SIGTERM);
1537 qWarning(
"kdeinit4: sending SIGHUP to children." );
1540 KDE_signal(SIGHUP, SIG_IGN);
1546 qWarning(
"kdeinit4: sending SIGTERM to children." );
1549 KDE_signal(SIGTERM, SIG_IGN);
1553 qWarning(
"kdeinit4: Exit." );
1565 XGetErrorText( dpy, err->error_code, errstr, 256 );
1566 fprintf(stderr,
"kdeinit4(%d) : KDE detected X Error: %s %d\n"
1567 " Major opcode: %d\n"
1568 " Minor opcode: %d\n"
1569 " Resource id: 0x%lx\n",
1570 getpid(), errstr, err->error_code, err->request_code, err->minor_code, err->resourceid );
1605 if( !qgetenv(
"XAUTHORITY" ).isEmpty()) {
1606 QByteArray display = qgetenv(
DISPLAY );
1608 if((i = display.lastIndexOf(
'.')) > display.lastIndexOf(
':') && i >= 0)
1609 display.truncate(i);
1610 display.replace(
':',
'_');
1612 display.replace(
'/',
'_');
1615 + QString::number( getuid()) + QLatin1String(
"-" ) + QString::fromLocal8Bit( display );
1617 QFile xauthfrom( QFile::decodeName( qgetenv(
"XAUTHORITY" )));
1618 if( !xauthfrom.open( QFile::ReadOnly ) || !xauthfile.
open( QFile::WriteOnly )
1619 || xauthfile.write( xauthfrom.readAll()) != xauthfrom.size() || !xauthfile.
finalize()) {
1622 setenv(
"XAUTHORITY", QFile::encodeName( xauth ),
true );
1634 BlackPixelOfScreen(DefaultScreenOfDisplay(
X11display)),
1635 BlackPixelOfScreen(DefaultScreenOfDisplay(
X11display)) );
1637 fprintf(stderr,
"kdeinit4: opened connection to %s\n", DisplayString(
X11display));
1641 (void) setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (
char *) &on, (int)
sizeof(on));
1644 fprintf(stderr,
"kdeinit4: Can not connect to the X Server.\n" \
1645 "kdeinit4: Might not terminate at end of session.\n");
1655 waitpid(-1, 0, WNOHANG);
1663 setlocale (LC_ALL,
"");
1664 setlocale (LC_NUMERIC,
"C");
1668 bool do_fork =
true;
1669 int launch_klauncher = 1;
1670 int launch_kded = 1;
1671 int keep_running = 1;
1675 char **safe_argv = (
char **) malloc(
sizeof(
char *) * argc);
1676 for(
int i = 0; i < argc; i++)
1678 safe_argv[i] = strcpy((
char*)malloc(strlen(argv[i])+1), argv[i]);
1679 if (strcmp(safe_argv[i],
"--no-klauncher") == 0)
1680 launch_klauncher = 0;
1681 if (strcmp(safe_argv[i],
"--no-kded") == 0)
1685 if (strcmp(safe_argv[i],
"--nofork") == 0)
1687 if (strcmp(safe_argv[i],
"--no-fork") == 0)
1690 if (strcmp(safe_argv[i],
"--suicide") == 0)
1692 if (strcmp(safe_argv[i],
"--exit") == 0)
1694 if (strcmp(safe_argv[i],
"--version") == 0)
1696 printf(
"Qt: %s\n", qVersion());
1700 #ifdef KDEINIT_OOM_PROTECT
1701 if (strcmp(safe_argv[i],
"--oom-pipe") == 0 && i+1<argc)
1702 oom_pipe = atol(argv[i+1]);
1704 if (strcmp(safe_argv[i],
"--help") == 0)
1706 printf(
"Usage: kdeinit4 [options]\n");
1709 printf(
" --nofork Do not fork\n");
1711 printf(
" --no-fork Do not fork\n");
1714 printf(
" --no-kded Do not start kded\n");
1715 printf(
" --suicide Terminate when no KDE applications are left running\n");
1716 printf(
" --version Show version information\n");
1732 if (pipe(
d.initpipe) != 0) {
1733 perror(
"kdeinit4: pipe failed");
1743 close(
d.initpipe[1]);
1747 while( read(
d.initpipe[0], &c, 1) < 0)
1750 close(
d.initpipe[0]);
1754 close(
d.initpipe[0]);
1767 #ifndef SKIP_PROCTITLE
1777 unsetenv(
"LD_BIND_NOW");
1778 unsetenv(
"DYLD_BIND_AT_LAUNCH");
1779 KApplication::loadedByKdeinit =
true;
1781 d.maxname = strlen(argv[0]);
1786 d.debug_wait =
false;
1787 d.launcher_ok =
false;
1803 if (!
d.suicide && qgetenv(
"KDE_IS_PRELINKED").isEmpty()) {
1805 for (
int i=0; i<extrasCount; i++) {
1810 if (!extra.isEmpty()) {
1812 l.setLoadHints(QLibrary::ExportExternalSymbolsHint);
1817 fprintf( stderr,
"%s was not found.\n",
extra_libs[i] );
1824 if (launch_klauncher)
1835 QFont::initialize();
1837 if (XSupportsLocale ())
1848 setenv(
"KDED_STARTED_BY_KDEINIT",
"1",
true);
1850 unsetenv(
"KDED_STARTED_BY_KDEINIT");
1852 fprintf(stderr,
"kdeinit4: Launched KDED, pid = %ld result = %d\n", (
long) pid,
d.result);
1858 for(
int i = 1; i < argc; i++)
1860 if (safe_argv[i][0] ==
'+')
1862 pid =
launch( 1, safe_argv[i]+1, 0);
1864 fprintf(stderr,
"kdeinit4: Launched '%s', pid = %ld result = %d\n", safe_argv[i]+1, (
long) pid,
d.result);
1868 else if (safe_argv[i][0] ==
'-'
1869 #ifdef KDEINIT_OOM_PROTECT
1878 pid =
launch( 1, safe_argv[i], 0 );
1880 fprintf(stderr,
"kdeinit4: Launched '%s', pid = %ld result = %d\n", safe_argv[i], (
long) pid,
d.result);
1886 for(
int i = 0; i < argc; i++)
1892 #ifndef SKIP_PROCTITLE
1899 if (
d.initpipe[1] != -1)
1902 write(
d.initpipe[1], &c, 1);
1903 close(
d.initpipe[1]);