3
#include <glib/gi18n.h>
4
#include <glibtop/procopenfiles.h>
8
#include <sys/socket.h>
12
#include "openfiles.h"
13
#include "proctable.h"
27
get_type_name(enum glibtop_file_type t)
31
case GLIBTOP_FILE_TYPE_FILE:
33
case GLIBTOP_FILE_TYPE_PIPE:
35
case GLIBTOP_FILE_TYPE_INETSOCKET:
36
return _("network connection");
37
case GLIBTOP_FILE_TYPE_LOCALSOCKET:
38
return _("local socket");
40
return _("unknown type");
47
friendlier_hostname(const char *dotted_quad, int port)
52
if(inet_pton(AF_INET, dotted_quad, &addr4) <= 0)
56
host = gethostbyaddr(&addr4, sizeof addr4, AF_INET);
61
return g_strdup_printf("%s:%d", host->h_name, port);
64
if(!dotted_quad[0]) return g_strdup("");
65
return g_strdup_printf("%s:%d", dotted_quad, port);
71
add_new_files (gpointer key, gpointer value, gpointer data)
73
glibtop_open_files_entry *openfiles = static_cast<glibtop_open_files_entry*>(value);
75
GtkTreeModel *model = static_cast<GtkTreeModel*>(data);
80
switch(openfiles->type)
82
case GLIBTOP_FILE_TYPE_FILE:
83
object = g_strdup(openfiles->info.file.name);
86
case GLIBTOP_FILE_TYPE_INETSOCKET:
87
object = friendlier_hostname(openfiles->info.sock.dest_host,
88
openfiles->info.sock.dest_port);
91
case GLIBTOP_FILE_TYPE_LOCALSOCKET:
92
object = g_strdup(openfiles->info.localsock.name);
96
object = g_strdup("");
99
gtk_list_store_insert (GTK_LIST_STORE (model), &row, 0);
100
gtk_list_store_set (GTK_LIST_STORE (model), &row,
101
COL_FD, openfiles->fd,
102
COL_TYPE, get_type_name(static_cast<glibtop_file_type>(openfiles->type)),
104
COL_OPENFILE_STRUCT, g_memdup(openfiles, sizeof(*openfiles)),
110
static GList *old_maps = NULL;
113
classify_openfiles (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
115
GHashTable *new_maps = static_cast<GHashTable*>(data);
116
GtkTreeIter *old_iter;
117
glibtop_open_files_entry *openfiles;
120
gtk_tree_model_get (model, iter, 1, &old_name, -1);
122
openfiles = static_cast<glibtop_open_files_entry*>(g_hash_table_lookup (new_maps, old_name));
124
g_hash_table_remove (new_maps, old_name);
130
old_iter = gtk_tree_iter_copy (iter);
131
old_maps = g_list_append (old_maps, old_iter);
139
compare_open_files(gconstpointer a, gconstpointer b)
141
const glibtop_open_files_entry *o1 = static_cast<const glibtop_open_files_entry *>(a);
142
const glibtop_open_files_entry *o2 = static_cast<const glibtop_open_files_entry *>(b);
144
/* Falta manejar los diferentes tipos! */
145
return (o1->fd == o2->fd) && (o1->type == o1->type); /* XXX! */
150
update_openfiles_dialog (GtkWidget *tree)
154
glibtop_open_files_entry *openfiles;
155
glibtop_proc_open_files procmap;
156
GHashTable *new_maps;
159
info = static_cast<ProcInfo*>(g_object_get_data (G_OBJECT (tree), "selected_info"));
164
model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree));
166
openfiles = glibtop_get_proc_open_files (&procmap, info->pid);
171
new_maps = static_cast<GHashTable *>(g_hash_table_new_full (g_str_hash, compare_open_files,
173
for (i=0; i < procmap.number; i++)
174
g_hash_table_insert (new_maps, openfiles + i, openfiles + i);
176
gtk_tree_model_foreach (model, classify_openfiles, new_maps);
178
g_hash_table_foreach (new_maps, add_new_files, model);
181
GtkTreeIter *iter = static_cast<GtkTreeIter*>(old_maps->data);
182
glibtop_open_files_entry *openfiles = NULL;
184
gtk_tree_model_get (model, iter,
185
COL_OPENFILE_STRUCT, &openfiles,
188
gtk_list_store_remove (GTK_LIST_STORE (model), iter);
189
gtk_tree_iter_free (iter);
192
old_maps = g_list_next (old_maps);
196
g_hash_table_destroy (new_maps);
201
close_openfiles_dialog (GtkDialog *dialog, gint id, gpointer data)
203
GtkWidget *tree = static_cast<GtkWidget*>(data);
207
client = static_cast<GConfClient*>(g_object_get_data (G_OBJECT (tree), "client"));
208
procman_save_tree_state (client, tree, "/apps/procman/openfilestree2");
210
timer = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (tree), "timer"));
211
g_source_remove (timer);
213
gtk_widget_destroy (GTK_WIDGET (dialog));
220
create_openfiles_tree (ProcData *procdata)
224
GtkTreeViewColumn *column;
225
GtkCellRenderer *cell;
228
const gchar * const titles[] = {
229
/* Translators: "FD" here means "File Descriptor". Please use
230
a very short translation if possible, and at most
231
2-3 characters for it to be able to fit in the UI. */
237
model = gtk_list_store_new (NUM_OPENFILES_COL,
239
G_TYPE_STRING, /* Type */
240
G_TYPE_STRING, /* Object */
241
G_TYPE_POINTER /* open_files_entry */
244
tree = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
245
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (tree), TRUE);
246
g_object_unref (G_OBJECT (model));
248
for (i = 0; i < NUM_OPENFILES_COL-1; i++) {
249
cell = gtk_cell_renderer_text_new ();
253
g_object_set(cell, "xalign", 1.0f, NULL);
257
column = gtk_tree_view_column_new_with_attributes (_(titles[i]),
261
gtk_tree_view_column_set_sort_column_id (column, i);
262
gtk_tree_view_column_set_resizable (column, TRUE);
263
gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
267
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (model),
270
GINT_TO_POINTER (COL_FD),
272
/*gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model),
274
GTK_SORT_ASCENDING);*/
277
procman_get_tree_state (procdata->client, tree, "/apps/procman/openfilestree");
285
openfiles_timer (gpointer data)
287
GtkWidget *tree = static_cast<GtkWidget*>(data);
290
model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree));
293
update_openfiles_dialog (tree);
300
create_single_openfiles_dialog (GtkTreeModel *model, GtkTreePath *path,
301
GtkTreeIter *iter, gpointer data)
303
ProcData *procdata = static_cast<ProcData*>(data);
304
GtkWidget *openfilesdialog;
305
GtkWidget *dialog_vbox, *vbox;
313
gtk_tree_model_get (model, iter, COL_POINTER, &info, -1);
318
openfilesdialog = gtk_dialog_new_with_buttons (_("Open Files"), NULL,
319
GTK_DIALOG_DESTROY_WITH_PARENT,
320
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
322
gtk_window_set_resizable (GTK_WINDOW (openfilesdialog), TRUE);
323
gtk_window_set_default_size (GTK_WINDOW (openfilesdialog), 575, 400);
324
gtk_dialog_set_has_separator (GTK_DIALOG (openfilesdialog), FALSE);
325
gtk_container_set_border_width (GTK_CONTAINER (openfilesdialog), 5);
327
vbox = GTK_DIALOG (openfilesdialog)->vbox;
328
gtk_box_set_spacing (GTK_BOX (vbox), 2);
329
gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
331
dialog_vbox = gtk_vbox_new (FALSE, 6);
332
gtk_container_set_border_width (GTK_CONTAINER (dialog_vbox), 5);
333
gtk_box_pack_start (GTK_BOX (vbox), dialog_vbox, TRUE, TRUE, 0);
335
cmd_hbox = gtk_hbox_new (FALSE, 12);
336
gtk_box_pack_start (GTK_BOX (dialog_vbox), cmd_hbox, FALSE, FALSE, 0);
339
label = procman_make_label_for_mmaps_or_ofiles (
340
_("_Files opened by process \"%s\" (PID %u):"),
344
gtk_box_pack_start (GTK_BOX (cmd_hbox),label, FALSE, FALSE, 0);
347
scrolled = gtk_scrolled_window_new (NULL, NULL);
348
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
349
GTK_POLICY_AUTOMATIC,
350
GTK_POLICY_AUTOMATIC);
351
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled),
354
tree = create_openfiles_tree (procdata);
355
gtk_container_add (GTK_CONTAINER (scrolled), tree);
356
g_object_set_data (G_OBJECT (tree), "selected_info", info);
357
g_object_set_data (G_OBJECT (tree), "client", procdata->client);
359
gtk_box_pack_start (GTK_BOX (dialog_vbox), scrolled, TRUE, TRUE, 0);
360
gtk_widget_show_all (scrolled);
362
g_signal_connect (G_OBJECT (openfilesdialog), "response",
363
G_CALLBACK (close_openfiles_dialog), tree);
365
gtk_widget_show_all (openfilesdialog);
367
timer = g_timeout_add (5000, openfiles_timer, tree);
368
g_object_set_data (G_OBJECT (tree), "timer", GUINT_TO_POINTER (timer));
370
update_openfiles_dialog (tree);
376
create_openfiles_dialog (ProcData *procdata)
378
gtk_tree_selection_selected_foreach (procdata->selection, create_single_openfiles_dialog,