From 989d64d0df78832dbf3592aa9b056fb0893b09e5 Mon Sep 17 00:00:00 2001 From: Ray Strode Date: Tue, 17 Sep 2013 18:42:29 -0400 Subject: daemon: rename gdm-slave-proxy to gdm-slave-job It doesn't actually proxy calls to the slave, so it's misnamed. --- daemon/Makefile.am | 4 +- daemon/gdm-display.c | 48 ++--- daemon/gdm-slave-job.c | 478 +++++++++++++++++++++++++++++++++++++++++++++++ daemon/gdm-slave-job.h | 65 +++++++ daemon/gdm-slave-proxy.c | 478 ----------------------------------------------- daemon/gdm-slave-proxy.h | 65 ------- 6 files changed, 569 insertions(+), 569 deletions(-) create mode 100644 daemon/gdm-slave-job.c create mode 100644 daemon/gdm-slave-job.h delete mode 100644 daemon/gdm-slave-proxy.c delete mode 100644 daemon/gdm-slave-proxy.h diff --git a/daemon/Makefile.am b/daemon/Makefile.am index cde425a4..7eacbdc8 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -313,8 +313,8 @@ gdm_SOURCES = \ gdm-transient-display.h \ gdm-manager.c \ gdm-manager.h \ - gdm-slave-proxy.c \ - gdm-slave-proxy.h \ + gdm-slave-job.c \ + gdm-slave-job.h \ gdm-dbus-util.c \ gdm-dbus-util.h \ $(NULL) diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c index 1d26e29f..ed251afb 100644 --- a/daemon/gdm-display.c +++ b/daemon/gdm-display.c @@ -41,7 +41,7 @@ #include "gdm-settings-direct.h" #include "gdm-settings-keys.h" -#include "gdm-slave-proxy.h" +#include "gdm-slave-job.h" #include "gdm-slave-glue.h" #include "gdm-dbus-util.h" @@ -71,7 +71,7 @@ struct GdmDisplayPrivate gboolean is_local; guint finish_idle_id; - GdmSlaveProxy *slave_proxy; + GdmSlaveJob *slave_job; char *slave_bus_name; GdmDBusSlave *slave_bus_proxy; int slave_name_id; @@ -592,9 +592,9 @@ queue_finish (GdmDisplay *display) } static void -slave_exited (GdmSlaveProxy *proxy, - int code, - GdmDisplay *display) +slave_exited (GdmSlaveJob *job, + int code, + GdmDisplay *display) { g_debug ("GdmDisplay: Slave exited: %d", code); @@ -602,9 +602,9 @@ slave_exited (GdmSlaveProxy *proxy, } static void -slave_died (GdmSlaveProxy *proxy, - int signum, - GdmDisplay *display) +slave_died (GdmSlaveJob *job, + int signum, + GdmDisplay *display) { g_debug ("GdmDisplay: Slave died: %d", signum); @@ -633,7 +633,7 @@ gdm_display_real_prepare (GdmDisplay *display) g_debug ("GdmDisplay: prepare display"); - g_assert (display->priv->slave_proxy == NULL); + g_assert (display->priv->slave_job == NULL); if (!gdm_display_create_authority (display)) { g_warning ("Unable to set up access control for display %d", @@ -643,12 +643,12 @@ gdm_display_real_prepare (GdmDisplay *display) _gdm_display_set_status (display, GDM_DISPLAY_PREPARED); - display->priv->slave_proxy = gdm_slave_proxy_new (); - g_signal_connect (display->priv->slave_proxy, + display->priv->slave_job = gdm_slave_job_new (); + g_signal_connect (display->priv->slave_job, "exited", G_CALLBACK (slave_exited), display); - g_signal_connect (display->priv->slave_proxy, + g_signal_connect (display->priv->slave_job, "died", G_CALLBACK (slave_died), display); @@ -656,13 +656,13 @@ gdm_display_real_prepare (GdmDisplay *display) log_file = g_strdup_printf ("%s-slave.log", display->priv->x11_display_name); log_path = g_build_filename (LOGDIR, log_file, NULL); g_free (log_file); - gdm_slave_proxy_set_log_path (display->priv->slave_proxy, log_path); + gdm_slave_job_set_log_path (display->priv->slave_job, log_path); g_free (log_path); command = g_strdup_printf ("%s --display-id %s", display->priv->slave_command, display->priv->id); - gdm_slave_proxy_set_command (display->priv->slave_proxy, command); + gdm_slave_job_set_command (display->priv->slave_job, command); g_free (command); return TRUE; @@ -702,11 +702,11 @@ gdm_display_real_manage (GdmDisplay *display) } } - g_assert (display->priv->slave_proxy != NULL); + g_assert (display->priv->slave_job != NULL); g_timer_start (display->priv->slave_timer); - gdm_slave_proxy_start (display->priv->slave_proxy); + gdm_slave_job_start (display->priv->slave_job); return TRUE; } @@ -766,11 +766,11 @@ gdm_display_real_unmanage (GdmDisplay *display) g_timer_stop (display->priv->slave_timer); - if (display->priv->slave_proxy != NULL) { - gdm_slave_proxy_stop (display->priv->slave_proxy); + if (display->priv->slave_job != NULL) { + gdm_slave_job_stop (display->priv->slave_job); - g_object_unref (display->priv->slave_proxy); - display->priv->slave_proxy = NULL; + g_object_unref (display->priv->slave_job); + display->priv->slave_job = NULL; } if (display->priv->user_access_file != NULL) { @@ -1446,11 +1446,11 @@ gdm_display_dispose (GObject *object) display->priv->finish_idle_id = 0; } - if (display->priv->slave_proxy != NULL) { - gdm_slave_proxy_stop (display->priv->slave_proxy); + if (display->priv->slave_job != NULL) { + gdm_slave_job_stop (display->priv->slave_job); - g_object_unref (display->priv->slave_proxy); - display->priv->slave_proxy = NULL; + g_object_unref (display->priv->slave_job); + display->priv->slave_job = NULL; } if (display->priv->user_access_file != NULL) { diff --git a/daemon/gdm-slave-job.c b/daemon/gdm-slave-job.c new file mode 100644 index 00000000..58ac630c --- /dev/null +++ b/daemon/gdm-slave-job.c @@ -0,0 +1,478 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef WITH_SYSTEMD +#include +#endif + +#include +#include +#include +#include + +#include "gdm-common.h" + +#include "gdm-slave-job.h" + +#define GDM_SLAVE_JOB_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SLAVE_JOB, GdmSlaveJobPrivate)) + +#define MAX_LOGS 5 + +struct GdmSlaveJobPrivate +{ + char *command; + char *log_path; + GPid pid; + guint child_watch_id; +}; + +enum { + PROP_0, + PROP_COMMAND, + PROP_LOG_PATH, +}; + +enum { + EXITED, + DIED, + LAST_SIGNAL +}; + +static guint signals [LAST_SIGNAL] = { 0, }; + +static void gdm_slave_job_class_init (GdmSlaveJobClass *klass); +static void gdm_slave_job_init (GdmSlaveJob *slave); +static void gdm_slave_job_finalize (GObject *object); + +G_DEFINE_TYPE (GdmSlaveJob, gdm_slave_job, G_TYPE_OBJECT) + +static void +child_watch (GPid pid, + int status, + GdmSlaveJob *slave) +{ + g_debug ("GdmSlaveJob: slave (pid:%d) done (%s:%d)", + (int) pid, + WIFEXITED (status) ? "status" + : WIFSIGNALED (status) ? "signal" + : "unknown", + WIFEXITED (status) ? WEXITSTATUS (status) + : WIFSIGNALED (status) ? WTERMSIG (status) + : -1); + + g_spawn_close_pid (slave->priv->pid); + slave->priv->pid = -1; + slave->priv->child_watch_id = 0; + + if (WIFEXITED (status)) { + int code = WEXITSTATUS (status); + g_signal_emit (slave, signals [EXITED], 0, code); + } else if (WIFSIGNALED (status)) { + int num = WTERMSIG (status); + g_signal_emit (slave, signals [DIED], 0, num); + } +} + +static void +rotate_logs (const char *path, + guint n_copies) +{ + int i; + + for (i = n_copies - 1; i > 0; i--) { + char *name_n; + char *name_n1; + + name_n = g_strdup_printf ("%s.%d", path, i); + if (i > 1) { + name_n1 = g_strdup_printf ("%s.%d", path, i - 1); + } else { + name_n1 = g_strdup (path); + } + + VE_IGNORE_EINTR (g_unlink (name_n)); + VE_IGNORE_EINTR (g_rename (name_n1, name_n)); + + g_free (name_n1); + g_free (name_n); + } + + VE_IGNORE_EINTR (g_unlink (path)); +} + +typedef struct { + const char *identifier; + const char *log_file; +} SpawnChildData; + +static void +spawn_child_setup (SpawnChildData *data) +{ +#ifdef WITH_SYSTEMD + if (sd_booted () > 0) { + return; + } +#endif + + if (data->log_file != NULL) { + int logfd; + + rotate_logs (data->log_file, MAX_LOGS); + + VE_IGNORE_EINTR (g_unlink (data->log_file)); + VE_IGNORE_EINTR (logfd = open (data->log_file, O_CREAT|O_APPEND|O_TRUNC|O_WRONLY|O_EXCL, 0644)); + + if (logfd != -1) { + VE_IGNORE_EINTR (dup2 (logfd, 1)); + VE_IGNORE_EINTR (dup2 (logfd, 2)); + close (logfd); + } + } +} + +static gboolean +spawn_command_line_async (const char *command_line, + const char *log_file, + char **env, + GPid *child_pid, + GError **error) +{ + char **argv; + GError *local_error; + gboolean ret; + gboolean res; + SpawnChildData data; + gboolean has_journald = FALSE; + + ret = FALSE; + + argv = NULL; + local_error = NULL; + if (! g_shell_parse_argv (command_line, NULL, &argv, &local_error)) { + g_warning ("Could not parse command: %s", local_error->message); + g_propagate_error (error, local_error); + goto out; + } + + data.identifier = argv[0]; + +#ifdef WITH_SYSTEMD + if (sd_booted () > 0) { + has_journald = TRUE; + } +#endif + + if (has_journald) { + data.log_file = NULL; + } else { + data.log_file = log_file; + } + + local_error = NULL; + res = g_spawn_async (NULL, + argv, + env, + G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, + (GSpawnChildSetupFunc)spawn_child_setup, + &data, + child_pid, + &local_error); + + if (! res) { + g_warning ("Could not spawn command: %s", local_error->message); + g_propagate_error (error, local_error); + goto out; + } + + ret = TRUE; + out: + g_strfreev (argv); + + return ret; +} + +static void +clear_child_watch (GdmSlaveJob *slave) +{ + slave->priv->child_watch_id = 0; + g_object_unref (slave); +} + +static gboolean +spawn_slave (GdmSlaveJob *slave) +{ + gboolean result; + GError *error; + + g_debug ("GdmSlaveJob: Running command: %s", slave->priv->command); + + error = NULL; + result = spawn_command_line_async (slave->priv->command, + slave->priv->log_path, + NULL, + &slave->priv->pid, + &error); + if (! result) { + g_warning ("Could not start command '%s': %s", slave->priv->command, error->message); + g_error_free (error); + goto out; + } + + g_debug ("GdmSlaveJob: Started slave with pid %d", slave->priv->pid); + + slave->priv->child_watch_id = g_child_watch_add_full (G_PRIORITY_DEFAULT, + slave->priv->pid, + (GChildWatchFunc)child_watch, + g_object_ref (slave), + (GDestroyNotify) + clear_child_watch); + + result = TRUE; + + out: + + return result; +} + +static void +kill_slave (GdmSlaveJob *slave) +{ + int res; + + if (slave->priv->pid <= 1) { + return; + } + + res = gdm_signal_pid (slave->priv->pid, SIGTERM); + if (res < 0) { + g_warning ("Unable to kill slave process"); + } else { + int exit_status; + + exit_status = gdm_wait_on_pid (slave->priv->pid); + + g_debug ("GdmSlaveJob: slave died with exit status %d", exit_status); + + g_spawn_close_pid (slave->priv->pid); + slave->priv->pid = 0; + } +} + +gboolean +gdm_slave_job_start (GdmSlaveJob *slave) +{ + gdm_slave_job_stop (slave); + + spawn_slave (slave); + + return TRUE; +} + +gboolean +gdm_slave_job_stop (GdmSlaveJob *slave) +{ + g_debug ("GdmSlaveJob: Killing 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; +} + +void +gdm_slave_job_set_command (GdmSlaveJob *slave, + const char *command) +{ + g_free (slave->priv->command); + slave->priv->command = g_strdup (command); +} + +void +gdm_slave_job_set_log_path (GdmSlaveJob *slave, + const char *path) +{ + g_free (slave->priv->log_path); + slave->priv->log_path = g_strdup (path); +} + +static void +gdm_slave_job_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GdmSlaveJob *self; + + self = GDM_SLAVE_JOB (object); + + switch (prop_id) { + case PROP_COMMAND: + gdm_slave_job_set_command (self, g_value_get_string (value)); + break; + case PROP_LOG_PATH: + gdm_slave_job_set_log_path (self, g_value_get_string (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gdm_slave_job_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GdmSlaveJob *self; + + self = GDM_SLAVE_JOB (object); + + switch (prop_id) { + case PROP_COMMAND: + g_value_set_string (value, self->priv->command); + break; + case PROP_LOG_PATH: + g_value_set_string (value, self->priv->log_path); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gdm_slave_job_dispose (GObject *object) +{ + GdmSlaveJob *slave; + + slave = GDM_SLAVE_JOB (object); + + g_debug ("GdmSlaveJob: Disposing slave job"); + gdm_slave_job_stop (slave); + + G_OBJECT_CLASS (gdm_slave_job_parent_class)->dispose (object); +} + +static void +gdm_slave_job_class_init (GdmSlaveJobClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = gdm_slave_job_get_property; + object_class->set_property = gdm_slave_job_set_property; + object_class->dispose = gdm_slave_job_dispose; + object_class->finalize = gdm_slave_job_finalize; + + g_type_class_add_private (klass, sizeof (GdmSlaveJobPrivate)); + + g_object_class_install_property (object_class, + PROP_COMMAND, + g_param_spec_string ("command", + "command", + "command", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_object_class_install_property (object_class, + PROP_LOG_PATH, + g_param_spec_string ("log-path", + "log path", + "log path", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + + signals [EXITED] = + g_signal_new ("exited", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GdmSlaveJobClass, exited), + NULL, + NULL, + g_cclosure_marshal_VOID__INT, + G_TYPE_NONE, + 1, + G_TYPE_INT); + + signals [DIED] = + g_signal_new ("died", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GdmSlaveJobClass, died), + NULL, + NULL, + g_cclosure_marshal_VOID__INT, + G_TYPE_NONE, + 1, + G_TYPE_INT); +} + +static void +gdm_slave_job_init (GdmSlaveJob *slave) +{ + + slave->priv = GDM_SLAVE_JOB_GET_PRIVATE (slave); + + slave->priv->pid = -1; +} + +static void +gdm_slave_job_finalize (GObject *object) +{ + GdmSlaveJob *slave; + + g_return_if_fail (object != NULL); + g_return_if_fail (GDM_IS_SLAVE_JOB (object)); + + slave = GDM_SLAVE_JOB (object); + + g_return_if_fail (slave->priv != NULL); + + g_free (slave->priv->command); + g_free (slave->priv->log_path); + + G_OBJECT_CLASS (gdm_slave_job_parent_class)->finalize (object); +} + +GdmSlaveJob * +gdm_slave_job_new (void) +{ + GObject *object; + + object = g_object_new (GDM_TYPE_SLAVE_JOB, + NULL); + + return GDM_SLAVE_JOB (object); +} diff --git a/daemon/gdm-slave-job.h b/daemon/gdm-slave-job.h new file mode 100644 index 00000000..65bf00d0 --- /dev/null +++ b/daemon/gdm-slave-job.h @@ -0,0 +1,65 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright (C) 2007 William Jon McCann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + + +#ifndef __GDM_SLAVE_JOB_H +#define __GDM_SLAVE_JOB_H + +#include + +G_BEGIN_DECLS + +#define GDM_TYPE_SLAVE_JOB (gdm_slave_job_get_type ()) +#define GDM_SLAVE_JOB(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_SLAVE_JOB, GdmSlaveJob)) +#define GDM_SLAVE_JOB_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_SLAVE_JOB, GdmSlaveJobClass)) +#define GDM_IS_SLAVE_JOB(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_SLAVE_JOB)) +#define GDM_IS_SLAVE_JOB_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_SLAVE_JOB)) +#define GDM_SLAVE_JOB_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_SLAVE_JOB, GdmSlaveJobClass)) + +typedef struct GdmSlaveJobPrivate GdmSlaveJobPrivate; + +typedef struct +{ + GObject parent; + GdmSlaveJobPrivate *priv; +} GdmSlaveJob; + +typedef struct +{ + GObjectClass parent_class; + void (* exited) (GdmSlaveJob *job, + int exit_code); + + void (* died) (GdmSlaveJob *job, + int signal_number); +} GdmSlaveJobClass; + +GType gdm_slave_job_get_type (void); +GdmSlaveJob * gdm_slave_job_new (void); +void gdm_slave_job_set_command (GdmSlaveJob *slave, + const char *command); +void gdm_slave_job_set_log_path (GdmSlaveJob *slave, + const char *path); +gboolean gdm_slave_job_start (GdmSlaveJob *slave); +gboolean gdm_slave_job_stop (GdmSlaveJob *slave); + +G_END_DECLS + +#endif /* __GDM_SLAVE_JOB_H */ diff --git a/daemon/gdm-slave-proxy.c b/daemon/gdm-slave-proxy.c deleted file mode 100644 index 887a4f03..00000000 --- a/daemon/gdm-slave-proxy.c +++ /dev/null @@ -1,478 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2007 William Jon McCann - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef WITH_SYSTEMD -#include -#endif - -#include -#include -#include -#include - -#include "gdm-common.h" - -#include "gdm-slave-proxy.h" - -#define GDM_SLAVE_PROXY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_SLAVE_PROXY, GdmSlaveProxyPrivate)) - -#define MAX_LOGS 5 - -struct GdmSlaveProxyPrivate -{ - char *command; - char *log_path; - GPid pid; - guint child_watch_id; -}; - -enum { - PROP_0, - PROP_COMMAND, - PROP_LOG_PATH, -}; - -enum { - EXITED, - DIED, - LAST_SIGNAL -}; - -static guint signals [LAST_SIGNAL] = { 0, }; - -static void gdm_slave_proxy_class_init (GdmSlaveProxyClass *klass); -static void gdm_slave_proxy_init (GdmSlaveProxy *slave); -static void gdm_slave_proxy_finalize (GObject *object); - -G_DEFINE_TYPE (GdmSlaveProxy, gdm_slave_proxy, G_TYPE_OBJECT) - -static void -child_watch (GPid pid, - int status, - GdmSlaveProxy *slave) -{ - g_debug ("GdmSlaveProxy: slave (pid:%d) done (%s:%d)", - (int) pid, - WIFEXITED (status) ? "status" - : WIFSIGNALED (status) ? "signal" - : "unknown", - WIFEXITED (status) ? WEXITSTATUS (status) - : WIFSIGNALED (status) ? WTERMSIG (status) - : -1); - - g_spawn_close_pid (slave->priv->pid); - slave->priv->pid = -1; - slave->priv->child_watch_id = 0; - - if (WIFEXITED (status)) { - int code = WEXITSTATUS (status); - g_signal_emit (slave, signals [EXITED], 0, code); - } else if (WIFSIGNALED (status)) { - int num = WTERMSIG (status); - g_signal_emit (slave, signals [DIED], 0, num); - } -} - -static void -rotate_logs (const char *path, - guint n_copies) -{ - int i; - - for (i = n_copies - 1; i > 0; i--) { - char *name_n; - char *name_n1; - - name_n = g_strdup_printf ("%s.%d", path, i); - if (i > 1) { - name_n1 = g_strdup_printf ("%s.%d", path, i - 1); - } else { - name_n1 = g_strdup (path); - } - - VE_IGNORE_EINTR (g_unlink (name_n)); - VE_IGNORE_EINTR (g_rename (name_n1, name_n)); - - g_free (name_n1); - g_free (name_n); - } - - VE_IGNORE_EINTR (g_unlink (path)); -} - -typedef struct { - const char *identifier; - const char *log_file; -} SpawnChildData; - -static void -spawn_child_setup (SpawnChildData *data) -{ -#ifdef WITH_SYSTEMD - if (sd_booted () > 0) { - return; - } -#endif - - if (data->log_file != NULL) { - int logfd; - - rotate_logs (data->log_file, MAX_LOGS); - - VE_IGNORE_EINTR (g_unlink (data->log_file)); - VE_IGNORE_EINTR (logfd = open (data->log_file, O_CREAT|O_APPEND|O_TRUNC|O_WRONLY|O_EXCL, 0644)); - - if (logfd != -1) { - VE_IGNORE_EINTR (dup2 (logfd, 1)); - VE_IGNORE_EINTR (dup2 (logfd, 2)); - close (logfd); - } - } -} - -static gboolean -spawn_command_line_async (const char *command_line, - const char *log_file, - char **env, - GPid *child_pid, - GError **error) -{ - char **argv; - GError *local_error; - gboolean ret; - gboolean res; - SpawnChildData data; - gboolean has_journald = FALSE; - - ret = FALSE; - - argv = NULL; - local_error = NULL; - if (! g_shell_parse_argv (command_line, NULL, &argv, &local_error)) { - g_warning ("Could not parse command: %s", local_error->message); - g_propagate_error (error, local_error); - goto out; - } - - data.identifier = argv[0]; - -#ifdef WITH_SYSTEMD - if (sd_booted () > 0) { - has_journald = TRUE; - } -#endif - - if (has_journald) { - data.log_file = NULL; - } else { - data.log_file = log_file; - } - - local_error = NULL; - res = g_spawn_async (NULL, - argv, - env, - G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD, - (GSpawnChildSetupFunc)spawn_child_setup, - &data, - child_pid, - &local_error); - - if (! res) { - g_warning ("Could not spawn command: %s", local_error->message); - g_propagate_error (error, local_error); - goto out; - } - - ret = TRUE; - out: - g_strfreev (argv); - - return ret; -} - -static void -clear_child_watch (GdmSlaveProxy *slave) -{ - slave->priv->child_watch_id = 0; - g_object_unref (slave); -} - -static gboolean -spawn_slave (GdmSlaveProxy *slave) -{ - gboolean result; - GError *error; - - g_debug ("GdmSlaveProxy: Running command: %s", slave->priv->command); - - error = NULL; - result = spawn_command_line_async (slave->priv->command, - slave->priv->log_path, - NULL, - &slave->priv->pid, - &error); - if (! result) { - g_warning ("Could not start command '%s': %s", slave->priv->command, error->message); - g_error_free (error); - goto out; - } - - g_debug ("GdmSlaveProxy: Started slave with pid %d", slave->priv->pid); - - slave->priv->child_watch_id = g_child_watch_add_full (G_PRIORITY_DEFAULT, - slave->priv->pid, - (GChildWatchFunc)child_watch, - g_object_ref (slave), - (GDestroyNotify) - clear_child_watch); - - result = TRUE; - - out: - - return result; -} - -static void -kill_slave (GdmSlaveProxy *slave) -{ - int res; - - if (slave->priv->pid <= 1) { - return; - } - - res = gdm_signal_pid (slave->priv->pid, SIGTERM); - if (res < 0) { - g_warning ("Unable to kill slave process"); - } else { - int exit_status; - - exit_status = gdm_wait_on_pid (slave->priv->pid); - - g_debug ("GdmSlaveProxy: slave died with exit status %d", exit_status); - - g_spawn_close_pid (slave->priv->pid); - slave->priv->pid = 0; - } -} - -gboolean -gdm_slave_proxy_start (GdmSlaveProxy *slave) -{ - gdm_slave_proxy_stop (slave); - - spawn_slave (slave); - - return TRUE; -} - -gboolean -gdm_slave_proxy_stop (GdmSlaveProxy *slave) -{ - g_debug ("GdmSlaveProxy: Killing 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; -} - -void -gdm_slave_proxy_set_command (GdmSlaveProxy *slave, - const char *command) -{ - g_free (slave->priv->command); - slave->priv->command = g_strdup (command); -} - -void -gdm_slave_proxy_set_log_path (GdmSlaveProxy *slave, - const char *path) -{ - g_free (slave->priv->log_path); - slave->priv->log_path = g_strdup (path); -} - -static void -gdm_slave_proxy_set_property (GObject *object, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - GdmSlaveProxy *self; - - self = GDM_SLAVE_PROXY (object); - - switch (prop_id) { - case PROP_COMMAND: - gdm_slave_proxy_set_command (self, g_value_get_string (value)); - break; - case PROP_LOG_PATH: - gdm_slave_proxy_set_log_path (self, g_value_get_string (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gdm_slave_proxy_get_property (GObject *object, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - GdmSlaveProxy *self; - - self = GDM_SLAVE_PROXY (object); - - switch (prop_id) { - case PROP_COMMAND: - g_value_set_string (value, self->priv->command); - break; - case PROP_LOG_PATH: - g_value_set_string (value, self->priv->log_path); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gdm_slave_proxy_dispose (GObject *object) -{ - GdmSlaveProxy *slave; - - slave = GDM_SLAVE_PROXY (object); - - g_debug ("GdmSlaveProxy: Disposing slave proxy"); - gdm_slave_proxy_stop (slave); - - G_OBJECT_CLASS (gdm_slave_proxy_parent_class)->dispose (object); -} - -static void -gdm_slave_proxy_class_init (GdmSlaveProxyClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->get_property = gdm_slave_proxy_get_property; - object_class->set_property = gdm_slave_proxy_set_property; - object_class->dispose = gdm_slave_proxy_dispose; - object_class->finalize = gdm_slave_proxy_finalize; - - g_type_class_add_private (klass, sizeof (GdmSlaveProxyPrivate)); - - g_object_class_install_property (object_class, - PROP_COMMAND, - g_param_spec_string ("command", - "command", - "command", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - g_object_class_install_property (object_class, - PROP_LOG_PATH, - g_param_spec_string ("log-path", - "log path", - "log path", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); - - signals [EXITED] = - g_signal_new ("exited", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSlaveProxyClass, exited), - NULL, - NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, - 1, - G_TYPE_INT); - - signals [DIED] = - g_signal_new ("died", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GdmSlaveProxyClass, died), - NULL, - NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, - 1, - G_TYPE_INT); -} - -static void -gdm_slave_proxy_init (GdmSlaveProxy *slave) -{ - - slave->priv = GDM_SLAVE_PROXY_GET_PRIVATE (slave); - - slave->priv->pid = -1; -} - -static void -gdm_slave_proxy_finalize (GObject *object) -{ - GdmSlaveProxy *slave; - - g_return_if_fail (object != NULL); - g_return_if_fail (GDM_IS_SLAVE_PROXY (object)); - - slave = GDM_SLAVE_PROXY (object); - - g_return_if_fail (slave->priv != NULL); - - g_free (slave->priv->command); - g_free (slave->priv->log_path); - - G_OBJECT_CLASS (gdm_slave_proxy_parent_class)->finalize (object); -} - -GdmSlaveProxy * -gdm_slave_proxy_new (void) -{ - GObject *object; - - object = g_object_new (GDM_TYPE_SLAVE_PROXY, - NULL); - - return GDM_SLAVE_PROXY (object); -} diff --git a/daemon/gdm-slave-proxy.h b/daemon/gdm-slave-proxy.h deleted file mode 100644 index dbe45b36..00000000 --- a/daemon/gdm-slave-proxy.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- - * - * Copyright (C) 2007 William Jon McCann - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - */ - - -#ifndef __GDM_SLAVE_PROXY_H -#define __GDM_SLAVE_PROXY_H - -#include - -G_BEGIN_DECLS - -#define GDM_TYPE_SLAVE_PROXY (gdm_slave_proxy_get_type ()) -#define GDM_SLAVE_PROXY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDM_TYPE_SLAVE_PROXY, GdmSlaveProxy)) -#define GDM_SLAVE_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GDM_TYPE_SLAVE_PROXY, GdmSlaveProxyClass)) -#define GDM_IS_SLAVE_PROXY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GDM_TYPE_SLAVE_PROXY)) -#define GDM_IS_SLAVE_PROXY_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GDM_TYPE_SLAVE_PROXY)) -#define GDM_SLAVE_PROXY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_SLAVE_PROXY, GdmSlaveProxyClass)) - -typedef struct GdmSlaveProxyPrivate GdmSlaveProxyPrivate; - -typedef struct -{ - GObject parent; - GdmSlaveProxyPrivate *priv; -} GdmSlaveProxy; - -typedef struct -{ - GObjectClass parent_class; - void (* exited) (GdmSlaveProxy *proxy, - int exit_code); - - void (* died) (GdmSlaveProxy *proxy, - int signal_number); -} GdmSlaveProxyClass; - -GType gdm_slave_proxy_get_type (void); -GdmSlaveProxy * gdm_slave_proxy_new (void); -void gdm_slave_proxy_set_command (GdmSlaveProxy *slave, - const char *command); -void gdm_slave_proxy_set_log_path (GdmSlaveProxy *slave, - const char *path); -gboolean gdm_slave_proxy_start (GdmSlaveProxy *slave); -gboolean gdm_slave_proxy_stop (GdmSlaveProxy *slave); - -G_END_DECLS - -#endif /* __GDM_SLAVE_PROXY_H */ -- cgit v1.2.1