summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog25
-rw-r--r--common/gdm-common.c34
-rw-r--r--common/gdm-common.h1
-rw-r--r--common/gdm-settings-desktop-backend.c43
-rw-r--r--common/gdm-settings-utils.c7
-rw-r--r--daemon/gdm-server.c30
-rw-r--r--daemon/gdm-session-worker-job.c30
-rw-r--r--daemon/gdm-slave-proxy.c25
-rw-r--r--daemon/gdm-welcome-session.c40
-rw-r--r--daemon/main.c4
-rw-r--r--gui/simple-greeter/gdm-remote-login-window.c21
-rw-r--r--gui/simple-greeter/gdm-session-client.c31
12 files changed, 162 insertions, 129 deletions
diff --git a/ChangeLog b/ChangeLog
index 16965da5..be8768eb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,30 @@
2008-03-17 William Jon McCann <jmccann@redhat.com>
+ * common/gdm-common.c: (gdm_wait_on_pid), (gdm_signal_pid),
+ (_read_bytes), (gdm_generate_random_bytes):
+ * common/gdm-common.h:
+ * common/gdm-settings-desktop-backend.c: (parse_key_string),
+ (gdm_settings_desktop_backend_get_value),
+ (gdm_settings_desktop_backend_finalize):
+ * common/gdm-settings-utils.c: (gdm_settings_parse_schemas):
+ * daemon/gdm-server.c: (server_died), (gdm_server_stop):
+ * daemon/gdm-session-worker-job.c: (session_worker_job_died),
+ (gdm_session_worker_job_stop):
+ * daemon/gdm-slave-proxy.c: (child_watch), (kill_slave),
+ (gdm_slave_proxy_stop), (gdm_slave_proxy_dispose),
+ (gdm_slave_proxy_finalize):
+ * daemon/gdm-welcome-session.c: (stop_dbus_daemon),
+ (welcome_session_died), (gdm_welcome_session_stop):
+ * daemon/main.c: (main):
+ * gui/simple-greeter/gdm-remote-login-window.c: (xserver_died):
+ * gui/simple-greeter/gdm-session-client.c: (client_died),
+ (gdm_session_client_stop):
+ Move wait_on_child to common. Always check return value of
+ gdm_signal_pid. Fix a number of small leaks. Make sure
+ to signal the slaves when exiting.
+
+2008-03-17 William Jon McCann <jmccann@redhat.com>
+
* gui/simple-greeter/gdm-greeter-login-window.c:
(gdm_greeter_login_window_init):
* gui/simple-greeter/gdm-greeter-panel.c: (gdm_greeter_panel_init):
diff --git a/common/gdm-common.c b/common/gdm-common.c
index ec9fe99e..b94aa016 100644
--- a/common/gdm-common.c
+++ b/common/gdm-common.c
@@ -64,13 +64,43 @@ gdm_set_fatal_warnings_if_unstable (void)
}
int
+gdm_wait_on_pid (int pid)
+{
+ int status;
+
+ wait_again:
+ errno = 0;
+ if (waitpid (pid, &status, 0) < 0) {
+ if (errno == EINTR) {
+ goto wait_again;
+ } else if (errno == ECHILD) {
+ ; /* do nothing, child already reaped */
+ } else {
+ g_debug ("GdmCommon: waitpid () should not fail");
+ }
+ }
+
+ g_debug ("GdmCommon: process (pid:%d) done (%s:%d)",
+ (int) pid,
+ WIFEXITED (status) ? "status"
+ : WIFSIGNALED (status) ? "signal"
+ : "unknown",
+ WIFEXITED (status) ? WEXITSTATUS (status)
+ : WIFSIGNALED (status) ? WTERMSIG (status)
+ : -1);
+
+ return status;
+}
+
+int
gdm_signal_pid (int pid,
int signal)
{
int status = -1;
/* perhaps block sigchld */
- g_debug ("sending signal %d to process %d", signal, pid);
+ g_debug ("GdmCommon: sending signal %d to process %d", signal, pid);
+ errno = 0;
status = kill (pid, signal);
if (status < 0) {
@@ -324,6 +354,7 @@ _read_bytes (int fd,
do {
size_t bytes_read = 0;
+ errno = 0;
bytes_read = read (fd, ((guchar *) bytes) + total_bytes_read,
bytes_left_to_read);
@@ -377,6 +408,7 @@ gdm_generate_random_bytes (gsize size,
* than the passed in size.
*/
+ errno = 0;
fd = open ("/dev/urandom", O_RDONLY);
if (fd < 0) {
diff --git a/common/gdm-common.h b/common/gdm-common.h
index 1f3bbd4a..c3122815 100644
--- a/common/gdm-common.h
+++ b/common/gdm-common.h
@@ -30,6 +30,7 @@ G_BEGIN_DECLS
gboolean gdm_is_version_unstable (void);
void gdm_set_fatal_warnings_if_unstable (void);
+int gdm_wait_on_pid (int pid);
int gdm_signal_pid (int pid,
int signal);
diff --git a/common/gdm-settings-desktop-backend.c b/common/gdm-settings-desktop-backend.c
index 18416fb9..e380f27b 100644
--- a/common/gdm-settings-desktop-backend.c
+++ b/common/gdm-settings-desktop-backend.c
@@ -77,6 +77,19 @@ parse_key_string (const char *keystring,
g = k = v = l = NULL;
split1 = split2 = NULL;
+ if (group != NULL) {
+ *group = g;
+ }
+ if (key != NULL) {
+ *key = k;
+ }
+ if (locale != NULL) {
+ *locale = l;
+ }
+ if (value != NULL) {
+ *value = v;
+ }
+
/*g_debug ("Attempting to parse key string: %s", keystring);*/
split1 = g_strsplit (keystring, "/", 2);
@@ -108,7 +121,7 @@ parse_key_string (const char *keystring,
}
ret = TRUE;
- out:
+
if (group != NULL) {
*group = g_strdup (g);
}
@@ -121,6 +134,7 @@ parse_key_string (const char *keystring,
if (value != NULL) {
*value = g_strdup (v);
}
+ out:
g_strfreev (split1);
g_strfreev (split2);
@@ -134,23 +148,27 @@ gdm_settings_desktop_backend_get_value (GdmSettingsBackend *backend,
char **value,
GError **error)
{
- GError *local_error;
- char *val;
- char *g;
- char *k;
- char *l;
+ GError *local_error;
+ char *val;
+ char *g;
+ char *k;
+ char *l;
+ gboolean ret;
g_return_val_if_fail (GDM_IS_SETTINGS_BACKEND (backend), FALSE);
g_return_val_if_fail (key != NULL, FALSE);
+ ret = FALSE;
+
if (value != NULL) {
*value = NULL;
}
+ val = g = k = l = NULL;
/*GDM_SETTINGS_BACKEND_CLASS (gdm_settings_desktop_backend_parent_class)->get_value (display);*/
if (! parse_key_string (key, &g, &k, &l, NULL)) {
g_set_error (error, GDM_SETTINGS_BACKEND_ERROR, GDM_SETTINGS_BACKEND_ERROR_KEY_NOT_FOUND, "Key not found");
- return FALSE;
+ goto out;
}
/*g_debug ("Getting key: %s %s %s", g, k, l);*/
@@ -162,16 +180,20 @@ gdm_settings_desktop_backend_get_value (GdmSettingsBackend *backend,
if (local_error != NULL) {
g_error_free (local_error);
g_set_error (error, GDM_SETTINGS_BACKEND_ERROR, GDM_SETTINGS_BACKEND_ERROR_KEY_NOT_FOUND, "Key not found");
- return FALSE;
+ goto out;
}
if (value != NULL) {
*value = g_strdup (val);
}
-
+ ret = TRUE;
+ out:
g_free (val);
+ g_free (g);
+ g_free (k);
+ g_free (l);
- return TRUE;
+ return ret;
}
static void
@@ -331,6 +353,7 @@ gdm_settings_desktop_backend_finalize (GObject *object)
save_settings (backend);
g_key_file_free (backend->priv->key_file);
+ g_free (backend->priv->filename);
G_OBJECT_CLASS (gdm_settings_desktop_backend_parent_class)->finalize (object);
}
diff --git a/common/gdm-settings-utils.c b/common/gdm-settings-utils.c
index af677f9b..ca0153bb 100644
--- a/common/gdm-settings-utils.c
+++ b/common/gdm-settings-utils.c
@@ -216,14 +216,17 @@ gdm_settings_parse_schemas (const char *file,
char *contents;
gsize len;
GError *error;
+ gboolean res;
g_return_val_if_fail (file != NULL, FALSE);
g_return_val_if_fail (root != NULL, FALSE);
g_assert (schemas != NULL);
+ contents = NULL;
error = NULL;
- if (! g_file_get_contents (file, &contents, &len, &error)) {
+ res = g_file_get_contents (file, &contents, &len, &error);
+ if (! res) {
g_warning ("Unable to read schemas file: %s", error->message);
g_error_free (error);
return FALSE;
@@ -235,7 +238,9 @@ gdm_settings_parse_schemas (const char *file,
*schemas = info->list;
+ g_markup_parse_context_free (ctx);
g_free (info);
+ g_free (contents);
return TRUE;
}
diff --git a/daemon/gdm-server.c b/daemon/gdm-server.c
index 05732bf3..91ce8133 100644
--- a/daemon/gdm-server.c
+++ b/daemon/gdm-server.c
@@ -678,32 +678,13 @@ gdm_server_start (GdmServer *server)
return res;
}
-static int
-wait_on_child (int pid)
-{
- int status;
-
- wait_again:
- if (waitpid (pid, &status, 0) < 0) {
- if (errno == EINTR) {
- goto wait_again;
- } else if (errno == ECHILD) {
- ; /* do nothing, child already reaped */
- } else {
- g_debug ("GdmServer: waitpid () should not fail");
- }
- }
-
- return status;
-}
-
static void
server_died (GdmServer *server)
{
int exit_status;
g_debug ("GdmServer: Waiting on process %d", server->priv->pid);
- exit_status = wait_on_child (server->priv->pid);
+ exit_status = gdm_wait_on_pid (server->priv->pid);
if (WIFEXITED (exit_status) && (WEXITSTATUS (exit_status) != 0)) {
g_debug ("GdmServer: Wait on child process failed");
@@ -726,6 +707,8 @@ server_died (GdmServer *server)
gboolean
gdm_server_stop (GdmServer *server)
{
+ int res;
+
if (server->priv->pid <= 1) {
return TRUE;
}
@@ -738,8 +721,11 @@ gdm_server_stop (GdmServer *server)
g_debug ("GdmServer: Stopping server");
- gdm_signal_pid (server->priv->pid, SIGTERM);
- server_died (server);
+ res = gdm_signal_pid (server->priv->pid, SIGTERM);
+ if (res < 0) {
+ } else {
+ server_died (server);
+ }
return TRUE;
}
diff --git a/daemon/gdm-session-worker-job.c b/daemon/gdm-session-worker-job.c
index d3243608..01d8b35a 100644
--- a/daemon/gdm-session-worker-job.c
+++ b/daemon/gdm-session-worker-job.c
@@ -222,32 +222,13 @@ gdm_session_worker_job_start (GdmSessionWorkerJob *session_worker_job)
return res;
}
-static int
-wait_on_child (int pid)
-{
- int status;
-
- wait_again:
- if (waitpid (pid, &status, 0) < 0) {
- if (errno == EINTR) {
- goto wait_again;
- } else if (errno == ECHILD) {
- ; /* do nothing, child already reaped */
- } else {
- g_debug ("GdmSessionWorkerJob: waitpid () should not fail");
- }
- }
-
- return status;
-}
-
static void
session_worker_job_died (GdmSessionWorkerJob *session_worker_job)
{
int exit_status;
g_debug ("GdmSessionWorkerJob: Waiting on process %d", session_worker_job->priv->pid);
- exit_status = wait_on_child (session_worker_job->priv->pid);
+ exit_status = gdm_wait_on_pid (session_worker_job->priv->pid);
if (WIFEXITED (exit_status) && (WEXITSTATUS (exit_status) != 0)) {
g_debug ("GdmSessionWorkerJob: Wait on child process failed");
@@ -264,6 +245,7 @@ session_worker_job_died (GdmSessionWorkerJob *session_worker_job)
gboolean
gdm_session_worker_job_stop (GdmSessionWorkerJob *session_worker_job)
{
+ int res;
if (session_worker_job->priv->pid <= 1) {
return TRUE;
@@ -277,8 +259,12 @@ gdm_session_worker_job_stop (GdmSessionWorkerJob *session_worker_job)
g_debug ("GdmSessionWorkerJob: Stopping job pid:%d", session_worker_job->priv->pid);
- gdm_signal_pid (session_worker_job->priv->pid, SIGTERM);
- session_worker_job_died (session_worker_job);
+ res = gdm_signal_pid (session_worker_job->priv->pid, SIGTERM);
+ if (res < 0) {
+ g_warning ("Unable to kill session worker process");
+ } else {
+ session_worker_job_died (session_worker_job);
+ }
return TRUE;
}
diff --git a/daemon/gdm-slave-proxy.c b/daemon/gdm-slave-proxy.c
index 2b51f705..979a1deb 100644
--- a/daemon/gdm-slave-proxy.c
+++ b/daemon/gdm-slave-proxy.c
@@ -82,6 +82,7 @@ child_watch (GPid pid,
g_spawn_close_pid (slave->priv->pid);
slave->priv->pid = -1;
+ slave->priv->child_watch_id = 0;
if (WIFEXITED (status)) {
int code = WEXITSTATUS (status);
@@ -147,11 +148,21 @@ spawn_slave (GdmSlaveProxy *slave)
static void
kill_slave (GdmSlaveProxy *slave)
{
+ int exit_status;
+ int res;
+
if (slave->priv->pid <= 1) {
return;
}
- gdm_signal_pid (slave->priv->pid, SIGTERM);
+ res = gdm_signal_pid (slave->priv->pid, SIGTERM);
+ if (res < 0) {
+ g_warning ("Unable to kill slave process");
+ } else {
+ exit_status = gdm_wait_on_pid (slave->priv->pid);
+ g_spawn_close_pid (slave->priv->pid);
+ slave->priv->pid = 0;
+ }
}
gboolean
@@ -167,12 +178,13 @@ gdm_slave_proxy_stop (GdmSlaveProxy *slave)
{
g_debug ("GdmSlaveProxy: Killing slave");
- kill_slave (slave);
-
if (slave->priv->child_watch_id > 0) {
g_source_remove (slave->priv->child_watch_id);
+ slave->priv->child_watch_id = 0;
}
+ kill_slave (slave);
+
return TRUE;
}
@@ -232,10 +244,7 @@ gdm_slave_proxy_dispose (GObject *object)
slave = GDM_SLAVE_PROXY (object);
g_debug ("GdmSlaveProxy: Disposing slave proxy");
- if (slave->priv->child_watch_id > 0) {
- g_source_remove (slave->priv->child_watch_id);
- slave->priv->child_watch_id = 0;
- }
+ gdm_slave_proxy_stop (slave);
G_OBJECT_CLASS (gdm_slave_proxy_parent_class)->dispose (object);
}
@@ -305,6 +314,8 @@ gdm_slave_proxy_finalize (GObject *object)
g_return_if_fail (slave->priv != NULL);
+ g_free (slave->priv->command);
+
G_OBJECT_CLASS (gdm_slave_proxy_parent_class)->finalize (object);
}
diff --git a/daemon/gdm-welcome-session.c b/daemon/gdm-welcome-session.c
index d2041c51..e320ea99 100644
--- a/daemon/gdm-welcome-session.c
+++ b/daemon/gdm-welcome-session.c
@@ -330,10 +330,16 @@ get_welcome_environment (GdmWelcomeSession *welcome_session)
static gboolean
stop_dbus_daemon (GdmWelcomeSession *welcome_session)
{
+ int res;
+
if (welcome_session->priv->dbus_pid > 0) {
g_debug ("GdmWelcomeSession: Stopping D-Bus daemon");
- gdm_signal_pid (-1 * welcome_session->priv->dbus_pid, SIGTERM);
- welcome_session->priv->dbus_pid = 0;
+ res = gdm_signal_pid (-1 * welcome_session->priv->dbus_pid, SIGTERM);
+ if (res < 0) {
+ g_warning ("Unable to kill D-Bus daemon");
+ } else {
+ welcome_session->priv->dbus_pid = 0;
+ }
}
return TRUE;
}
@@ -741,32 +747,13 @@ gdm_welcome_session_start (GdmWelcomeSession *welcome_session)
return res;
}
-static int
-wait_on_child (int pid)
-{
- int status;
-
- wait_again:
- if (waitpid (pid, &status, 0) < 0) {
- if (errno == EINTR) {
- goto wait_again;
- } else if (errno == ECHILD) {
- ; /* do nothing, child already reaped */
- } else {
- g_debug ("GdmWelcomeSession: waitpid () should not fail");
- }
- }
-
- return status;
-}
-
static void
welcome_session_died (GdmWelcomeSession *welcome_session)
{
int exit_status;
g_debug ("GdmWelcomeSession: Waiting on process %d", welcome_session->priv->pid);
- exit_status = wait_on_child (welcome_session->priv->pid);
+ exit_status = gdm_wait_on_pid (welcome_session->priv->pid);
if (WIFEXITED (exit_status) && (WEXITSTATUS (exit_status) != 0)) {
g_debug ("GdmWelcomeSession: Wait on child process failed");
@@ -783,6 +770,7 @@ welcome_session_died (GdmWelcomeSession *welcome_session)
gboolean
gdm_welcome_session_stop (GdmWelcomeSession *welcome_session)
{
+ int res;
if (welcome_session->priv->pid <= 1) {
return TRUE;
@@ -796,8 +784,12 @@ gdm_welcome_session_stop (GdmWelcomeSession *welcome_session)
g_debug ("GdmWelcomeSession: Stopping welcome_session");
- gdm_signal_pid (-1 * welcome_session->priv->pid, SIGTERM);
- welcome_session_died (welcome_session);
+ res = gdm_signal_pid (-1 * welcome_session->priv->pid, SIGTERM);
+ if (res < 0) {
+ g_warning ("Unable to kill welcome session process");
+ } else {
+ welcome_session_died (welcome_session);
+ }
if (welcome_session->priv->ckc != NULL) {
close_welcome_session (welcome_session);
diff --git a/daemon/main.c b/daemon/main.c
index 21fefc8a..e945d056 100644
--- a/daemon/main.c
+++ b/daemon/main.c
@@ -630,6 +630,8 @@ main (int argc,
g_main_loop_run (main_loop);
+ g_debug ("GDM finished, cleaning up...");
+
if (manager != NULL) {
g_object_unref (manager);
}
@@ -642,6 +644,8 @@ main (int argc,
g_object_unref (signal_handler);
}
+ gdm_settings_direct_shutdown ();
+
g_main_loop_unref (main_loop);
ret = 0;
diff --git a/gui/simple-greeter/gdm-remote-login-window.c b/gui/simple-greeter/gdm-remote-login-window.c
index b3ffd751..d58e4199 100644
--- a/gui/simple-greeter/gdm-remote-login-window.c
+++ b/gui/simple-greeter/gdm-remote-login-window.c
@@ -66,32 +66,13 @@ static void gdm_remote_login_window_finalize (GObject
G_DEFINE_TYPE (GdmRemoteLoginWindow, gdm_remote_login_window, GTK_TYPE_WINDOW)
-static int
-wait_on_child (int pid)
-{
- int status;
-
- wait_again:
- if (waitpid (pid, &status, 0) < 0) {
- if (errno == EINTR) {
- goto wait_again;
- } else if (errno == ECHILD) {
- ; /* do nothing, child already reaped */
- } else {
- g_debug ("GdmRemoteLoginWindow: waitpid () should not fail");
- }
- }
-
- return status;
-}
-
static void
xserver_died (GdmRemoteLoginWindow *login_window)
{
int exit_status;
g_debug ("GdmRemoteLoginWindow: Waiting on process %d", login_window->priv->xserver_pid);
- exit_status = wait_on_child (login_window->priv->xserver_pid);
+ exit_status = gdm_wait_on_pid (login_window->priv->xserver_pid);
if (WIFEXITED (exit_status) && (WEXITSTATUS (exit_status) != 0)) {
g_debug ("GdmRemoteLoginWindow: Wait on child process failed");
diff --git a/gui/simple-greeter/gdm-session-client.c b/gui/simple-greeter/gdm-session-client.c
index 12b368df..0160da1f 100644
--- a/gui/simple-greeter/gdm-session-client.c
+++ b/gui/simple-greeter/gdm-session-client.c
@@ -162,32 +162,13 @@ gdm_session_client_start (GdmSessionClient *client,
return ret;
}
-static int
-wait_on_child (int pid)
-{
- int status;
-
- wait_again:
- if (waitpid (pid, &status, 0) < 0) {
- if (errno == EINTR) {
- goto wait_again;
- } else if (errno == ECHILD) {
- ; /* do nothing, child already reaped */
- } else {
- g_debug ("GdmSessionClient: waitpid () should not fail");
- }
- }
-
- return status;
-}
-
static void
client_died (GdmSessionClient *client)
{
int exit_status;
g_debug ("GdmSessionClient: Waiting on process %d", client->priv->pid);
- exit_status = wait_on_child (client->priv->pid);
+ exit_status = gdm_wait_on_pid (client->priv->pid);
if (WIFEXITED (exit_status) && (WEXITSTATUS (exit_status) != 0)) {
g_debug ("GdmSessionClient: Wait on child process failed");
@@ -214,8 +195,14 @@ gdm_session_client_stop (GdmSessionClient *client)
g_debug ("GdmSessionClient: Stopping client: %s", client->priv->name);
if (client->priv->pid > 0) {
- gdm_signal_pid (client->priv->pid, SIGTERM);
- client_died (client);
+ int res;
+
+ res = gdm_signal_pid (client->priv->pid, SIGTERM);
+ if (res < 0) {
+ g_warning ("Unable to kill session client process %d", client->priv->pid);
+ } else {
+ client_died (client);
+ }
}
}