summaryrefslogtreecommitdiff
path: root/src/gs-job.c.orig
diff options
context:
space:
mode:
Diffstat (limited to 'src/gs-job.c.orig')
-rw-r--r--src/gs-job.c.orig567
1 files changed, 0 insertions, 567 deletions
diff --git a/src/gs-job.c.orig b/src/gs-job.c.orig
deleted file mode 100644
index 896addc..0000000
--- a/src/gs-job.c.orig
+++ /dev/null
@@ -1,567 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
- *
- * Copyright (C) 2004-2006 William Jon McCann <[email protected]>
- *
- * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * Authors: William Jon McCann <[email protected]>
- *
- */
-
-#include "config.h"
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <signal.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <string.h>
-
-#if defined(HAVE_SETPRIORITY) && defined(PRIO_PROCESS)
-#include <sys/resource.h>
-#endif
-
-#include <glib.h>
-#include <glib/gstdio.h>
-#include <gdk/gdk.h>
-#include <gdk/gdkx.h>
-
-#include "gs-debug.h"
-#include "gs-job.h"
-
-#include "subprocs.h"
-
-static void gs_job_class_init (GSJobClass *klass);
-static void gs_job_init (GSJob *job);
-static void gs_job_finalize (GObject *object);
-
-#define GS_JOB_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GS_TYPE_JOB, GSJobPrivate))
-
-typedef enum
-{
- GS_JOB_INVALID,
- GS_JOB_RUNNING,
- GS_JOB_STOPPED,
- GS_JOB_KILLED,
- GS_JOB_DEAD
-} GSJobStatus;
-
-struct GSJobPrivate
-{
- GtkWidget *widget;
-
- GSJobStatus status;
- gint pid;
- guint watch_id;
-
- char *command;
-};
-
-G_DEFINE_TYPE (GSJob, gs_job, G_TYPE_OBJECT)
-
-static char *
-widget_get_id_string (GtkWidget *widget)
-{
- char *id = NULL;
-
- g_return_val_if_fail (widget != NULL, NULL);
-
- id = g_strdup_printf ("0x%X",
- (guint32)GDK_WINDOW_XID (widget->window));
- return id;
-}
-
-static void
-gs_job_class_init (GSJobClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- object_class->finalize = gs_job_finalize;
-
- g_type_class_add_private (klass, sizeof (GSJobPrivate));
-}
-
-static void
-gs_job_init (GSJob *job)
-{
- job->priv = GS_JOB_GET_PRIVATE (job);
-}
-
-/* adapted from gspawn.c */
-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
- {
- gs_debug ("waitpid () should not fail in 'GSJob'");
- }
- }
-
- return status;
-}
-
-static void
-gs_job_died (GSJob *job)
-{
- if (job->priv->pid > 0)
- {
- int exit_status;
-
- gs_debug ("Waiting on process %d", job->priv->pid);
- exit_status = wait_on_child (job->priv->pid);
-
- job->priv->status = GS_JOB_DEAD;
-
- if (WIFEXITED (exit_status) && (WEXITSTATUS (exit_status) != 0))
- {
- gs_debug ("Wait on child process failed");
- }
- else
- {
- /* exited normally */
- }
- }
- g_spawn_close_pid (job->priv->pid);
- job->priv->pid = 0;
-
- gs_debug ("Job died");
-}
-
-static void
-gs_job_finalize (GObject *object)
-{
- GSJob *job;
-
- g_return_if_fail (object != NULL);
- g_return_if_fail (GS_IS_JOB (object));
-
- job = GS_JOB (object);
-
- g_return_if_fail (job->priv != NULL);
-
- if (job->priv->pid > 0)
- {
- signal_pid (job->priv->pid, SIGTERM);
- gs_job_died (job);
- }
-
- g_free (job->priv->command);
- job->priv->command = NULL;
-
- G_OBJECT_CLASS (gs_job_parent_class)->finalize (object);
-}
-
-void
-gs_job_set_widget (GSJob *job,
- GtkWidget *widget)
-{
- g_return_if_fail (job != NULL);
- g_return_if_fail (GS_IS_JOB (job));
-
- if (widget != job->priv->widget)
- {
- job->priv->widget = widget;
-
- /* restart job */
- if (gs_job_is_running (job))
- {
- gs_job_stop (job);
- gs_job_start (job);
- }
- }
-}
-
-gboolean
-gs_job_set_command (GSJob *job,
- const char *command)
-{
- g_return_val_if_fail (GS_IS_JOB (job), FALSE);
-
- gs_debug ("Setting command for job: '%s'",
- command != NULL ? command : "NULL");
-
- g_free (job->priv->command);
- job->priv->command = g_strdup (command);
-
- return TRUE;
-}
-
-GSJob *
-gs_job_new (void)
-{
- GObject *job;
-
- job = g_object_new (GS_TYPE_JOB, NULL);
-
- return GS_JOB (job);
-}
-
-GSJob *
-gs_job_new_for_widget (GtkWidget *widget)
-{
- GObject *job;
-
- job = g_object_new (GS_TYPE_JOB, NULL);
-
- gs_job_set_widget (GS_JOB (job), widget);
-
- return GS_JOB (job);
-}
-
-static void
-nice_process (int pid,
- int nice_level)
-{
- g_return_if_fail (pid > 0);
-
- if (nice_level == 0)
- {
- return;
- }
-
-#if defined(HAVE_SETPRIORITY) && defined(PRIO_PROCESS)
- gs_debug ("Setting child process priority to: %d", nice_level);
- if (setpriority (PRIO_PROCESS, pid, nice_level) != 0)
- {
- gs_debug ("setpriority(PRIO_PROCESS, %lu, %d) failed",
- (unsigned long) pid, nice_level);
- }
-#else
- gs_debug ("don't know how to change process priority on this system.");
-#endif
-}
-
-static GPtrArray *
-get_env_vars (GtkWidget *widget)
-{
- GPtrArray *env;
- char *str;
- int i;
- static const char *allowed_env_vars [] =
- {
- "PATH",
- "SESSION_MANAGER",
- "XAUTHORITY",
- "XAUTHLOCALHOSTNAME",
- "LANG",
- "LANGUAGE",
- "DBUS_SESSION_BUS_ADDRESS"
- };
-
- env = g_ptr_array_new ();
-
- str = gdk_screen_make_display_name (gtk_widget_get_screen (widget));
- g_ptr_array_add (env, g_strdup_printf ("DISPLAY=%s", str));
- g_free (str);
-
- g_ptr_array_add (env, g_strdup_printf ("HOME=%s",
- g_get_home_dir ()));
-
- for (i = 0; i < G_N_ELEMENTS (allowed_env_vars); i++)
- {
- const char *var;
- const char *val;
- var = allowed_env_vars [i];
- val = g_getenv (var);
- if (val != NULL)
- {
- g_ptr_array_add (env, g_strdup_printf ("%s=%s",
- var,
- val));
- }
- }
-
- str = widget_get_id_string (widget);
- g_ptr_array_add (env, g_strdup_printf ("XSCREENSAVER_WINDOW=%s", str));
- g_free (str);
-
- g_ptr_array_add (env, NULL);
-
- return env;
-}
-
-static gboolean
-spawn_on_widget (GtkWidget *widget,
- const char *command,
- int *pid,
- GIOFunc watch_func,
- gpointer user_data,
- guint *watch_id)
-{
- char **argv;
- GPtrArray *env;
- gboolean result;
- GIOChannel *channel;
- GError *error = NULL;
- int standard_error;
- int child_pid;
- int id;
- int i;
-
- if (command == NULL)
- {
- return FALSE;
- }
-
- if (! g_shell_parse_argv (command, NULL, &argv, &error))
- {
- gs_debug ("Could not parse command: %s", error->message);
- g_error_free (error);
- return FALSE;
- }
-
- env = get_env_vars (widget);
-
- error = NULL;
- result = gdk_spawn_on_screen_with_pipes (gtk_widget_get_screen (widget),
- NULL,
- argv,
- (char **)env->pdata,
- G_SPAWN_SEARCH_PATH | G_SPAWN_DO_NOT_REAP_CHILD,
- NULL,
- NULL,
- &child_pid,
- NULL,
- NULL,
- &standard_error,
- &error);
- for (i = 0; i < env->len; i++)
- {
- g_free (g_ptr_array_index (env, i));
- }
- g_ptr_array_free (env, TRUE);
-
- if (! result)
- {
- gs_debug ("Could not start command '%s': %s", command, error->message);
- g_error_free (error);
- g_strfreev (argv);
- return FALSE;
- }
-
- g_strfreev (argv);
-
- nice_process (child_pid, 10);
-
- if (pid != NULL)
- {
- *pid = child_pid;
- }
- else
- {
- g_spawn_close_pid (child_pid);
- }
-
- channel = g_io_channel_unix_new (standard_error);
- g_io_channel_set_close_on_unref (channel, TRUE);
- g_io_channel_set_flags (channel,
- g_io_channel_get_flags (channel) | G_IO_FLAG_NONBLOCK,
- NULL);
- id = g_io_add_watch (channel,
- G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- watch_func,
- user_data);
- if (watch_id != NULL)
- {
- *watch_id = id;
- }
-
- g_io_channel_unref (channel);
-
- return result;
-}
-
-static gboolean
-command_watch (GIOChannel *source,
- GIOCondition condition,
- GSJob *job)
-{
- GIOStatus status;
- GError *error = NULL;
- gboolean done = FALSE;
-
- g_return_val_if_fail (job != NULL, FALSE);
-
- if (condition & G_IO_IN)
- {
- char *str;
-
- status = g_io_channel_read_line (source, &str, NULL, NULL, &error);
-
- if (status == G_IO_STATUS_NORMAL)
- {
- gs_debug ("command output: %s", str);
-
- }
- else if (status == G_IO_STATUS_EOF)
- {
- done = TRUE;
-
- }
- else if (error != NULL)
- {
- gs_debug ("command error: %s", error->message);
- g_error_free (error);
- }
-
- g_free (str);
- }
- else if (condition & G_IO_HUP)
- {
- done = TRUE;
- }
-
- if (done)
- {
- gs_job_died (job);
-
- job->priv->watch_id = 0;
- return FALSE;
- }
-
- return TRUE;
-}
-
-gboolean
-gs_job_is_running (GSJob *job)
-{
- gboolean running;
-
- g_return_val_if_fail (GS_IS_JOB (job), FALSE);
-
- running = (job->priv->pid > 0);
-
- return running;
-}
-
-gboolean
-gs_job_start (GSJob *job)
-{
- gboolean result;
-
- g_return_val_if_fail (job != NULL, FALSE);
- g_return_val_if_fail (GS_IS_JOB (job), FALSE);
-
- gs_debug ("starting job");
-
- if (job->priv->pid != 0)
- {
- gs_debug ("Cannot restart active job.");
- return FALSE;
- }
-
- if (job->priv->widget == NULL)
- {
- gs_debug ("Could not start job: screensaver window is not set.");
- return FALSE;
- }
-
- if (job->priv->command == NULL)
- {
- /* no warning here because a NULL command is interpreted
- as a no-op job */
- gs_debug ("No command set for job.");
- return FALSE;
- }
-
- result = spawn_on_widget (job->priv->widget,
- job->priv->command,
- &job->priv->pid,
- (GIOFunc)command_watch,
- job,
- &job->priv->watch_id);
-
- if (result)
- {
- job->priv->status = GS_JOB_RUNNING;
- }
-
- return result;
-}
-
-static void
-remove_command_watch (GSJob *job)
-{
- if (job->priv->watch_id != 0)
- {
- g_source_remove (job->priv->watch_id);
- job->priv->watch_id = 0;
- }
-}
-
-gboolean
-gs_job_stop (GSJob *job)
-{
- g_return_val_if_fail (job != NULL, FALSE);
- g_return_val_if_fail (GS_IS_JOB (job), FALSE);
-
- gs_debug ("stopping job");
-
- if (job->priv->pid == 0)
- {
- gs_debug ("Could not stop job: pid not defined");
- return FALSE;
- }
-
- if (job->priv->status == GS_JOB_STOPPED)
- {
- gs_job_suspend (job, FALSE);
- }
-
- remove_command_watch (job);
-
- signal_pid (job->priv->pid, SIGTERM);
-
- job->priv->status = GS_JOB_KILLED;
-
- gs_job_died (job);
-
- return TRUE;
-}
-
-gboolean
-gs_job_suspend (GSJob *job,
- gboolean suspend)
-{
- g_return_val_if_fail (job != NULL, FALSE);
- g_return_val_if_fail (GS_IS_JOB (job), FALSE);
-
- gs_debug ("suspending job");
-
- if (job->priv->pid == 0)
- {
- return FALSE;
- }
-
- signal_pid (job->priv->pid, (suspend ? SIGSTOP : SIGCONT));
-
- job->priv->status = (suspend ? GS_JOB_STOPPED : GS_JOB_RUNNING);
-
- return TRUE;
-}