|
Packit |
15f964 |
/*
|
|
Packit |
15f964 |
* killev.c
|
|
Packit |
15f964 |
*
|
|
Packit |
15f964 |
* This program is free software; you can redistribute it and/or modify it
|
|
Packit |
15f964 |
* under the terms of the GNU Lesser General Public License as published by
|
|
Packit |
15f964 |
* the Free Software Foundation.
|
|
Packit |
15f964 |
*
|
|
Packit |
15f964 |
* This program is distributed in the hope that it will be useful, but
|
|
Packit |
15f964 |
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
Packit |
15f964 |
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
Packit |
15f964 |
* for more details.
|
|
Packit |
15f964 |
*
|
|
Packit |
15f964 |
* You should have received a copy of the GNU Lesser General Public License
|
|
Packit |
15f964 |
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
15f964 |
*
|
|
Packit |
15f964 |
*
|
|
Packit |
15f964 |
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
|
|
Packit |
15f964 |
*
|
|
Packit |
15f964 |
*/
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
#include "evolution-config.h"
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
#include <signal.h>
|
|
Packit |
15f964 |
#include <stdlib.h>
|
|
Packit |
15f964 |
#include <unistd.h>
|
|
Packit |
15f964 |
#include <sys/wait.h>
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
#include <gio/gio.h>
|
|
Packit |
15f964 |
#include <glib/gi18n.h>
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
#include <libedataserver/libedataserver.h>
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
/* Seconds to wait after asking Evolution to terminate gracefully.
|
|
Packit |
15f964 |
* If the process has not terminated before the timeout expires,
|
|
Packit |
15f964 |
* then we get violent. */
|
|
Packit |
15f964 |
#define EVOLUTION_SHUTDOWN_TIMEOUT 5
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
static GPid evolution_pid;
|
|
Packit |
15f964 |
static GMainLoop *main_loop;
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
static void
|
|
Packit |
15f964 |
file_monitor_changed_cb (GFileMonitor *monitor,
|
|
Packit |
15f964 |
GFile *file,
|
|
Packit |
15f964 |
GFile *not_used,
|
|
Packit |
15f964 |
GFileMonitorEvent event_type)
|
|
Packit |
15f964 |
{
|
|
Packit |
15f964 |
if (event_type != G_FILE_MONITOR_EVENT_DELETED)
|
|
Packit |
15f964 |
return;
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
g_print ("Evolution process exited normally\n");
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
g_main_loop_quit (main_loop);
|
|
Packit |
15f964 |
}
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
static gboolean
|
|
Packit |
15f964 |
evolution_not_responding_cb (gpointer user_data)
|
|
Packit |
15f964 |
{
|
|
Packit |
15f964 |
g_print ("No response from Evolution -- killing the process\n");
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
/* Kill the process. */
|
|
Packit |
15f964 |
kill ((pid_t) evolution_pid, SIGTERM);
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
g_main_loop_quit (main_loop);
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
return FALSE;
|
|
Packit |
15f964 |
}
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
static gboolean
|
|
Packit |
15f964 |
get_evolution_pid (GFile *file)
|
|
Packit |
15f964 |
{
|
|
Packit |
15f964 |
gint64 v_int64;
|
|
Packit |
15f964 |
gchar *contents = NULL;
|
|
Packit |
15f964 |
gboolean success = FALSE;
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
/* Try to read Evolution's PID from its .running file. */
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
if (!g_file_load_contents (file, NULL, &contents, NULL, NULL, NULL))
|
|
Packit |
15f964 |
goto exit;
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
/* Try to extract an integer value from the string. */
|
|
Packit |
15f964 |
v_int64 = g_ascii_strtoll (contents, NULL, 10);
|
|
Packit |
15f964 |
if (!(v_int64 > 0 && v_int64 < G_MAXINT64))
|
|
Packit |
15f964 |
goto exit;
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
/* XXX Probably not portable. */
|
|
Packit |
15f964 |
evolution_pid = (GPid) v_int64;
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
success = TRUE;
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
exit:
|
|
Packit |
15f964 |
g_free (contents);
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
return success;
|
|
Packit |
15f964 |
}
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
gint
|
|
Packit |
15f964 |
main (gint argc,
|
|
Packit |
15f964 |
gchar **argv)
|
|
Packit |
15f964 |
{
|
|
Packit |
15f964 |
GFile *pid_file = NULL;
|
|
Packit |
15f964 |
GFileMonitor *monitor;
|
|
Packit |
15f964 |
const gchar *user_config_dir;
|
|
Packit |
15f964 |
gchar *filename;
|
|
Packit |
15f964 |
gint retval = EXIT_SUCCESS;
|
|
Packit |
15f964 |
GError *error = NULL;
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
bindtextdomain (GETTEXT_PACKAGE, EVOLUTION_LOCALEDIR);
|
|
Packit |
15f964 |
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
|
Packit |
15f964 |
textdomain (GETTEXT_PACKAGE);
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
user_config_dir = e_get_user_config_dir ();
|
|
Packit |
15f964 |
filename = g_build_filename (user_config_dir, ".running", NULL);
|
|
Packit |
15f964 |
pid_file = g_file_new_for_path (filename);
|
|
Packit |
15f964 |
g_free (filename);
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
if (!get_evolution_pid (pid_file)) {
|
|
Packit |
15f964 |
g_printerr ("Could not find Evolution's process ID\n");
|
|
Packit |
15f964 |
retval = EXIT_FAILURE;
|
|
Packit |
15f964 |
goto kill;
|
|
Packit |
15f964 |
}
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
if (g_getenv ("DISPLAY") == NULL)
|
|
Packit |
15f964 |
goto kill;
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
/* Play it safe here and bail if something goes wrong. We don't
|
|
Packit |
15f964 |
* want to just skip to the killing if we can't ask Evolution to
|
|
Packit |
15f964 |
* terminate gracefully. Despite our name we actually want to
|
|
Packit |
15f964 |
* -avoid- killing Evolution if at all possible. */
|
|
Packit |
15f964 |
if (!g_spawn_command_line_async ("evolution --quit", &error)) {
|
|
Packit |
15f964 |
g_printerr ("%s\n", error->message);
|
|
Packit |
15f964 |
g_error_free (error);
|
|
Packit |
15f964 |
retval = EXIT_FAILURE;
|
|
Packit |
15f964 |
goto kill;
|
|
Packit |
15f964 |
}
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
/* Now we set up a monitor on Evolution's .running file.
|
|
Packit |
15f964 |
* If Evolution is still responsive it will delete this
|
|
Packit |
15f964 |
* file just before terminating and we'll be notified. */
|
|
Packit |
15f964 |
monitor = g_file_monitor_file (pid_file, 0, NULL, &error);
|
|
Packit |
15f964 |
if (error != NULL) {
|
|
Packit |
15f964 |
g_printerr ("%s\n", error->message);
|
|
Packit |
15f964 |
g_error_free (error);
|
|
Packit |
15f964 |
retval = EXIT_FAILURE;
|
|
Packit |
15f964 |
goto kill;
|
|
Packit |
15f964 |
}
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
g_signal_connect (
|
|
Packit |
15f964 |
monitor, "changed",
|
|
Packit |
15f964 |
G_CALLBACK (file_monitor_changed_cb), NULL);
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
e_named_timeout_add_seconds (
|
|
Packit |
15f964 |
EVOLUTION_SHUTDOWN_TIMEOUT,
|
|
Packit |
15f964 |
evolution_not_responding_cb, NULL);
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
/* Start the clock. */
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
main_loop = g_main_loop_new (NULL, TRUE);
|
|
Packit |
15f964 |
g_main_loop_run (main_loop);
|
|
Packit |
15f964 |
g_main_loop_unref (main_loop);
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
g_object_unref (monitor);
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
kill:
|
|
Packit |
15f964 |
#ifdef KILL_PROCESS_COMMAND
|
|
Packit |
15f964 |
#ifdef KILL_PROCESS_COMMAND_ARGS
|
|
Packit |
15f964 |
#define KILL_CMD KILL_PROCESS_COMMAND " " KILL_PROCESS_COMMAND_ARGS
|
|
Packit |
15f964 |
#else
|
|
Packit |
15f964 |
#define KILL_CMD KILL_PROCESS_COMMAND
|
|
Packit |
15f964 |
#endif
|
|
Packit |
15f964 |
#ifndef KILL_PROCESS_COMMAND_ARG_EXACT
|
|
Packit |
15f964 |
#define KILL_PROCESS_COMMAND_ARG_EXACT ""
|
|
Packit |
15f964 |
#endif
|
|
Packit |
15f964 |
if (system (KILL_CMD " " KILL_PROCESS_COMMAND_ARG_EXACT " -TERM evolution 2> /dev/null") == -1)
|
|
Packit |
15f964 |
g_warning ("%s: Failed to execute: '%s'", G_STRFUNC, KILL_PROCESS_COMMAND);
|
|
Packit |
15f964 |
if (system (KILL_CMD " -TERM evolution-alarm-notify 2> /dev/null") == -1)
|
|
Packit |
15f964 |
g_warning ("%s: Failed to execute: '%s'", G_STRFUNC, KILL_PROCESS_COMMAND);
|
|
Packit |
15f964 |
if (system (KILL_CMD " -TERM evolution-source-registry 2> /dev/null") == -1)
|
|
Packit |
15f964 |
g_warning ("%s: Failed to execute: '%s'", G_STRFUNC, KILL_PROCESS_COMMAND);
|
|
Packit |
15f964 |
if (system (KILL_CMD " -TERM evolution-addressbook-factory 2> /dev/null") == -1)
|
|
Packit |
15f964 |
g_warning ("%s: Failed to execute: '%s'", G_STRFUNC, KILL_PROCESS_COMMAND);
|
|
Packit |
15f964 |
if (system (KILL_CMD " -TERM evolution-calendar-factory 2> /dev/null") == -1)
|
|
Packit |
15f964 |
g_warning ("%s: Failed to execute: '%s'", G_STRFUNC, KILL_PROCESS_COMMAND);
|
|
Packit |
15f964 |
#undef KILL_CMD
|
|
Packit |
15f964 |
#else
|
|
Packit |
15f964 |
g_printerr ("No \"kill\" command available.\n");
|
|
Packit |
15f964 |
#endif
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
g_clear_object (&pid_file);
|
|
Packit |
15f964 |
|
|
Packit |
15f964 |
return retval;
|
|
Packit |
15f964 |
}
|