~ubuntu-branches/ubuntu/oneiric/gnome-system-monitor/oneiric-proposed

« back to all changes in this revision

Viewing changes to src/lsof.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2006-11-09 17:52:49 UTC
  • mto: (2.1.2 lenny) (1.1.57 upstream)
  • mto: This revision was merged to the branch mainline in revision 21.
  • Revision ID: james.westby@ubuntu.com-20061109175249-wnmejquq0y6eob89
Tags: upstream-2.17.2.1
ImportĀ upstreamĀ versionĀ 2.17.2.1

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
 
 
6
#include <set>
 
7
#include <string>
 
8
#include <sstream>
 
9
#include <iterator>
 
10
 
 
11
#include <pcrecpp.h>
 
12
 
 
13
extern "C" {
 
14
#include "procman.h"
 
15
#include "lsof.h"
 
16
#include "util.h"
 
17
}
 
18
 
 
19
 
 
20
using std::string;
 
21
 
 
22
 
 
23
namespace
 
24
{
 
25
 
 
26
  class LsofBase
 
27
  {
 
28
    virtual bool matches(const string &filename) const = 0;
 
29
 
 
30
  public:
 
31
 
 
32
    virtual ~LsofBase()
 
33
    { }
 
34
 
 
35
 
 
36
    template<typename OutputIterator>
 
37
    void search(const ProcInfo &info, OutputIterator out) const
 
38
    {
 
39
      glibtop_open_files_entry *entries;
 
40
      glibtop_proc_open_files buf;
 
41
 
 
42
      entries = glibtop_get_proc_open_files(&buf, info.pid);
 
43
 
 
44
      for (unsigned i = 0; i != buf.number; ++i) {
 
45
        if (entries[i].type & GLIBTOP_FILE_TYPE_FILE) {
 
46
          const string filename(entries[i].info.file.name);
 
47
          if (this->matches(filename))
 
48
            *out++ = filename;
 
49
        }
 
50
      }
 
51
 
 
52
      g_free(entries);
 
53
    }
 
54
  };
 
55
 
 
56
 
 
57
#ifdef FOOBAR
 
58
 
 
59
  class Lsof
 
60
    : public LsofBase
 
61
  {
 
62
    string pattern;
 
63
    bool caseless;
 
64
 
 
65
    virtual bool matches(const string &filename) const
 
66
    {
 
67
      if (this->caseless) {
 
68
        char *cp, *cf;
 
69
        cp = g_utf8_strdown(this->pattern.c_str(), -1);
 
70
        cf = g_utf8_strdown(filename.c_str(), -1);
 
71
        string p(cp), f(cf);
 
72
        g_free(cp);
 
73
        g_free(cf);
 
74
        return f.find(p) != string::npos;
 
75
      }
 
76
 
 
77
      return filename.find(this->pattern) != string::npos;
 
78
    }
 
79
 
 
80
  public:
 
81
 
 
82
    Lsof(const string &pattern, bool caseless)
 
83
      : pattern(pattern), caseless(caseless)
 
84
    { }
 
85
  };
 
86
 
 
87
#else
 
88
 
 
89
  class Lsof
 
90
    : public LsofBase
 
91
  {
 
92
    pcrecpp::RE re;
 
93
 
 
94
    virtual bool matches(const string &filename) const
 
95
    {
 
96
      return this->re.PartialMatch(filename);
 
97
    }
 
98
 
 
99
  public:
 
100
 
 
101
    Lsof(const string &pattern, bool caseless)
 
102
      : re(pattern, pcrecpp::RE_Options().set_caseless(caseless).set_utf8(true))
 
103
    { }
 
104
  };
 
105
 
 
106
#endif
 
107
 
 
108
 
 
109
 
 
110
  // GUI Stuff
 
111
 
 
112
 
 
113
  enum ProcmanLsof {
 
114
    PROCMAN_LSOF_COL_PIXBUF,
 
115
    PROCMAN_LSOF_COL_PROCESS,
 
116
    PROCMAN_LSOF_COL_PID,
 
117
    PROCMAN_LSOF_COL_FILENAME,
 
118
    PROCMAN_LSOF_NCOLS
 
119
  };
 
120
 
 
121
 
 
122
  struct GUI {
 
123
 
 
124
    GtkListStore *model;
 
125
    GtkEntry *entry;
 
126
    GtkWindow *window;
 
127
    GtkLabel *count;
 
128
    ProcData *procdata;
 
129
    bool case_insensitive;
 
130
 
 
131
 
 
132
    GUI()
 
133
    {
 
134
      procman_debug("New Lsof GUI %p", this);
 
135
    }
 
136
 
 
137
 
 
138
    ~GUI()
 
139
    {
 
140
      procman_debug("Destroying Lsof GUI %p", this);
 
141
    }
 
142
 
 
143
 
 
144
    void clear_results()
 
145
    {
 
146
      gtk_list_store_clear(this->model);
 
147
      gtk_label_set_text(this->count, "");
 
148
    }
 
149
 
 
150
 
 
151
    void clear()
 
152
    {
 
153
      this->clear_results();
 
154
      gtk_entry_set_text(this->entry, "");
 
155
    }
 
156
 
 
157
 
 
158
    void update_count(unsigned count)
 
159
    {
 
160
      string s = static_cast<std::ostringstream&>(std::ostringstream() << count).str();
 
161
      gtk_label_set_text(this->count, s.c_str());
 
162
    }
 
163
 
 
164
 
 
165
    string pattern() const
 
166
    {
 
167
      return gtk_entry_get_text(this->entry);
 
168
    }
 
169
 
 
170
 
 
171
    void search()
 
172
    {
 
173
      typedef std::set<string> MatchSet;
 
174
      typedef MatchSet::const_iterator iterator;
 
175
 
 
176
      this->clear_results();
 
177
 
 
178
      Lsof lsof(this->pattern(), this->case_insensitive);
 
179
      // lsof = new SimpleLsof(this->pattern(), this->case_insensitive);
 
180
      unsigned count = 0;
 
181
 
 
182
      for (GList *i = this->procdata->info; i; i = i->next) {
 
183
        ProcInfo &info(*static_cast<ProcInfo*>(i->data));
 
184
 
 
185
        MatchSet matches;
 
186
        lsof.search(info, std::inserter(matches, matches.begin()));
 
187
        count += matches.size();
 
188
 
 
189
        for (iterator it(matches.begin()), end(matches.end()); it != end; ++it) {
 
190
          GtkTreeIter file;
 
191
          gtk_list_store_append(this->model, &file);
 
192
          gtk_list_store_set(this->model, &file,
 
193
                             PROCMAN_LSOF_COL_PIXBUF, info.pixbuf,
 
194
                             PROCMAN_LSOF_COL_PROCESS, info.name,
 
195
                             PROCMAN_LSOF_COL_PID, info.pid,
 
196
                             PROCMAN_LSOF_COL_FILENAME, it->c_str(),
 
197
                             -1);
 
198
        }
 
199
      }
 
200
 
 
201
      this->update_count(count);
 
202
    }
 
203
 
 
204
 
 
205
    static void search_button_clicked(GtkButton *, gpointer data)
 
206
    {
 
207
      static_cast<GUI*>(data)->search();
 
208
    }
 
209
 
 
210
 
 
211
    static void clear_button_clicked(GtkButton *, gpointer data)
 
212
    {
 
213
      static_cast<GUI*>(data)->clear();
 
214
    }
 
215
 
 
216
 
 
217
    static void close_button_clicked(GtkButton *, gpointer data)
 
218
    {
 
219
      GUI *gui = static_cast<GUI*>(data);
 
220
      gtk_widget_destroy(GTK_WIDGET(gui->window));
 
221
      delete gui;
 
222
    }
 
223
 
 
224
 
 
225
    static void case_button_toggled(GtkToggleButton *button, gpointer data)
 
226
    {
 
227
      bool state = gtk_toggle_button_get_active(button);
 
228
      static_cast<GUI*>(data)->case_insensitive = state;
 
229
    }
 
230
 
 
231
 
 
232
    static gboolean window_delete_event(GtkWidget *, GdkEvent *, gpointer data)
 
233
    {
 
234
      delete static_cast<GUI*>(data);
 
235
      return FALSE;
 
236
    }
 
237
 
 
238
  };
 
239
}
 
240
 
 
241
 
 
242
 
 
243
 
 
244
void procman_lsof(ProcData *procdata)
 
245
{
 
246
  GtkListStore *model = \
 
247
    gtk_list_store_new(PROCMAN_LSOF_NCOLS,
 
248
                       GDK_TYPE_PIXBUF, // PROCMAN_LSOF_COL_PIXBUF
 
249
                       G_TYPE_STRING,   // PROCMAN_LSOF_COL_PROCESS
 
250
                       G_TYPE_UINT,     // PROCMAN_LSOF_COL_PID
 
251
                       G_TYPE_STRING    // PROCMAN_LSOF_COL_FILENAME
 
252
                       );
 
253
 
 
254
  GtkWidget *tree = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model));
 
255
  g_object_unref(model);
 
256
  gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(tree), TRUE);
 
257
 
 
258
 
 
259
  GtkTreeViewColumn *column;
 
260
  GtkCellRenderer *renderer;
 
261
 
 
262
  // PIXBUF / PROCESS
 
263
 
 
264
  column = gtk_tree_view_column_new();
 
265
 
 
266
  renderer = gtk_cell_renderer_pixbuf_new();
 
267
  gtk_tree_view_column_pack_start(column, renderer, FALSE);
 
268
  gtk_tree_view_column_set_attributes(column, renderer,
 
269
                                      "pixbuf", PROCMAN_LSOF_COL_PIXBUF,
 
270
                                      NULL);
 
271
 
 
272
  renderer = gtk_cell_renderer_text_new();
 
273
  gtk_tree_view_column_pack_start(column, renderer, FALSE);
 
274
  gtk_tree_view_column_set_attributes(column, renderer,
 
275
                                      "text", PROCMAN_LSOF_COL_PROCESS,
 
276
                                      NULL);
 
277
 
 
278
  gtk_tree_view_column_set_title(column, _("Process"));
 
279
  gtk_tree_view_column_set_sort_column_id(column, PROCMAN_LSOF_COL_PROCESS);
 
280
  gtk_tree_view_column_set_resizable(column, TRUE);
 
281
  gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_GROW_ONLY);
 
282
  gtk_tree_view_column_set_min_width(column, 10);
 
283
  gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
 
284
  gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model), PROCMAN_LSOF_COL_PROCESS,
 
285
                                       GTK_SORT_ASCENDING);
 
286
 
 
287
 
 
288
  // PID
 
289
  renderer = gtk_cell_renderer_text_new();
 
290
  column = gtk_tree_view_column_new_with_attributes(_("PID"), renderer,
 
291
                                                    "text", PROCMAN_LSOF_COL_PID,
 
292
                                                    NULL);
 
293
  gtk_tree_view_column_set_sort_column_id(column, PROCMAN_LSOF_COL_PID);
 
294
  gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_GROW_ONLY);
 
295
  gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
 
296
 
 
297
 
 
298
  // FILENAME
 
299
  renderer = gtk_cell_renderer_text_new();
 
300
  column = gtk_tree_view_column_new_with_attributes(_("Filename"), renderer,
 
301
                                                    "text", PROCMAN_LSOF_COL_FILENAME,
 
302
                                                    NULL);
 
303
  gtk_tree_view_column_set_sort_column_id(column, PROCMAN_LSOF_COL_FILENAME);
 
304
  gtk_tree_view_column_set_resizable(column, TRUE);
 
305
  gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
 
306
  gtk_tree_view_append_column(GTK_TREE_VIEW(tree), column);
 
307
 
 
308
 
 
309
  GtkWidget *dialog; /* = gtk_dialog_new_with_buttons(_("Search for Open Files"), NULL,
 
310
                        GTK_DIALOG_DESTROY_WITH_PARENT,
 
311
                        GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
 
312
                        NULL); */
 
313
  dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 
314
  gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(procdata->app));
 
315
  gtk_window_set_destroy_with_parent(GTK_WINDOW(dialog), TRUE);
 
316
  // gtk_window_set_modal(GTK_WINDOW(dialog), TRUE);
 
317
  gtk_window_set_title(GTK_WINDOW(dialog), _("Search for Open Files"));
 
318
 
 
319
  // g_signal_connect(G_OBJECT(dialog), "response",
 
320
  //               G_CALLBACK(close_dialog), NULL);
 
321
  gtk_window_set_resizable(GTK_WINDOW(dialog), TRUE);
 
322
  gtk_window_set_default_size(GTK_WINDOW(dialog), 575, 400);
 
323
  // gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
 
324
  gtk_container_set_border_width(GTK_CONTAINER(dialog), 12);
 
325
  GtkWidget *mainbox = gtk_vbox_new(FALSE, 12);
 
326
  gtk_container_add(GTK_CONTAINER(dialog), mainbox);
 
327
  gtk_box_set_spacing(GTK_BOX(mainbox), 6);
 
328
 
 
329
 
 
330
  // Label, entry and search button
 
331
 
 
332
  GtkWidget *hbox1 = gtk_hbox_new(FALSE, 12);
 
333
  gtk_box_pack_start(GTK_BOX(mainbox), hbox1, FALSE, FALSE, 0);
 
334
 
 
335
  GtkWidget *image = gtk_image_new_from_stock(GTK_STOCK_FIND, GTK_ICON_SIZE_DIALOG);
 
336
  gtk_box_pack_start(GTK_BOX(hbox1), image, FALSE, FALSE, 0);
 
337
 
 
338
 
 
339
  GtkWidget *vbox2 = gtk_vbox_new(FALSE, 12);
 
340
  gtk_box_pack_start(GTK_BOX(hbox1), vbox2, TRUE, TRUE, 0);
 
341
 
 
342
 
 
343
  GtkWidget *hbox = gtk_hbox_new(FALSE, 12);
 
344
  gtk_box_pack_start(GTK_BOX(vbox2), hbox, TRUE, TRUE, 0);
 
345
  GtkWidget *label = gtk_label_new_with_mnemonic(_("_Name contains:"));
 
346
  gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
 
347
  GtkWidget *entry = gtk_entry_new();
 
348
  gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 0);
 
349
  GtkWidget *search_button = gtk_button_new_from_stock(GTK_STOCK_FIND);
 
350
  gtk_box_pack_start(GTK_BOX(hbox), search_button, FALSE, FALSE, 0);
 
351
  GtkWidget *clear_button = gtk_button_new_from_stock(GTK_STOCK_CLEAR);
 
352
  gtk_box_pack_start(GTK_BOX(hbox), clear_button, FALSE, FALSE, 0);
 
353
 
 
354
  // g_object_set(G_OBJECT(dialog), "activates_default", TRUE, NULL);
 
355
  // gtk_window_set_default(GTK_WINDOW(dialog), GTK_WIDGET(search_button));
 
356
 
 
357
 
 
358
  GtkWidget *case_button = gtk_check_button_new_with_mnemonic(_("Case insensitive matching"));
 
359
  GtkWidget *hbox3 = gtk_hbox_new(FALSE, 12);
 
360
  gtk_box_pack_start(GTK_BOX(hbox3), case_button, FALSE, FALSE, 0);
 
361
  gtk_box_pack_start(GTK_BOX(vbox2), hbox3, FALSE, FALSE, 0);
 
362
 
 
363
 
 
364
  GtkWidget *results_box = gtk_hbox_new(FALSE, 12);
 
365
  gtk_box_pack_start(GTK_BOX(mainbox), results_box, FALSE, FALSE, 0);
 
366
  GtkWidget *results_label = gtk_label_new_with_mnemonic(_("S_earch results:"));
 
367
  gtk_box_pack_start(GTK_BOX(results_box), results_label, FALSE, FALSE, 0);
 
368
  GtkWidget *count_label = gtk_label_new(NULL);
 
369
  gtk_box_pack_end(GTK_BOX(results_box), count_label, FALSE, FALSE, 0);
 
370
 
 
371
 
 
372
 
 
373
 
 
374
  // Scrolled TreeView
 
375
  GtkWidget *scrolled = gtk_scrolled_window_new(NULL, NULL);
 
376
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
 
377
                                 GTK_POLICY_AUTOMATIC,
 
378
                                 GTK_POLICY_AUTOMATIC);
 
379
  gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled),
 
380
                                      GTK_SHADOW_IN);
 
381
  gtk_container_add(GTK_CONTAINER(scrolled), tree);
 
382
  gtk_box_pack_start(GTK_BOX(mainbox), scrolled, TRUE, TRUE, 0);
 
383
 
 
384
  GtkWidget *bottom_box = gtk_hbox_new(FALSE, 12);
 
385
  GtkWidget *close_button = gtk_button_new_from_stock(GTK_STOCK_CLOSE);
 
386
  gtk_box_pack_start(GTK_BOX(mainbox), bottom_box, FALSE, FALSE, 0);
 
387
  gtk_box_pack_end(GTK_BOX(bottom_box), close_button, FALSE, FALSE, 0);
 
388
 
 
389
 
 
390
  GUI *gui = new GUI; // wil be deleted by the close button or delete-event
 
391
  gui->procdata = procdata;
 
392
  gui->model = model;
 
393
  gui->window = GTK_WINDOW(dialog);
 
394
  gui->entry = GTK_ENTRY(entry);
 
395
  gui->count = GTK_LABEL(count_label);
 
396
 
 
397
  g_signal_connect(G_OBJECT(clear_button), "clicked",
 
398
                   G_CALLBACK(GUI::clear_button_clicked), gui);
 
399
  g_signal_connect(G_OBJECT(search_button), "clicked",
 
400
                   G_CALLBACK(GUI::search_button_clicked), gui);
 
401
  g_signal_connect(G_OBJECT(close_button), "clicked",
 
402
                   G_CALLBACK(GUI::close_button_clicked), gui);
 
403
  g_signal_connect(G_OBJECT(case_button), "toggled",
 
404
                   G_CALLBACK(GUI::case_button_toggled), gui);
 
405
  g_signal_connect(G_OBJECT(dialog), "delete-event",
 
406
                   G_CALLBACK(GUI::window_delete_event), gui);
 
407
 
 
408
 
 
409
  gtk_widget_show_all(dialog);
 
410
}
 
411