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>
62 #include <kapplication.h>
69 #include <sys/prctl.h>
71 #define PR_SET_NAME 15
79 #include <kdeversion.h>
85 #include <X11/Xatom.h>
87 #include <kstartupinfo.h>
94 #ifdef __KDE_HAVE_GCC_VISIBILITY
111 #define MAX_SOCK_FILE 255
115 #define DISPLAY "DISPLAY"
116 #elif defined(Q_WS_QWS)
117 #define DISPLAY "QWS_DISPLAY"
118 #elif defined(Q_WS_MACX)
119 #define DISPLAY "MAC_DISPLAY"
120 #elif defined(Q_WS_WIN)
121 #define DISPLAY "WIN_DISPLAY"
123 #error Use QT/X11 or QT/Embedded
166 #ifdef KDEINIT_OOM_PROTECT
167 static int oom_pipe = -1;
179 int maxfd = FD_SETSIZE;
181 if (getrlimit(RLIMIT_NOFILE, &rl) == 0)
183 for (
int fd = 3;
fd < maxfd; ++
fd)
185 #ifdef KDEINIT_OOM_PROTECT
198 while (
struct child *child = children) {
200 children = child->next;
204 if (
d.deadpipe[0] != -1)
206 close(
d.deadpipe[0]);
210 if (
d.deadpipe[1] != -1)
212 close(
d.deadpipe[1]);
216 if (
d.initpipe[0] != -1)
218 close(
d.initpipe[0]);
222 if (
d.initpipe[1] != -1)
224 close(
d.initpipe[1]);
228 if (
d.launcher[0] != -1)
230 close(
d.launcher[0]);
238 if (
d.accepted_fd != -1)
240 close(
d.accepted_fd);
256 KDE_signal(SIGCHLD, SIG_DFL);
257 KDE_signal(SIGPIPE, SIG_DFL);
263 struct child *child, **childptr = &
children;
265 while ((child = *childptr))
267 if (child->pid == exit_pid)
271 long request_data[2];
274 request_data[0] = exit_pid;
276 write(child->sock, &request_header,
sizeof(request_header));
277 write(child->sock, request_data, request_header.
arg_length);
280 *childptr = child->next;
285 childptr = &child->next;
292 fprintf( stderr,
"%s\n", errorMsg.toLocal8Bit().data() );
293 QByteArray utf8ErrorMsg = errorMsg.toUtf8();
295 write(
d.fd[1], &
d.result, 1);
296 int l = utf8ErrorMsg.length();
297 write(
d.fd[1], &l,
sizeof(
int));
298 write(
d.fd[1], utf8ErrorMsg.data(), l);
305 if( tty == NULL || *tty ==
'\0' )
307 int fd = KDE_open( tty, O_WRONLY );
310 perror(
"kdeinit4: could not open() tty" );
313 if( dup2( fd, STDOUT_FILENO ) < 0 )
315 perror(
"kdeinit4: could not dup2() stdout tty" );
317 if( dup2( fd, STDERR_FILENO ) < 0 )
319 perror(
"kdeinit4: could not dup2() stderr tty" );
328 #ifdef Q_WS_X11 // Only X11 supports multiple desktops
329 Atom net_current_desktop = XInternAtom( disp,
"_NET_CURRENT_DESKTOP", False );
332 unsigned char *data_ret;
333 unsigned long nitems_ret, unused;
334 if( XGetWindowProperty( disp, DefaultRootWindow( disp ), net_current_desktop,
335 0l, 1l, False, XA_CARDINAL, &type_ret, &format_ret, &nitems_ret, &unused, &data_ret )
338 if (type_ret == XA_CARDINAL && format_ret == 32 && nitems_ret == 1)
339 desktop = *((
long *) data_ret) + 1;
341 XFree ((
char*) data_ret);
348 const char*
get_env_var(
const char* var,
int envc,
const char* envs )
352 const char* env_l = envs;
353 int ln = strlen( var );
354 for (
int i = 0; i < envc; i++)
356 if( strncmp( env_l, var, ln ) == 0 )
358 while(*env_l != 0) env_l++;
367 int envc,
const char* envs )
376 KStartupInfoData data;
378 data.setDesktop( desktop );
379 data.setBin(QFile::decodeName(bin));
392 KStartupInfoData data;
406 const QRegExp pathSepRegExp(QString::fromLatin1(
"[:\b]"));
409 const char* path =
get_env_var(
"PATH=", envc, envs );
411 paths = QFile::decodeName(path).split(pathSepRegExp);
413 paths = QString::fromLocal8Bit(qgetenv(
"PATH")).split(pathSepRegExp, QString::KeepEmptyParts);
416 s_instance->
dirs()->
findExe(QFile::decodeName(exec), paths.join(QLatin1String(
":")));
417 if (avoid_loops && !execpath.isEmpty()) {
418 const int pos = execpath.lastIndexOf(QLatin1Char(
'/'));
419 const QString bin_path = execpath.left(pos);
420 for( QStringList::Iterator it = paths.begin();
423 if( *it == bin_path || *it == bin_path + QLatin1Char(
'/')) {
428 execpath = s_instance->
dirs()->
findExe(QFile::decodeName(exec), paths.join(QLatin1String(
":")));
430 return QFile::encodeName(execpath);
433 #ifdef KDEINIT_OOM_PROTECT
434 static void oom_protect_sighandler(
int ) {
440 struct sigaction act, oldact;
441 act.sa_handler = oom_protect_sighandler;
443 sigemptyset( &act.sa_mask );
444 sigaction( SIGUSR1, &act, &oldact );
445 sigset_t sigs, oldsigs;
446 sigemptyset( &sigs );
447 sigaddset( &sigs, SIGUSR1 );
448 sigprocmask( SIG_BLOCK, &sigs, &oldsigs );
449 pid_t pid = getpid();
450 if( write( oom_pipe, &pid,
sizeof( pid_t )) > 0 ) {
451 sigsuspend( &oldsigs );
454 fprintf( stderr,
"Failed to reset OOM protection: %d\n", pid );
457 sigprocmask( SIG_SETMASK, &oldsigs, NULL );
458 sigaction( SIGUSR1, &oldact, NULL );
467 static pid_t
launch(
int argc,
const char *_name,
const char *args,
468 const char *cwd=0,
int envc=0,
const char *envs=0,
469 bool reset_env =
false,
470 const char *tty=0,
bool avoid_loops =
false,
471 const char* startup_id_str =
"0" )
479 if (_name[0] !=
'/') {
481 lib = QFile::decodeName(name);
483 KLibrary klib(QLatin1String(
"libkdeinit4_") + lib, *s_instance );
485 if( libpath.isEmpty()) {
492 lib = QFile::decodeName(name);
493 name = name.mid(name.lastIndexOf(
'/') + 1);
495 if (lib.endsWith(QLatin1String(
".so")))
500 if( lib.contains( QLatin1String(
"/lib" KDELIBSUFF
"/kde4/libexec/" ))) {
501 libpath =
QString( lib ).replace( QLatin1String(
"/lib" KDELIBSUFF
"/kde4/libexec/" ),
502 QLatin1String(
"/lib" KDELIBSUFF
"/libkdeinit4_")) + QLatin1String(
".so");
503 }
else if( lib.contains( QLatin1String(
"/bin/" ))) {
504 libpath =
QString( lib ).replace( QLatin1String(
"/bin/" ),
505 QLatin1String(
"/lib" KDELIBSUFF
"/libkdeinit4_")) + QLatin1String(
".so");
508 if (!QFile::exists(libpath)) {
515 fprintf(stderr,
"kdeinit4: preparing to launch %s\n", libpath.isEmpty()
516 ? execpath.constData() : libpath.toUtf8().constData());
524 perror(
"kdeinit4: pipe() failed");
526 d.errorMsg =
i18n(
"Unable to start new process.\n"
527 "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();
533 KStartupInfoId startup_id;
534 startup_id.initId( startup_id_str );
535 if( !startup_id.none())
548 perror(
"kdeinit4: fork() failed");
550 d.errorMsg =
i18n(
"Unable to create new process.\n"
551 "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 for(
int tmp_env_count = 0;
577 unset_envs.append(
environ[ tmp_env_count ] );
578 foreach(
const QByteArray &tmp, unset_envs)
580 int pos = tmp.indexOf(
'=' );
582 unsetenv( tmp.left( pos ));
586 for (
int i = 0; i < envc; i++)
588 putenv((
char *)envs);
589 while(*envs != 0) envs++;
594 if( startup_id.none())
595 KStartupInfo::resetStartupEnv();
597 startup_id.setupStartupEnv();
601 QByteArray procTitle;
602 d.argv = (
char **) malloc(
sizeof(
char *) * (argc+1));
603 d.argv[0] = (
char *) _name;
606 if (!argvexe.isEmpty()) {
607 QByteArray cstr = argvexe.toLocal8Bit();
608 kDebug(7016) <<
"kdeinit4: launch() setting argv: " << cstr.data();
609 d.argv[0] = strdup(cstr.data());
612 for (
int i = 1; i < argc; i++)
614 d.argv[i] = (
char *) args;
616 procTitle += (
char *) args;
617 while(*args != 0) args++;
622 #ifndef SKIP_PROCTITLE
626 r = prctl(
PR_SET_NAME, (
unsigned long) name.data(), 0, 0, 0);
628 proctitle_set(
"%s [kdeinit]%s", name.data(), procTitle.data() ? procTitle.data() :
"" );
630 proctitle_set(
"kdeinit4: %s%s", name.data(), procTitle.data() ? procTitle.data() :
"" );
632 proctitle_set(
"kdeinit4: %s%s", name.data(), procTitle.data() ? procTitle.data() :
"" );
637 if (libpath.isEmpty() && execpath.isEmpty())
644 if ( !qgetenv(
"KDE_IS_PRELINKED").isEmpty() && !execpath.isEmpty())
649 if ( !libpath.isEmpty() )
651 if (!l.load() || !l.isLoaded() )
653 QString ltdlError (l.errorString());
654 if (execpath.isEmpty())
663 fprintf(stderr,
"Could not open library %s: %s\n", qPrintable(lib),
664 qPrintable(ltdlError) );
671 write(
d.fd[1], &
d.result, 1);
675 fcntl(
d.fd[1], F_SETFD, FD_CLOEXEC);
679 QByteArray executable = execpath;
681 if (!bundlepath.isEmpty())
682 executable = QFile::encodeName(bundlepath);
685 if (!executable.isEmpty())
686 execvp(executable,
d.argv);
689 write(
d.fd[1], &
d.result, 1);
694 void * sym = l.resolve(
"kdeinitmain");
697 sym = l.resolve(
"kdemain" );
700 QString ltdlError = l.errorString();
701 fprintf(stderr,
"Could not find kdemain: %s\n", qPrintable(ltdlError) );
709 write(
d.fd[1], &
d.result, 1);
712 d.func = (int (*)(int,
char *[])) sym;
715 fprintf(stderr,
"kdeinit4: Suspending process\n"
716 "kdeinit4: 'gdb kdeinit4 %d' to debug\n"
717 "kdeinit4: 'kill -SIGCONT %d' to continue\n",
719 kill(getpid(), SIGSTOP);
726 exit(
d.func(argc,
d.argv));
736 d.n = read(
d.fd[0], &
d.result, 1);
750 d.n = read(
d.fd[0], &l,
sizeof(
int));
751 if (
d.n ==
sizeof(
int))
755 d.n = read(
d.fd[0], tmp.data(), l);
766 if (errno == ECHILD) {
769 if (errno == EINTR || errno == EAGAIN) {
778 fprintf(stderr,
"kdeinit4: (%s %s) Pipe closed unexpectedly", name.constData(), execpath.constData());
779 perror(
"kdeinit4: Pipe closed unexpectedly");
784 perror(
"kdeinit4: Error reading from pipe");
791 if( !startup_id.none())
793 if(
d.fork &&
d.result == 0 )
815 write(
d.deadpipe[1], &c, 1);
822 struct sigaction act;
825 if (pipe(
d.deadpipe) != 0)
827 perror(
"kdeinit4: Aborting. Can not create pipe");
831 options = fcntl(
d.deadpipe[0], F_GETFL);
834 perror(
"kdeinit4: Aborting. Can not make pipe non-blocking");
838 if (fcntl(
d.deadpipe[0], F_SETFL, options | O_NONBLOCK) == -1)
840 perror(
"kdeinit4: Aborting. Can not make pipe non-blocking");
850 sigemptyset(&(act.sa_mask));
851 sigaddset(&(act.sa_mask), SIGCHLD);
852 sigprocmask(SIG_UNBLOCK, &(act.sa_mask), 0L);
853 act.sa_flags = SA_NOCLDSTOP;
859 act.sa_flags |= SA_RESTART;
861 sigaction( SIGCHLD, &act, 0L);
863 act.sa_handler=SIG_IGN;
864 sigemptyset(&(act.sa_mask));
865 sigaddset(&(act.sa_mask), SIGPIPE);
866 sigprocmask(SIG_UNBLOCK, &(act.sa_mask), 0L);
868 sigaction( SIGPIPE, &act, 0L);
873 struct sockaddr_un sa;
874 kde_socklen_t socklen;
876 const QByteArray home_dir = qgetenv(
"HOME");
878 if (home_dir.isEmpty())
880 fprintf(stderr,
"kdeinit4: Aborting. $HOME not set!");
883 if (chdir(home_dir) != 0) {
884 fprintf(stderr,
"kdeinit4: Aborting. Couldn't enter '%s'!", home_dir.constData());
889 QByteArray path = home_dir;
890 QByteArray readOnly = qgetenv(
"KDE_HOME_READONLY");
891 if (
access(path.data(), R_OK|W_OK))
895 fprintf(stderr,
"kdeinit4: Aborting. $HOME directory (%s) does not exist.\n", path.data());
898 else if (readOnly.isEmpty())
900 fprintf(stderr,
"kdeinit4: Aborting. No write access to $HOME directory (%s).\n", path.data());
904 #if 0 // obsolete in kde4. Should we check writing to another file instead?
905 path = qgetenv(
"ICEAUTHORITY");
909 path +=
"/.ICEauthority";
911 if (
access(path.data(), R_OK|W_OK) && (errno != ENOENT))
913 fprintf(stderr,
"kdeinit4: Aborting. No write access to '%s'.\n", path.data());
926 struct sockaddr_un server;
932 s = socket(PF_UNIX, SOCK_STREAM, 0);
935 perror(
"socket() failed");
938 server.sun_family = AF_UNIX;
940 socklen =
sizeof(server);
942 if(connect(s, (
struct sockaddr *)&server, socklen) == 0)
944 fprintf(stderr,
"kdeinit4: Shutting down running client.\n");
948 write(s, &request_header,
sizeof(request_header));
958 d.wrapper = socket(PF_UNIX, SOCK_STREAM, 0);
961 perror(
"kdeinit4: Aborting. socket() failed");
965 options = fcntl(
d.wrapper, F_GETFL);
968 perror(
"kdeinit4: Aborting. Can not make socket non-blocking");
973 if (fcntl(
d.wrapper, F_SETFL, options | O_NONBLOCK) == -1)
975 perror(
"kdeinit4: Aborting. Can not make socket non-blocking");
982 socklen =
sizeof(sa);
983 memset(&sa, 0, socklen);
984 sa.sun_family = AF_UNIX;
986 if(bind(
d.wrapper, (
struct sockaddr *)&sa, socklen) != 0)
988 if (max_tries == 0) {
989 perror(
"kdeinit4: Aborting. bind() failed");
990 fprintf(stderr,
"Could not bind to socket '%s'\n",
sock_file);
1002 perror(
"kdeinit4: Aborting. Can not set permissions on socket");
1003 fprintf(stderr,
"Wrong permissions of socket '%s'\n",
sock_file);
1009 if(
listen(
d.wrapper, SOMAXCONN) < 0)
1011 perror(
"kdeinit4: Aborting. listen() failed");
1025 int bytes_left = len;
1026 while ( bytes_left > 0)
1028 result = read(sock, buffer, bytes_left);
1034 else if (result == 0)
1036 else if ((result == -1) && (errno != EINTR) && (errno != EAGAIN))
1044 if (socketpair(AF_UNIX, SOCK_STREAM, 0,
d.launcher) < 0) {
1045 perror(
"kdeinit4: socketpair() failed");
1049 strcpy(args,
"--fd=");
1050 sprintf(args + 5,
"%d",
d.launcher[1]);
1051 d.launcher_pid =
launch( 2,
"klauncher", args );
1052 close(
d.launcher[1]);
1054 fprintf(stderr,
"kdeinit4: Launched KLauncher, pid = %ld, result = %d\n",
1055 (
long)
d.launcher_pid,
d.result);
1064 fprintf(stderr,
"kdeinit4: Communication error with launcher. Exiting!\n");
1071 fprintf(stderr,
"kdeinit4: KLauncher died unexpectedly.\n");
1076 kill(
d.launcher_pid, SIGKILL);
1080 d.launcher_ok =
false;
1082 close(
d.launcher[0]);
1093 char *request_data = 0L;
1094 int result =
read_socket(sock, (
char *) &request_header,
sizeof(request_header));
1102 request_data = (
char *) malloc(request_header.
arg_length);
1115 d.launcher_ok =
true;
1128 memcpy( &l, request_data,
sizeof(
long ));
1130 const char *name = request_data +
sizeof(long);
1131 const char *args = name + strlen(name) + 1;
1132 const char *cwd = 0;
1134 const char *envs = 0;
1135 const char *tty = 0;
1136 int avoid_loops = 0;
1137 const char *startup_id_str =
"0";
1140 fprintf(stderr,
"kdeinit4: Got %s '%s' from %s.\n",
1145 const char *arg_n = args;
1146 for(
int i = 1; i < argc; i++)
1148 arg_n = arg_n + strlen(arg_n) + 1;
1154 cwd = arg_n; arg_n += strlen(cwd) + 1;
1159 memcpy( &l, arg_n,
sizeof(
long ));
1161 arg_n +=
sizeof(long);
1163 for(
int i = 0; i < envc; i++)
1165 arg_n = arg_n + strlen(arg_n) + 1;
1170 arg_n += strlen( tty ) + 1;
1177 memcpy( &l, arg_n,
sizeof(
long ));
1179 arg_n +=
sizeof( long );
1185 startup_id_str = arg_n;
1186 arg_n += strlen( startup_id_str ) + 1;
1189 if ((request_header.
arg_length > (arg_n - request_data)) &&
1193 cwd = arg_n; arg_n += strlen(cwd) + 1;
1196 if ((arg_n - request_data) != request_header.
arg_length)
1199 fprintf(stderr,
"kdeinit4: EXEC request has invalid format.\n");
1202 d.debug_wait =
false;
1207 QByteArray olddisplay = qgetenv(
DISPLAY);
1208 QByteArray kdedisplay = qgetenv(
"KDE_DISPLAY");
1209 bool reset_display = (! olddisplay.isEmpty() &&
1210 ! kdedisplay.isEmpty() &&
1211 olddisplay != kdedisplay);
1214 setenv(
DISPLAY, kdedisplay,
true);
1216 pid =
launch( argc, name, args, cwd, envc, envs,
1218 tty, avoid_loops, startup_id_str );
1220 if (reset_display) {
1221 unsetenv(
"KDE_DISPLAY");
1222 setenv(
DISPLAY, olddisplay,
true);
1225 if (pid && (
d.result == 0))
1228 response_header.
arg_length =
sizeof(response_data);
1229 response_data = pid;
1230 write(sock, &response_header,
sizeof(response_header));
1231 write(sock, &response_data, response_header.
arg_length);
1234 struct child *child = (
struct child *) malloc(
sizeof(
struct child));
1236 child->sock = dup(sock);
1242 int l =
d.errorMsg.length();
1246 write(sock, &response_header,
sizeof(response_header));
1248 write(sock,
d.errorMsg.data(), l);
1250 d.debug_wait =
false;
1254 const char *env_name;
1255 const char *env_value;
1256 env_name = request_data;
1257 env_value = env_name + strlen(env_name) + 1;
1260 fprintf(stderr,
"kdeinit4: Got SETENV '%s=%s' from %s.\n", env_name, env_value, who);
1264 (
int) (strlen(env_name) + strlen(env_value) + 2))
1267 fprintf(stderr,
"kdeinit4: SETENV request has invalid format.\n");
1272 setenv( env_name, env_value, 1);
1277 fprintf(stderr,
"kdeinit4: terminate KDE.\n");
1286 fprintf(stderr,
"kdeinit4: Got termination request (PID %ld).\n", (
long) getpid());
1288 if (
d.launcher_pid) {
1289 kill(
d.launcher_pid, SIGTERM);
1291 close(
d.launcher[0]);
1299 fprintf(stderr,
"kdeinit4: Closed sockets, but not exiting until all children terminate.\n");
1308 fprintf(stderr,
"kdeinit4: Debug wait activated.\n");
1310 d.debug_wait =
true;
1319 int max_sock =
d.deadpipe[0];
1320 if (
d.wrapper > max_sock)
1321 max_sock =
d.wrapper;
1322 if (
d.launcher[0] > max_sock)
1323 max_sock =
d.launcher[0];
1325 if (
X11fd > max_sock)
1341 while( read(
d.deadpipe[0], &c, 1) == 1)
1346 exit_pid = waitpid(-1, &exit_status, WNOHANG);
1350 fprintf(stderr,
"kdeinit4: PID %ld terminated.\n", (
long) exit_pid);
1352 if (waitForPid && (exit_pid == waitForPid))
1355 if( WIFEXITED( exit_status ))
1356 exit_status = WEXITSTATUS(exit_status);
1357 else if( WIFSIGNALED(exit_status))
1358 exit_status = 128 + WTERMSIG( exit_status );
1361 if (
d.wrapper < 0 && !children) {
1363 fprintf(stderr,
"kdeinit4: Last child terminated, exiting (PID %ld).\n",
1370 while( exit_pid > 0);
1376 if (
d.launcher[0] >= 0)
1377 FD_SET(
d.launcher[0], &rd_set);
1379 FD_SET(
d.wrapper, &rd_set);
1380 FD_SET(
d.deadpipe[0], &rd_set);
1385 result = select(max_sock, &rd_set, &wr_set, &e_set, 0);
1387 if (errno == EINTR || errno == EAGAIN)
1389 perror(
"kdeinit4: Aborting. select() failed");
1394 if (
d.wrapper >= 0 && FD_ISSET(
d.wrapper, &rd_set))
1396 struct sockaddr_un client;
1397 kde_socklen_t sClient =
sizeof(client);
1398 int sock = accept(
d.wrapper, (
struct sockaddr *)&client, &sClient);
1401 d.accepted_fd = sock;
1409 if (
d.launcher[0] >= 0 && FD_ISSET(
d.launcher[0], &rd_set))
1413 if (waitForPid ==
d.launcher_pid)
1421 XEvent event_return;
1433 QFile::decodeName(qgetenv(
"LTDL_LIBRARY_PATH")).split(QLatin1Char(
':'),QString::SkipEmptyParts);
1435 const QByteArray ldlibpath = qgetenv(
"DYLD_LIBRARY_PATH");
1437 const QByteArray ldlibpath = qgetenv(
"LD_LIBRARY_PATH");
1440 QFile::decodeName(ldlibpath).split(QLatin1Char(
':'),QString::SkipEmptyParts);
1442 QByteArray extra_path;
1444 for (QStringList::ConstIterator it = candidates.begin();
1445 it != candidates.end();
1449 if (ltdl_library_path.contains(d))
1451 if (ld_library_path.contains(d))
1453 if (d[d.length()-1] == QLatin1Char(
'/'))
1455 d.truncate(d.length()-1);
1456 if (ltdl_library_path.contains(d))
1458 if (ld_library_path.contains(d))
1461 if ((d == QLatin1String(
"/lib")) || (d == QLatin1String(
"/usr/lib")))
1464 QByteArray dir = QFile::encodeName(d);
1469 if ( !extra_path.isEmpty())
1477 QByteArray display = qgetenv(
DISPLAY);
1478 if (display.isEmpty())
1480 #if defined(Q_WS_X11) || defined(Q_WS_QWS)
1481 fprintf(stderr,
"kdeinit4: Aborting. $"DISPLAY" is not set.\n");
1486 if((i = display.lastIndexOf(
'.')) > display.lastIndexOf(
':') && i >= 0)
1487 display.truncate(i);
1489 display.replace(
':',
'_');
1491 display.replace(
'/',
'_');
1494 const QString socketFileName = QString::fromLatin1(
"kdeinit4_%1").arg(QLatin1String(display));
1498 fprintf(stderr,
"kdeinit4: Aborting. Socket name will be too long:\n");
1499 fprintf(stderr,
" '%s'\n", socketName.data());
1510 qWarning(
"kdeinit4: Fatal IO error: client killed" );
1522 kill(
d.launcher_pid, SIGTERM);
1524 kill(
d.kded_pid, SIGTERM);
1529 qWarning(
"kdeinit4: sending SIGHUP to children." );
1532 KDE_signal(SIGHUP, SIG_IGN);
1538 qWarning(
"kdeinit4: sending SIGTERM to children." );
1541 KDE_signal(SIGTERM, SIG_IGN);
1545 qWarning(
"kdeinit4: Exit." );
1557 XGetErrorText( dpy, err->error_code, errstr, 256 );
1558 fprintf(stderr,
"kdeinit4(%d) : KDE detected X Error: %s %d\n"
1559 " Major opcode: %d\n"
1560 " Minor opcode: %d\n"
1561 " Resource id: 0x%lx\n",
1562 getpid(), errstr, err->error_code, err->request_code, err->minor_code, err->resourceid );
1597 if( !qgetenv(
"XAUTHORITY" ).isEmpty()) {
1598 QByteArray display = qgetenv(
DISPLAY );
1600 if((i = display.lastIndexOf(
'.')) > display.lastIndexOf(
':') && i >= 0)
1601 display.truncate(i);
1602 display.replace(
':',
'_');
1604 display.replace(
'/',
'_');
1607 + QString::number( getuid()) + QLatin1String(
"-" ) + QString::fromLocal8Bit( display );
1609 QFile xauthfrom( QFile::decodeName( qgetenv(
"XAUTHORITY" )));
1610 if( !xauthfrom.open( QFile::ReadOnly ) || !xauthfile.
open( QFile::WriteOnly )
1611 || xauthfile.write( xauthfrom.readAll()) != xauthfrom.size() || !xauthfile.
finalize()) {
1614 setenv(
"XAUTHORITY", QFile::encodeName( xauth ),
true );
1626 BlackPixelOfScreen(DefaultScreenOfDisplay(
X11display)),
1627 BlackPixelOfScreen(DefaultScreenOfDisplay(
X11display)) );
1629 fprintf(stderr,
"kdeinit4: opened connection to %s\n", DisplayString(
X11display));
1633 (void) setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (
char *) &on, (int)
sizeof(on));
1636 fprintf(stderr,
"kdeinit4: Can not connect to the X Server.\n" \
1637 "kdeinit4: Might not terminate at end of session.\n");
1647 waitpid(-1, 0, WNOHANG);
1655 setlocale (LC_ALL,
"");
1656 setlocale (LC_NUMERIC,
"C");
1660 bool do_fork =
true;
1661 int launch_klauncher = 1;
1662 int launch_kded = 1;
1663 int keep_running = 1;
1667 char **safe_argv = (
char **) malloc(
sizeof(
char *) * argc);
1668 for(
int i = 0; i < argc; i++)
1670 safe_argv[i] = strcpy((
char*)malloc(strlen(argv[i])+1), argv[i]);
1671 if (strcmp(safe_argv[i],
"--no-klauncher") == 0)
1672 launch_klauncher = 0;
1673 if (strcmp(safe_argv[i],
"--no-kded") == 0)
1677 if (strcmp(safe_argv[i],
"--nofork") == 0)
1679 if (strcmp(safe_argv[i],
"--no-fork") == 0)
1682 if (strcmp(safe_argv[i],
"--suicide") == 0)
1684 if (strcmp(safe_argv[i],
"--exit") == 0)
1686 if (strcmp(safe_argv[i],
"--version") == 0)
1688 printf(
"Qt: %s\n", qVersion());
1692 #ifdef KDEINIT_OOM_PROTECT
1693 if (strcmp(safe_argv[i],
"--oom-pipe") == 0 && i+1<argc)
1694 oom_pipe = atol(argv[i+1]);
1696 if (strcmp(safe_argv[i],
"--help") == 0)
1698 printf(
"Usage: kdeinit4 [options]\n");
1701 printf(
" --nofork Do not fork\n");
1703 printf(
" --no-fork Do not fork\n");
1706 printf(
" --no-kded Do not start kded\n");
1707 printf(
" --suicide Terminate when no KDE applications are left running\n");
1708 printf(
" --version Show version information\n");
1724 if (pipe(
d.initpipe) != 0) {
1725 perror(
"kdeinit4: pipe failed");
1735 close(
d.initpipe[1]);
1739 while( read(
d.initpipe[0], &c, 1) < 0)
1742 close(
d.initpipe[0]);
1746 close(
d.initpipe[0]);
1759 #ifndef SKIP_PROCTITLE
1769 unsetenv(
"LD_BIND_NOW");
1770 unsetenv(
"DYLD_BIND_AT_LAUNCH");
1771 KApplication::loadedByKdeinit =
true;
1773 d.maxname = strlen(argv[0]);
1778 d.debug_wait =
false;
1779 d.launcher_ok =
false;
1795 if (!
d.suicide && qgetenv(
"KDE_IS_PRELINKED").isEmpty()) {
1797 for (
int i=0; i<extrasCount; i++) {
1802 if (!extra.isEmpty()) {
1804 l.setLoadHints(QLibrary::ExportExternalSymbolsHint);
1809 fprintf( stderr,
"%s was not found.\n",
extra_libs[i] );
1816 if (launch_klauncher)
1827 QFont::initialize();
1829 if (XSupportsLocale ())
1840 setenv(
"KDED_STARTED_BY_KDEINIT",
"1",
true);
1842 unsetenv(
"KDED_STARTED_BY_KDEINIT");
1844 fprintf(stderr,
"kdeinit4: Launched KDED, pid = %ld result = %d\n", (
long) pid,
d.result);
1850 for(
int i = 1; i < argc; i++)
1852 if (safe_argv[i][0] ==
'+')
1854 pid =
launch( 1, safe_argv[i]+1, 0);
1856 fprintf(stderr,
"kdeinit4: Launched '%s', pid = %ld result = %d\n", safe_argv[i]+1, (
long) pid,
d.result);
1860 else if (safe_argv[i][0] ==
'-'
1861 #ifdef KDEINIT_OOM_PROTECT
1870 pid =
launch( 1, safe_argv[i], 0 );
1872 fprintf(stderr,
"kdeinit4: Launched '%s', pid = %ld result = %d\n", safe_argv[i], (
long) pid,
d.result);
1878 for(
int i = 0; i < argc; i++)
1884 #ifndef SKIP_PROCTITLE
1891 if (
d.initpipe[1] != -1)
1894 write(
d.initpipe[1], &c, 1);
1895 close(
d.initpipe[1]);
QString saveLocation(const char *type, const QString &suffix=QString(), bool create=true) const
QString i18n(const char *text)
static void reset_oom_protect()
static void secondary_child_handler(int)
#define LAUNCHER_EXT_EXEC
QDebug perror(QDebug s, KDebugTag)
const char * get_env_var(const char *var, int envc, const char *envs)
static bool handle_launcher_request(int sock, const char *who)
static void init_kdeinit_socket()
static void exitWithErrorMsg(const QString &errorMsg)
static QString locate(const char *type, const QString &filename, const KComponentData &cData=KGlobal::mainComponent())
virtual bool open(OpenMode flags=QIODevice::ReadWrite)
static void init_signals()
int chmod(const QString &path, mode_t mode)
QTcpServer * listen(const QString &protocol, const QHostAddress &address=QHostAddress::Any, quint16 port=0, QObject *parent=0)
static QDebug kDebug(bool cond, int area=KDE_DEFAULT_DEBUG_AREA)
#define KDE_VERSION_STRING
void mac_fork_and_reexec_self()
static pid_t launch(int argc, const char *_name, const char *args, const char *cwd=0, int envc=0, const char *envs=0, bool reset_env=false, const char *tty=0, bool avoid_loops=false, const char *startup_id_str="0")
static void start_klauncher()
void proctitle_init(int argc, char *argv[], char *envp[])
Set up the memory space for setting the proctitle.
static void child_died(pid_t exit_pid, int exit_status)
static void handle_requests(pid_t waitForPid)
#define LAUNCHER_EXEC_NEW
#define LAUNCHER_DEBUG_WAIT
static void kdeinit_library_path()
void proctitle_set(const char *fmt,...)
Change the process title.
int main(int argc, char **argv, char **envp)
const char * commandToString(int command)
#define LAUNCHER_CHILD_DIED
static Display * X11_startup_notify_display
#define LAUNCHER_TERMINATE_KDEINIT
static void setup_tty(const char *tty)
QByteArray execpath_avoid_loops(const QByteArray &exec, int envc, const char *envs, bool avoid_loops)
static const char * extra_libs[]
static KComponentData * s_instance
static void cleanup_fds()
static char sock_file[MAX_SOCK_FILE]
#define LAUNCHER_KWRAPPER
QStringList resourceDirs(const char *type) const
static void init_startup_info(KStartupInfoId &id, const char *bin, int envc, const char *envs)
static void launcher_died()
static Display * X11display
static int initXconnection()
static void complete_startup_info(KStartupInfoId &id, pid_t pid)
int(* func)(int, char *[])
static QString locateLocal(const char *type, const QString &filename, const KComponentData &cData=KGlobal::mainComponent())
int access(const QString &path, int mode)
static int read_socket(int sock, char *buffer, int len)
static QString findExe(const QString &appname, const QString &pathstr=QString(), SearchOptions options=NoSearchOptions)
static int get_current_desktop(Display *disp)
#define LAUNCHER_TERMINATE_KDE
int(* launcher_func)(int)
int kdeinit_xio_errhandler(Display *)
static int X11_startup_notify_fd
int kdeinit_x_errhandler(Display *, XErrorEvent *err)
static void sig_child_handler(int)
static struct child * children
KStandardDirs * dirs() const