int main (int argc, char **argv) { GMainLoop *main_loop; GOptionContext *context; DBusGConnection *connection; MdmSlave *slave; static char *display_id = NULL; MdmSignalHandler *signal_handler; static GOptionEntry entries [] = { { "display-id", 0, 0, G_OPTION_ARG_STRING, &display_id, N_("Display ID"), N_("ID") }, { NULL } }; bindtextdomain (GETTEXT_PACKAGE, MATELOCALEDIR); textdomain (GETTEXT_PACKAGE); setlocale (LC_ALL, ""); mdm_set_fatal_warnings_if_unstable (); g_type_init (); context = g_option_context_new (_("MATE Display Manager Slave")); g_option_context_add_main_entries (context, entries, NULL); g_option_context_parse (context, &argc, &argv, NULL); g_option_context_free (context); connection = get_system_bus (); if (connection == NULL) { goto out; } mdm_xerrors_init (); mdm_log_init (); settings = mdm_settings_new (); if (settings == NULL) { g_warning ("Unable to initialize settings"); goto out; } if (! mdm_settings_direct_init (settings, DATADIR "/mdm/mdm.schemas", "/")) { g_warning ("Unable to initialize settings"); goto out; } mdm_log_set_debug (is_debug_set ()); if (display_id == NULL) { g_critical ("No display ID set"); exit (1); } main_loop = g_main_loop_new (NULL, FALSE); signal_handler = mdm_signal_handler_new (); mdm_signal_handler_set_fatal_func (signal_handler, (GDestroyNotify)g_main_loop_quit, main_loop); mdm_signal_handler_add (signal_handler, SIGTERM, signal_cb, NULL); mdm_signal_handler_add (signal_handler, SIGINT, signal_cb, NULL); mdm_signal_handler_add (signal_handler, SIGILL, signal_cb, NULL); mdm_signal_handler_add (signal_handler, SIGBUS, signal_cb, NULL); mdm_signal_handler_add (signal_handler, SIGFPE, signal_cb, NULL); mdm_signal_handler_add (signal_handler, SIGHUP, signal_cb, NULL); mdm_signal_handler_add (signal_handler, SIGSEGV, signal_cb, NULL); mdm_signal_handler_add (signal_handler, SIGABRT, signal_cb, NULL); mdm_signal_handler_add (signal_handler, SIGUSR1, signal_cb, NULL); mdm_signal_handler_add (signal_handler, SIGUSR2, signal_cb, NULL); slave = mdm_product_slave_new (display_id); if (slave == NULL) { goto out; } g_signal_connect (slave, "stopped", G_CALLBACK (on_slave_stopped), main_loop); mdm_slave_start (slave); g_main_loop_run (main_loop); if (slave != NULL) { g_object_unref (slave); } if (signal_handler != NULL) { g_object_unref (signal_handler); } if (main_loop != NULL) { g_main_loop_unref (main_loop); } out: g_debug ("Slave finished"); return mdm_return_code; }
gboolean mdm_display_manage (MdmDisplay *d) { pid_t pid; int fds[2]; if (!d) return FALSE; mdm_debug ("mdm_display_manage: Managing %s", d->name); if (pipe (fds) < 0) { mdm_error ("mdm_display_manage: Cannot create pipe"); } if ( ! mdm_display_check_loop (d)) return FALSE; if (d->slavepid != 0) mdm_debug ("mdm_display_manage: Old slave pid is %d", (int)d->slavepid); /* If we have an old slave process hanging around, kill it */ /* This shouldn't be a normal code path however, so it doesn't matter * that we are hanging */ whack_old_slave (d, FALSE /* kill_connection */); /* Ensure that /tmp/.ICE-unix and /tmp/.X11-unix exist and have the * correct permissions */ mdm_ensure_sanity (); d->managetime = time (NULL); mdm_debug ("Forking slave process"); /* Fork slave process */ pid = d->slavepid = fork (); switch (pid) { case 0: setpgid (0, 0); /* Make the slave it's own leader. This 1) makes killing -pid of * the daemon work more sanely because the daemon can whack the * slave much better itself */ setsid (); /* In the child setup empty mask and set all signals to * default values, we'll make them more fun later */ mdm_unset_signals (); d->slavepid = getpid (); mdm_connection_close (pipeconn); pipeconn = NULL; mdm_connection_close (unixconn); unixconn = NULL; mdm_log_shutdown (); /* Debian changes */ #if 0 /* upstream version */ - /* Close everything */ - mdm_close_all_descriptors (0 /* from */, fds[0] /* except */, slave_fifo_pipe_fd /* except2 */); #endif /* Close stdin/stdout/stderr. Leave others, as pam modules may have them open */ VE_IGNORE_EINTR (close (0)); VE_IGNORE_EINTR (close (1)); VE_IGNORE_EINTR (close (2)); /* End of Debian changes */ /* No error checking here - if it's messed the best response * is to ignore & try to continue */ mdm_open_dev_null (O_RDONLY); /* open stdin - fd 0 */ mdm_open_dev_null (O_RDWR); /* open stdout - fd 1 */ mdm_open_dev_null (O_RDWR); /* open stderr - fd 2 */ mdm_log_init (); d->slave_notify_fd = fds[0]; fcntl (d->slave_notify_fd, F_SETFL, fcntl (d->slave_notify_fd, F_GETFL) | O_NONBLOCK); mdm_slave_start (d); /* should never retern */ /* yaikes, how did we ever get here? */ mdm_server_stop (d); _exit (DISPLAY_REMANAGE); break; case -1: d->slavepid = 0; mdm_error ("mdm_display_manage: Failed forking MDM slave process for %s", d->name); return FALSE; default: mdm_debug ("mdm_display_manage: Forked slave: %d", (int)pid); d->master_notify_fd = fds[1]; VE_IGNORE_EINTR (close (fds[0])); break; } /* invalidate chosen hostname */ g_free (d->chosen_hostname); d->chosen_hostname = NULL; /* use_chooser can only be temporary, if you want it permanent you set it up in the server definition with "chooser=true" and it will get set up during server command line resolution */ d->use_chooser = FALSE; if (SERVER_IS_LOCAL (d)) { d->dispstat = DISPLAY_ALIVE; } /* reset sleep to 1, to sleep just in case (avoids X server races) */ d->sleep_before_run = 1; return TRUE; }