static void InstallIOErrorHandler(void) { IceIOErrorHandler default_handler; prev_handler = IceSetIOErrorHandler (NULL); default_handler = IceSetIOErrorHandler (MyIoErrorHandler); if (prev_handler == default_handler) prev_handler = NULL; }
/* We call any handler installed before (or after) iceInit but avoid calling the default libICE handler which does an exit() */ static void iceInit(void) { static Bool iceInitialized = 0; if (!iceInitialized) { IceIOErrorHandler defaultIceHandler; oldIceHandler = IceSetIOErrorHandler(NULL); defaultIceHandler = IceSetIOErrorHandler(iceErrorHandler); if (oldIceHandler == defaultIceHandler) oldIceHandler = NULL; IceAddConnectionWatch(iceNewConnection, NULL); iceInitialized = 1; } }
static void ice_init (void) { static gboolean ice_initted = FALSE; if (! ice_initted) { IceIOErrorHandler default_handler; ice_installed_handler = IceSetIOErrorHandler (NULL); default_handler = IceSetIOErrorHandler (ice_io_error_handler); if (ice_installed_handler == default_handler) ice_installed_handler = NULL; IceAddConnectionWatch (new_ice_connection, NULL); ice_initted = TRUE; } }
static void ice_init(void) { static bool initted = false; if (!initted) { IceSetIOErrorHandler(ice_io_error_handler); IceAddConnectionWatch(ice_connection_watch, nullptr); initted = true; } }
void doInstallIOErrorHandler (void) { IceIOErrorHandler default_handler; prev_handler = IceSetIOErrorHandler (NULL); default_handler = IceSetIOErrorHandler (MyIoErrorHandler); if (prev_handler == default_handler) prev_handler = NULL; #ifdef X_NOT_POSIX signal(SIGPIPE, SIG_IGN); #else { struct sigaction act; (void) sigemptyset(&act.sa_mask); act.sa_flags = 0; act.sa_handler = SIG_IGN; (void) sigaction(SIGPIPE, &act, NULL); } #endif }
void x_session_initialize (struct x_display_info *dpyinfo) { #define SM_ERRORSTRING_LEN 512 char errorstring[SM_ERRORSTRING_LEN]; char *previous_id = NULL; SmcCallbacks callbacks; ptrdiff_t name_len = 0; /* libSM seems to crash if pwd is missing - see bug#18851. */ if (! get_current_dir_name ()) { fprintf (stderr, "Disabling session management due to pwd error: %s\n", emacs_strerror (errno)); return; } ice_fd = -1; doing_interact = false; /* Check if we where started by the session manager. If so, we will have a previous id. */ if (STRINGP (Vx_session_previous_id)) previous_id = SSDATA (Vx_session_previous_id); /* Construct the path to the Emacs program. */ if (STRINGP (Vinvocation_directory)) name_len += SBYTES (Vinvocation_directory); if (STRINGP (Vinvocation_name)) name_len += SBYTES (Vinvocation_name); /* This malloc will not be freed, but it is only done once, and hopefully not very large */ emacs_program = xmalloc (name_len + 1); char *z = emacs_program; if (STRINGP (Vinvocation_directory)) z = lispstpcpy (z, Vinvocation_directory); if (STRINGP (Vinvocation_name)) lispstpcpy (z, Vinvocation_name); /* The SM protocol says all callbacks are mandatory, so set up all here and in the mask passed to SmcOpenConnection. */ callbacks.save_yourself.callback = smc_save_yourself_CB; callbacks.save_yourself.client_data = 0; callbacks.die.callback = smc_die_CB; callbacks.die.client_data = 0; callbacks.save_complete.callback = smc_save_complete_CB; callbacks.save_complete.client_data = 0; callbacks.shutdown_cancelled.callback = smc_shutdown_cancelled_CB; callbacks.shutdown_cancelled.client_data = 0; /* Set error handlers. */ SmcSetErrorHandler (smc_error_handler); IceSetErrorHandler (ice_error_handler); IceSetIOErrorHandler (ice_io_error_handler); /* Install callback for when connection status changes. */ IceAddConnectionWatch (ice_conn_watch_CB, 0); /* Open the connection to the session manager. A failure is not critical, it usually means that no session manager is running. The errorstring is here for debugging. */ smc_conn = SmcOpenConnection (NULL, NULL, 1, 0, (SmcSaveYourselfProcMask| SmcDieProcMask| SmcSaveCompleteProcMask| SmcShutdownCancelledProcMask), &callbacks, previous_id, &client_id, SM_ERRORSTRING_LEN, errorstring); if (smc_conn != 0) { Vx_session_id = build_string (client_id); #ifdef USE_GTK /* GTK creates a leader window by itself, but we need to tell it about our client_id. */ gdk_x11_set_sm_client_id (client_id); #else create_client_leader_window (dpyinfo, client_id); #endif } }
void x_session_initialize (struct x_display_info *dpyinfo) { #define SM_ERRORSTRING_LEN 512 char errorstring[SM_ERRORSTRING_LEN]; char* previous_id = NULL; SmcCallbacks callbacks; int name_len = 0; ice_fd = -1; doing_interact = False; /* Check if we where started by the session manager. If so, we will have a previous id. */ if (! EQ (Vx_session_previous_id, Qnil) && STRINGP (Vx_session_previous_id)) previous_id = SSDATA (Vx_session_previous_id); /* Construct the path to the Emacs program. */ if (! EQ (Vinvocation_directory, Qnil)) name_len += strlen (SSDATA (Vinvocation_directory)); name_len += strlen (SSDATA (Vinvocation_name)); /* This malloc will not be freed, but it is only done once, and hopefully not very large */ emacs_program = xmalloc (name_len + 1); emacs_program[0] = '\0'; if (! EQ (Vinvocation_directory, Qnil)) strcpy (emacs_program, SSDATA (Vinvocation_directory)); strcat (emacs_program, SSDATA (Vinvocation_name)); /* The SM protocol says all callbacks are mandatory, so set up all here and in the mask passed to SmcOpenConnection. */ callbacks.save_yourself.callback = smc_save_yourself_CB; callbacks.save_yourself.client_data = 0; callbacks.die.callback = smc_die_CB; callbacks.die.client_data = 0; callbacks.save_complete.callback = smc_save_complete_CB; callbacks.save_complete.client_data = 0; callbacks.shutdown_cancelled.callback = smc_shutdown_cancelled_CB; callbacks.shutdown_cancelled.client_data = 0; /* Set error handlers. */ SmcSetErrorHandler (smc_error_handler); IceSetErrorHandler (ice_error_handler); IceSetIOErrorHandler (ice_io_error_handler); /* Install callback for when connection status changes. */ IceAddConnectionWatch (ice_conn_watch_CB, 0); /* Open the connection to the session manager. A failure is not critical, it usually means that no session manager is running. The errorstring is here for debugging. */ smc_conn = SmcOpenConnection (NULL, NULL, 1, 0, (SmcSaveYourselfProcMask| SmcDieProcMask| SmcSaveCompleteProcMask| SmcShutdownCancelledProcMask), &callbacks, previous_id, &client_id, SM_ERRORSTRING_LEN, errorstring); if (smc_conn != 0) { Vx_session_id = make_string (client_id, strlen (client_id)); #ifdef USE_GTK /* GTK creats a leader window by itself, but we need to tell it about our client_id. */ gdk_set_sm_client_id (client_id); #else create_client_leader_window (dpyinfo, client_id); #endif } }
gboolean ice_setup_listeners (int num_listeners, IceListenObj *listen_objs, XfsmManager *manager) { GIOChannel *channel; char *auth_setup_file; gchar *command; FILE *cleanup_fp; FILE *setup_fp; int fd; int n; IceSetIOErrorHandler (ice_error_handler); IceAddConnectionWatch (ice_connection_watch, manager); cleanup_fp = ice_tmpfile(&auth_cleanup_file); if (cleanup_fp == NULL) return FALSE; setup_fp = ice_tmpfile(&auth_setup_file); if (setup_fp == NULL) { fclose (cleanup_fp); unlink (auth_cleanup_file); g_free (auth_cleanup_file); return FALSE; } for (n = 0; n < num_listeners; n++) { fd = IceGetListenConnectionNumber (listen_objs[n]); /* Make sure we don't pass on these file descriptors to an * exec'd child process. */ fcntl (fd, F_SETFD, fcntl (fd, F_GETFD, 0) | FD_CLOEXEC); channel = g_io_channel_unix_new (fd); g_io_add_watch (channel, G_IO_ERR | G_IO_HUP | G_IO_IN, ice_connection_accept, listen_objs[n]); g_io_channel_unref (channel); /* setup auth for this listener */ ice_auth_add (setup_fp, cleanup_fp, "ICE", listen_objs[n]); ice_auth_add (setup_fp, cleanup_fp, "XSMP", listen_objs[n]); IceSetHostBasedAuthProc (listen_objs[n], ice_auth_proc); } fclose (setup_fp); fclose (cleanup_fp); /* setup ICE authority and remove setup file */ command = g_strdup_printf ("%s source %s", ICEAUTH_CMD, auth_setup_file); if (system (command) != 0) { g_warning ("Failed to setup the ICE authentication data, session " "management might not work properly."); } g_free (command); unlink (auth_setup_file); g_free (auth_setup_file); return TRUE; }
extern "C" Q_DECL_EXPORT int kdemain( int argc, char* argv[] ) { sanity_check(argc, argv); putenv((char*)"SESSION_MANAGER="); checkComposite(); QApplication *a = new QApplication(argc, argv); QApplication::setApplicationName( QStringLiteral( "ksmserver") ); QApplication::setApplicationVersion( QString::fromLatin1( version ) ); QApplication::setOrganizationDomain( QStringLiteral( "kde.org") ); fcntl(ConnectionNumber(QX11Info::display()), F_SETFD, 1); a->setQuitOnLastWindowClosed(false); // #169486 QCommandLineParser parser; parser.setApplicationDescription(QString::fromLatin1(description)); parser.addHelpOption(); parser.addVersionOption(); QCommandLineOption restoreOption(QStringList() << QStringLiteral("r") << QStringLiteral("restore"), i18n("Restores the saved user session if available")); parser.addOption(restoreOption); QCommandLineOption wmOption(QStringList() << QStringLiteral("w") << QStringLiteral("windowmanager"), i18n("Starts <wm> in case no other window manager is \nparticipating in the session. Default is 'kwin'"), i18n("wm")); parser.addOption(wmOption); QCommandLineOption nolocalOption(QStringLiteral("nolocal"), i18n("Also allow remote connections")); parser.addOption(nolocalOption); #if COMPILE_SCREEN_LOCKER QCommandLineOption lockscreenOption(QStringLiteral("lockscreen"), i18n("Starts the session in locked mode")); parser.addOption(lockscreenOption); #endif parser.process(*a); //TODO: should we still use this? // if( !QDBusConnection::sessionBus().interface()-> // registerService( QStringLiteral( "org.kde.ksmserver" ), // QDBusConnectionInterface::DontQueueService ) ) // { // qWarning("Could not register with D-BUS. Aborting."); // return 1; // } QString wm = parser.value(wmOption); bool only_local = !parser.isSet(nolocalOption); #ifndef HAVE__ICETRANSNOLISTEN /* this seems strange, but the default is only_local, so if !only_local * the option --nolocal was given, and we warn (the option --nolocal * does nothing on this platform, as here the default is reversed) */ if (!only_local) { qWarning("--nolocal is not supported on your platform. Sorry."); } only_local = false; #endif #if COMPILE_SCREEN_LOCKER KSMServer *server = new KSMServer( wm, only_local, parser.isSet(lockscreenOption ) ); #else KSMServer *server = new KSMServer( wm, only_local ); #endif // for the KDE-already-running check in startkde KSelectionOwner kde_running( "_KDE_RUNNING", 0 ); kde_running.claim( false ); IceSetIOErrorHandler( IoErrorHandler ); KConfigGroup config(KSharedConfig::openConfig(), "General"); int realScreenCount = ScreenCount( QX11Info::display() ); bool screenCountChanged = ( config.readEntry( "screenCount", realScreenCount ) != realScreenCount ); QString loginMode = config.readEntry( "loginMode", "restorePreviousLogout" ); if ( parser.isSet( restoreOption ) && ! screenCountChanged ) server->restoreSession( QStringLiteral( SESSION_BY_USER ) ); else if ( loginMode == QStringLiteral( "default" ) || screenCountChanged ) server->startDefaultSession(); else if ( loginMode == QStringLiteral( "restorePreviousLogout" ) ) server->restoreSession( QStringLiteral( SESSION_PREVIOUS_LOGOUT ) ); else if ( loginMode == QStringLiteral( "restoreSavedSession" ) ) server->restoreSession( QStringLiteral( SESSION_BY_USER ) ); else server->startDefaultSession(); KDBusService service(KDBusService::Unique); int ret = a->exec(); kde_running.release(); // needs to be done before QApplication destruction delete a; return ret; }
static void ice_init(void) { static SmPointer context; SmcCallbacks callbacks; char error_string_ret[4096]; char *client_id; char style[2]; SmPropValue styleVal; SmProp styleProp; SmProp *props[1]; int sm_fd; if (!getenv("SESSION_MANAGER")) return; IceSetIOErrorHandler(ice_io_error_handler); callbacks.save_yourself.callback = callback_save_yourself; callbacks.die.callback = callback_die; callbacks.save_complete.callback = callback_save_complete; callbacks.shutdown_cancelled.callback = callback_shutdown_cancelled; callbacks.save_yourself.client_data = callbacks.die.client_data = callbacks.save_complete.client_data = callbacks.shutdown_cancelled.client_data = (SmPointer) NULL; client_id = Estrdup(sm_client_id); error_string_ret[0] = '\0'; sm_conn = SmcOpenConnection(NULL, &context, SmProtoMajor, SmProtoMinor, SmcSaveYourselfProcMask | SmcDieProcMask | SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask, &callbacks, client_id, &sm_client_id, 4096, error_string_ret); Efree(client_id); if (error_string_ret[0]) Eprintf("While connecting to session manager: %s.", error_string_ret); if (!sm_conn) return; style[0] = SmRestartIfRunning; style[1] = 0; styleVal.length = 1; styleVal.value = style; styleProp.name = (char *)SmRestartStyleHint; styleProp.type = (char *)SmCARD8; styleProp.num_vals = 1; styleProp.vals = &styleVal; props[0] = &styleProp; ice_conn = SmcGetIceConnection(sm_conn); sm_fd = IceConnectionNumber(ice_conn); /* Just in case we are a copy of E created by a doExit("restart") */ SmcSetProperties(sm_conn, 1, props); fcntl(sm_fd, F_SETFD, fcntl(sm_fd, F_GETFD, 0) | FD_CLOEXEC); sm_efd = EventFdRegister(sm_fd, ice_msgs_process); }
extern "C" Q_DECL_EXPORT int kdemain( int argc, char* argv[] ) { sanity_check(argc, argv); putenv((char*)"SESSION_MANAGER="); checkComposite(); // force xcb QPA plugin as ksmserver is very X11 specific const QByteArray origQpaPlatform = qgetenv("QT_QPA_PLATFORM"); qputenv("QT_QPA_PLATFORM", QByteArrayLiteral("xcb")); QQuickWindow::setDefaultAlphaBuffer(true); QCoreApplication::setAttribute(Qt::AA_DisableHighDpiScaling); QApplication *a = new QApplication(argc, argv); // now the QPA platform is set, unset variable again to not launch apps with incorrect environment if (origQpaPlatform.isEmpty()) { qunsetenv("QT_QPA_PLATFORM"); } else { qputenv("QT_QPA_PLATFORM", origQpaPlatform); } QApplication::setApplicationName( QStringLiteral( "ksmserver") ); QApplication::setApplicationVersion( QString::fromLatin1( version ) ); QApplication::setOrganizationDomain( QStringLiteral( "kde.org") ); fcntl(ConnectionNumber(QX11Info::display()), F_SETFD, 1); a->setQuitOnLastWindowClosed(false); // #169486 QCommandLineParser parser; parser.setApplicationDescription(i18n(description)); parser.addHelpOption(); parser.addVersionOption(); QCommandLineOption restoreOption(QStringList() << QStringLiteral("r") << QStringLiteral("restore"), i18n("Restores the saved user session if available")); parser.addOption(restoreOption); QCommandLineOption wmOption(QStringList() << QStringLiteral("w") << QStringLiteral("windowmanager"), i18n("Starts <wm> in case no other window manager is \nparticipating in the session. Default is 'kwin'"), i18n("wm")); parser.addOption(wmOption); QCommandLineOption nolocalOption(QStringLiteral("nolocal"), i18n("Also allow remote connections")); parser.addOption(nolocalOption); QCommandLineOption lockscreenOption(QStringLiteral("lockscreen"), i18n("Starts the session in locked mode")); parser.addOption(lockscreenOption); QCommandLineOption noLockscreenOption(QStringLiteral("no-lockscreen"), i18n("Starts without lock screen support. Only needed if other component provides the lock screen.")); parser.addOption(noLockscreenOption); parser.process(*a); //TODO: should we still use this? // if( !QDBusConnection::sessionBus().interface()-> // registerService( QStringLiteral( "org.kde.ksmserver" ), // QDBusConnectionInterface::DontQueueService ) ) // { // qCWarning(KSMSERVER, "Could not register with D-BUS. Aborting."); // return 1; // } QString wm = parser.value(wmOption); bool only_local = !parser.isSet(nolocalOption); #ifndef HAVE__ICETRANSNOLISTEN /* this seems strange, but the default is only_local, so if !only_local * the option --nolocal was given, and we warn (the option --nolocal * does nothing on this platform, as here the default is reversed) */ if (!only_local) { qCWarning(KSMSERVER, "--nolocal is not supported on your platform. Sorry."); } only_local = false; #endif KSMServer::InitFlags flags = KSMServer::InitFlag::None; if (only_local) { flags |= KSMServer::InitFlag::OnlyLocal; } if (parser.isSet(lockscreenOption)) { flags |= KSMServer::InitFlag::ImmediateLockScreen; } if (parser.isSet(noLockscreenOption)) { flags |= KSMServer::InitFlag::NoLockScreen; } KSMServer *server = new KSMServer( wm, flags); // for the KDE-already-running check in startkde KSelectionOwner kde_running( "_KDE_RUNNING", 0 ); kde_running.claim( false ); IceSetIOErrorHandler( IoErrorHandler ); KConfigGroup config(KSharedConfig::openConfig(), "General"); int realScreenCount = ScreenCount( QX11Info::display() ); bool screenCountChanged = ( config.readEntry( "screenCount", realScreenCount ) != realScreenCount ); QString loginMode = config.readEntry( "loginMode", "restorePreviousLogout" ); if ( parser.isSet( restoreOption ) && ! screenCountChanged ) server->restoreSession( QStringLiteral( SESSION_BY_USER ) ); else if ( loginMode == QStringLiteral( "default" ) || screenCountChanged ) server->startDefaultSession(); else if ( loginMode == QStringLiteral( "restorePreviousLogout" ) ) server->restoreSession( QStringLiteral( SESSION_PREVIOUS_LOGOUT ) ); else if ( loginMode == QStringLiteral( "restoreSavedSession" ) ) server->restoreSession( QStringLiteral( SESSION_BY_USER ) ); else server->startDefaultSession(); KDBusService service(KDBusService::Unique); int ret = a->exec(); kde_running.release(); // needs to be done before QApplication destruction delete a; return ret; }