/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* Procman process actions * Copyright (C) 2001 Kevin Vandersloot * * 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 Library General Public * License along with this program; if not, see . * */ #include #include #include #include #include #include #include "procactions.h" #include "application.h" #include "proctable.h" #include "procdialogs.h" static void renice_single_process (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { const struct ProcActionArgs * const args = static_cast(data); ProcInfo *info = NULL; gint error; int saved_errno; gchar *error_msg; GtkMessageDialog *dialog; gtk_tree_model_get (model, iter, COL_POINTER, &info, -1); if (!info) return; if (info->nice == args->arg_value) return; error = setpriority (PRIO_PROCESS, info->pid, args->arg_value); /* success */ if(error != -1) return; saved_errno = errno; /* need to be root */ if(errno == EPERM || errno == EACCES) { gboolean success; success = procdialog_create_root_password_dialog ( PROCMAN_ACTION_RENICE, args->app, info->pid, args->arg_value); if(success) return; if(errno) { saved_errno = errno; } } /* failed */ error_msg = g_strdup_printf ( _("Cannot change the priority of process with PID %d to %d.\n" "%s"), info->pid, args->arg_value, g_strerror(saved_errno)); dialog = GTK_MESSAGE_DIALOG (gtk_message_dialog_new ( NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", error_msg)); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (GTK_WIDGET (dialog)); g_free (error_msg); } void renice (GsmApplication *app, int nice) { struct ProcActionArgs args = { app, nice }; /* EEEK - ugly hack - make sure the table is not updated as a crash ** occurs if you first kill a process and the tree node is removed while ** still in the foreach function */ proctable_freeze (app); gtk_tree_selection_selected_foreach(app->selection, renice_single_process, &args); proctable_thaw (app); proctable_update (app); } static void kill_single_process (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { const struct ProcActionArgs * const args = static_cast(data); char *error_msg; ProcInfo *info; int error; int saved_errno; GtkMessageDialog *dialog; gtk_tree_model_get (model, iter, COL_POINTER, &info, -1); if (!info) return; error = kill (info->pid, args->arg_value); /* success */ if(error != -1) return; saved_errno = errno; /* need to be root */ if(errno == EPERM) { gboolean success; success = procdialog_create_root_password_dialog ( PROCMAN_ACTION_KILL, args->app, info->pid, args->arg_value); if(success) return; if(errno) { saved_errno = errno; } } /* failed */ error_msg = g_strdup_printf ( _("Cannot kill process with PID %d with signal %d.\n" "%s"), info->pid, args->arg_value, g_strerror(saved_errno)); dialog = GTK_MESSAGE_DIALOG (gtk_message_dialog_new ( NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s", error_msg)); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (GTK_WIDGET (dialog)); g_free (error_msg); } void kill_process (GsmApplication *app, int sig) { struct ProcActionArgs args = { app, sig }; /* EEEK - ugly hack - make sure the table is not updated as a crash ** occurs if you first kill a process and the tree node is removed while ** still in the foreach function */ proctable_freeze (app); gtk_tree_selection_selected_foreach (app->selection, kill_single_process, &args); proctable_thaw (app); proctable_update (app); }