~ubuntu-branches/ubuntu/gutsy/gnome-system-monitor/gutsy

« back to all changes in this revision

Viewing changes to src/openfiles.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2006-12-18 00:11:37 UTC
  • mfrom: (1.1.18 upstream)
  • Revision ID: james.westby@ubuntu.com-20061218001137-xqbegj3g7g92y982
Tags: 2.17.4-0ubuntu1
* New upstream version:
  - 100% C++.
  - Disabled libsexy because it is buggy and unmaintained.
  - Fixed build on solaris.
* debian/control.in:
  - doesn't Build-Depends on libpcre3-dev
  - doesn't Recommends libsexy2
* debian/patches/01_load_library_instead_of_so.patch:
  - updated
* debian/patches/02_lpi.patch:
  - updated
* debian/patches/03_autoconf.patch:
  - updated

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <config.h>
 
2
 
 
3
#include <glib/gi18n.h>
 
4
#include <glibtop/procopenfiles.h>
 
5
#include <sys/stat.h>
 
6
#include <netdb.h>
 
7
#include <sys/types.h>
 
8
#include <sys/socket.h>
 
9
#include <arpa/inet.h>
 
10
 
 
11
#include "procman.h"
 
12
#include "openfiles.h"
 
13
#include "proctable.h"
 
14
#include "util.h"
 
15
 
 
16
enum
 
17
{
 
18
        COL_FD,
 
19
        COL_TYPE,
 
20
        COL_OBJECT,
 
21
        COL_OPENFILE_STRUCT,
 
22
        NUM_OPENFILES_COL
 
23
};
 
24
 
 
25
 
 
26
static const char*
 
27
get_type_name(enum glibtop_file_type t)
 
28
{
 
29
        switch(t)
 
30
        {
 
31
        case GLIBTOP_FILE_TYPE_FILE:
 
32
                return _("file");
 
33
        case GLIBTOP_FILE_TYPE_PIPE:
 
34
                return _("pipe");
 
35
        case GLIBTOP_FILE_TYPE_INETSOCKET:
 
36
                return _("network connection");
 
37
        case GLIBTOP_FILE_TYPE_LOCALSOCKET:
 
38
                return _("local socket");
 
39
        default:
 
40
                return _("unknown type");
 
41
        }
 
42
}
 
43
 
 
44
 
 
45
 
 
46
static char *
 
47
friendlier_hostname(const char *dotted_quad, int port)
 
48
{
 
49
        struct in_addr addr4;
 
50
        struct hostent *host;
 
51
 
 
52
        if(inet_pton(AF_INET, dotted_quad, &addr4) <= 0)
 
53
                goto failsafe;
 
54
 
 
55
 
 
56
        host = gethostbyaddr(&addr4, sizeof addr4, AF_INET);
 
57
 
 
58
        if(!host)
 
59
                goto failsafe;
 
60
 
 
61
        return g_strdup_printf("%s:%d", host->h_name, port);
 
62
 
 
63
 failsafe:
 
64
        if(!dotted_quad[0]) return g_strdup("");
 
65
        return g_strdup_printf("%s:%d", dotted_quad, port);
 
66
}
 
67
 
 
68
 
 
69
 
 
70
static void
 
71
add_new_files (gpointer key, gpointer value, gpointer data)
 
72
{
 
73
        glibtop_open_files_entry *openfiles = static_cast<glibtop_open_files_entry*>(value);
 
74
 
 
75
        GtkTreeModel *model = static_cast<GtkTreeModel*>(data);
 
76
        GtkTreeIter row;
 
77
 
 
78
        char *object;
 
79
 
 
80
        switch(openfiles->type)
 
81
        {
 
82
        case GLIBTOP_FILE_TYPE_FILE:
 
83
                object = g_strdup(openfiles->info.file.name);
 
84
                break;
 
85
 
 
86
        case GLIBTOP_FILE_TYPE_INETSOCKET:
 
87
                object = friendlier_hostname(openfiles->info.sock.dest_host,
 
88
                                             openfiles->info.sock.dest_port);
 
89
                break;
 
90
 
 
91
        case GLIBTOP_FILE_TYPE_LOCALSOCKET:
 
92
                object = g_strdup(openfiles->info.localsock.name);
 
93
                break;
 
94
 
 
95
        default:
 
96
                object = g_strdup("");
 
97
        }
 
98
 
 
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)),
 
103
                            COL_OBJECT, object,
 
104
                            COL_OPENFILE_STRUCT, g_memdup(openfiles, sizeof(*openfiles)),
 
105
                            -1);
 
106
 
 
107
        g_free(object);
 
108
}
 
109
 
 
110
static GList *old_maps = NULL;
 
111
 
 
112
static gboolean
 
113
classify_openfiles (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
 
114
{
 
115
        GHashTable *new_maps = static_cast<GHashTable*>(data);
 
116
        GtkTreeIter *old_iter;
 
117
        glibtop_open_files_entry *openfiles;
 
118
        gchar *old_name;
 
119
 
 
120
        gtk_tree_model_get (model, iter, 1, &old_name, -1);
 
121
 
 
122
        openfiles = static_cast<glibtop_open_files_entry*>(g_hash_table_lookup (new_maps, old_name));
 
123
        if (openfiles) {
 
124
                g_hash_table_remove (new_maps, old_name);
 
125
                g_free (old_name);
 
126
                return FALSE;
 
127
 
 
128
        }
 
129
 
 
130
        old_iter = gtk_tree_iter_copy (iter);
 
131
        old_maps = g_list_append (old_maps, old_iter);
 
132
        g_free (old_name);
 
133
        return FALSE;
 
134
 
 
135
}
 
136
 
 
137
 
 
138
static gboolean
 
139
compare_open_files(gconstpointer a, gconstpointer b)
 
140
{
 
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);
 
143
 
 
144
        /* Falta manejar los diferentes tipos! */
 
145
        return (o1->fd == o2->fd) && (o1->type == o1->type); /* XXX! */
 
146
}
 
147
 
 
148
 
 
149
static void
 
150
update_openfiles_dialog (GtkWidget *tree)
 
151
{
 
152
        ProcInfo *info;
 
153
        GtkTreeModel *model;
 
154
        glibtop_open_files_entry *openfiles;
 
155
        glibtop_proc_open_files procmap;
 
156
        GHashTable *new_maps;
 
157
        guint i;
 
158
 
 
159
        info = static_cast<ProcInfo*>(g_object_get_data (G_OBJECT (tree), "selected_info"));
 
160
 
 
161
        if (!info)
 
162
                return;
 
163
 
 
164
        model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree));
 
165
 
 
166
        openfiles = glibtop_get_proc_open_files (&procmap, info->pid);
 
167
 
 
168
        if (!openfiles)
 
169
                return;
 
170
 
 
171
        new_maps = static_cast<GHashTable *>(g_hash_table_new_full (g_str_hash, compare_open_files,
 
172
                                                                    NULL, NULL));
 
173
        for (i=0; i < procmap.number; i++)
 
174
                g_hash_table_insert (new_maps, openfiles + i, openfiles + i);
 
175
 
 
176
        gtk_tree_model_foreach (model, classify_openfiles, new_maps);
 
177
 
 
178
        g_hash_table_foreach (new_maps, add_new_files, model);
 
179
 
 
180
        while (old_maps) {
 
181
                GtkTreeIter *iter = static_cast<GtkTreeIter*>(old_maps->data);
 
182
                glibtop_open_files_entry *openfiles = NULL;
 
183
 
 
184
                gtk_tree_model_get (model, iter,
 
185
                                    COL_OPENFILE_STRUCT, &openfiles,
 
186
                                    -1);
 
187
 
 
188
                gtk_list_store_remove (GTK_LIST_STORE (model), iter);
 
189
                gtk_tree_iter_free (iter);
 
190
                g_free (openfiles);
 
191
 
 
192
                old_maps = g_list_next (old_maps);
 
193
 
 
194
        }
 
195
 
 
196
        g_hash_table_destroy (new_maps);
 
197
        g_free (openfiles);
 
198
}
 
199
 
 
200
static void
 
201
close_openfiles_dialog (GtkDialog *dialog, gint id, gpointer data)
 
202
{
 
203
        GtkWidget *tree = static_cast<GtkWidget*>(data);
 
204
        GConfClient *client;
 
205
        guint timer;
 
206
 
 
207
        client = static_cast<GConfClient*>(g_object_get_data (G_OBJECT (tree), "client"));
 
208
        procman_save_tree_state (client, tree, "/apps/procman/openfilestree2");
 
209
 
 
210
        timer = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (tree), "timer"));
 
211
        g_source_remove (timer);
 
212
 
 
213
        gtk_widget_destroy (GTK_WIDGET (dialog));
 
214
 
 
215
        return ;
 
216
}
 
217
 
 
218
 
 
219
static GtkWidget *
 
220
create_openfiles_tree (ProcData *procdata)
 
221
{
 
222
        GtkWidget *tree;
 
223
        GtkListStore *model;
 
224
        GtkTreeViewColumn *column;
 
225
        GtkCellRenderer *cell;
 
226
        gint i;
 
227
 
 
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. */
 
232
                N_("FD"),
 
233
                N_("Type"),
 
234
                N_("Object")
 
235
        };
 
236
 
 
237
        model = gtk_list_store_new (NUM_OPENFILES_COL,
 
238
                                    G_TYPE_INT,         /* FD */
 
239
                                    G_TYPE_STRING,      /* Type */
 
240
                                    G_TYPE_STRING,      /* Object */
 
241
                                    G_TYPE_POINTER      /* open_files_entry */
 
242
                );
 
243
 
 
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));
 
247
 
 
248
        for (i = 0; i < NUM_OPENFILES_COL-1; i++) {
 
249
                cell = gtk_cell_renderer_text_new ();
 
250
 
 
251
                switch (i) {
 
252
                case COL_FD:
 
253
                        g_object_set(cell, "xalign", 1.0f, NULL);
 
254
                        break;
 
255
                }
 
256
 
 
257
                column = gtk_tree_view_column_new_with_attributes (_(titles[i]),
 
258
                                                                   cell,
 
259
                                                                   "text", i,
 
260
                                                                   NULL);
 
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);
 
264
        }
 
265
 
 
266
#if 0
 
267
        gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (model),
 
268
                                         COL_VMSZ,
 
269
                                         sort_ints,
 
270
                                         GINT_TO_POINTER (COL_FD),
 
271
                                         NULL);
 
272
/*gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model),
 
273
  0,
 
274
  GTK_SORT_ASCENDING);*/
 
275
#endif
 
276
 
 
277
        procman_get_tree_state (procdata->client, tree, "/apps/procman/openfilestree");
 
278
 
 
279
        return tree;
 
280
 
 
281
}
 
282
 
 
283
 
 
284
static gboolean
 
285
openfiles_timer (gpointer data)
 
286
{
 
287
        GtkWidget *tree = static_cast<GtkWidget*>(data);
 
288
        GtkTreeModel *model;
 
289
 
 
290
        model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree));
 
291
        g_assert(model);
 
292
 
 
293
        update_openfiles_dialog (tree);
 
294
 
 
295
        return TRUE;
 
296
}
 
297
 
 
298
 
 
299
static void
 
300
create_single_openfiles_dialog (GtkTreeModel *model, GtkTreePath *path,
 
301
                                GtkTreeIter *iter, gpointer data)
 
302
{
 
303
        ProcData *procdata = static_cast<ProcData*>(data);
 
304
        GtkWidget *openfilesdialog;
 
305
        GtkWidget *dialog_vbox, *vbox;
 
306
        GtkWidget *cmd_hbox;
 
307
        GtkWidget *label;
 
308
        GtkWidget *scrolled;
 
309
        GtkWidget *tree;
 
310
        ProcInfo *info;
 
311
        guint timer;
 
312
 
 
313
        gtk_tree_model_get (model, iter, COL_POINTER, &info, -1);
 
314
 
 
315
        if (!info)
 
316
                return;
 
317
 
 
318
        openfilesdialog = gtk_dialog_new_with_buttons (_("Open Files"), NULL,
 
319
                                                       GTK_DIALOG_DESTROY_WITH_PARENT,
 
320
                                                       GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
 
321
                                                       NULL);
 
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);
 
326
 
 
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);
 
330
 
 
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);
 
334
 
 
335
        cmd_hbox = gtk_hbox_new (FALSE, 12);
 
336
        gtk_box_pack_start (GTK_BOX (dialog_vbox), cmd_hbox, FALSE, FALSE, 0);
 
337
 
 
338
 
 
339
        label = procman_make_label_for_mmaps_or_ofiles (
 
340
                _("_Files opened by process \"%s\" (PID %u):"),
 
341
                info->name,
 
342
                info->pid);
 
343
 
 
344
        gtk_box_pack_start (GTK_BOX (cmd_hbox),label, FALSE, FALSE, 0);
 
345
 
 
346
 
 
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),
 
352
                                             GTK_SHADOW_IN);
 
353
 
 
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);
 
358
 
 
359
        gtk_box_pack_start (GTK_BOX (dialog_vbox), scrolled, TRUE, TRUE, 0);
 
360
        gtk_widget_show_all (scrolled);
 
361
 
 
362
        g_signal_connect (G_OBJECT (openfilesdialog), "response",
 
363
                          G_CALLBACK (close_openfiles_dialog), tree);
 
364
 
 
365
        gtk_widget_show_all (openfilesdialog);
 
366
 
 
367
        timer = g_timeout_add (5000, openfiles_timer, tree);
 
368
        g_object_set_data (G_OBJECT (tree), "timer", GUINT_TO_POINTER (timer));
 
369
 
 
370
        update_openfiles_dialog (tree);
 
371
 
 
372
}
 
373
 
 
374
 
 
375
void
 
376
create_openfiles_dialog (ProcData *procdata)
 
377
{
 
378
        gtk_tree_selection_selected_foreach (procdata->selection, create_single_openfiles_dialog,
 
379
                                             procdata);
 
380
}