~ubuntu-branches/ubuntu/utopic/pcmanfm/utopic

« back to all changes in this revision

Viewing changes to debian/patches/revert-new-IPC.patch

  • Committer: Package Import Robot
  • Author(s): Andrew Lee (李健秋)
  • Date: 2011-12-30 18:24:45 UTC
  • Revision ID: package-import@ubuntu.com-20111230182445-l2oyiktnzc5be7qs
Tags: 0.9.8-2
* Apply revert-new-IPC.patch(from Arch Linux). (Closes: #605760)
* Bumped Standards-Version to 3.9.2.
* Updating description: fix description-synopsis-starts-with-article.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
diff -Naur pcmanfm-20101030_10ae31a.orig/src/Makefile.am pcmanfm-20101030_10ae31a/src/Makefile.am
 
2
--- pcmanfm-20101030_10ae31a.orig/src/Makefile.am       2010-10-30 20:36:02.000000000 +0200
 
3
+++ pcmanfm-20101030_10ae31a/src/Makefile.am    2010-10-31 09:13:48.000000000 +0100
 
4
@@ -16,7 +16,6 @@
 
5
        pref.c pref.h \
 
6
        utils.c utils.h \
 
7
        gseal-gtk-compat.h \
 
8
-       single-inst.c single-inst.h \
 
9
        $(NULL)
 
10
 
 
11
 EXTRA_DIST= \
 
12
diff -Naur pcmanfm-20101030_10ae31a.orig/src/pcmanfm.c pcmanfm-20101030_10ae31a/src/pcmanfm.c
 
13
--- pcmanfm-20101030_10ae31a.orig/src/pcmanfm.c 2010-10-30 20:36:02.000000000 +0200
 
14
+++ pcmanfm-20101030_10ae31a/src/pcmanfm.c      2010-10-31 09:25:45.000000000 +0100
 
15
@@ -31,6 +31,8 @@
 
16
 #include <string.h>
 
17
 /* socket is used to keep single instance */
 
18
 #include <sys/types.h>
 
19
+#include <sys/socket.h>
 
20
+#include <sys/un.h>
 
21
 #include <signal.h>
 
22
 #include <unistd.h> /* for getcwd */
 
23
 
 
24
@@ -41,13 +43,14 @@
 
25
 #include "volume-manager.h"
 
26
 #include "pref.h"
 
27
 #include "pcmanfm.h"
 
28
-#include "single-inst.h"
 
29
+
 
30
+static int sock;
 
31
+GIOChannel* io_channel = NULL;
 
32
 
 
33
 static int signal_pipe[2] = {-1, -1};
 
34
 gboolean daemon_mode = FALSE;
 
35
 
 
36
 static char** files_to_open = NULL;
 
37
-static int n_files_to_open = 0;
 
38
 static char* profile = NULL;
 
39
 static gboolean no_desktop = FALSE;
 
40
 static gboolean show_desktop = FALSE;
 
41
@@ -80,25 +83,13 @@
 
42
     { NULL }
 
43
 };
 
44
 
 
45
-/* single instance command id */
 
46
-enum {
 
47
-    CMD_INVALID,
 
48
-    CMD_CWD,
 
49
-    CMD_PROFILE,
 
50
-    CMD_DESKTOP,
 
51
-    CMD_DESKTOP_OFF,
 
52
-    CMD_DAEMON_MODE,
 
53
-    CMD_DESKTOP_PREF,
 
54
-    CMD_SET_WALLPAPER,
 
55
-    CMD_WALLPAPER_MODE,
 
56
-    CMD_SHOW_PREF,
 
57
-    CMD_FILES_TO_OPEN,
 
58
-    CMD_EOF
 
59
-};
 
60
-
 
61
 static const char* valid_wallpaper_modes[] = {"color", "stretch", "fit", "center", "tile"};
 
62
 
 
63
+static gboolean single_instance_check();
 
64
+static void single_instance_finalize();
 
65
+static void get_socket_name(char* buf, int len);
 
66
 static gboolean pcmanfm_run();
 
67
+static gboolean on_socket_event(GIOChannel* ioc, GIOCondition cond, gpointer data);
 
68
 
 
69
 /* it's not safe to call gtk+ functions in unix signal handler
 
70
  * since the process is interrupted here and the state of gtk+ is unpredictable. */
 
71
@@ -121,97 +112,6 @@
 
72
     return TRUE;
 
73
 }
 
74
 
 
75
-static gboolean on_single_inst_command(int cmd, SingleInstCmdData* data)
 
76
-{
 
77
-    switch(cmd)
 
78
-    {
 
79
-    case CMD_CWD:
 
80
-        g_free(ipc_cwd);
 
81
-        ipc_cwd = single_inst_get_str(data, NULL);
 
82
-        break;
 
83
-    case CMD_PROFILE:
 
84
-        /* Not supported */
 
85
-        break;
 
86
-    case CMD_DESKTOP:
 
87
-        single_inst_get_bool(data, &show_desktop);
 
88
-        break;
 
89
-    case CMD_DESKTOP_OFF:
 
90
-        single_inst_get_bool(data, &desktop_off);
 
91
-        break;
 
92
-    case CMD_DAEMON_MODE:
 
93
-        /* Not supported */
 
94
-        break;
 
95
-    case CMD_DESKTOP_PREF:
 
96
-        single_inst_get_bool(data, &desktop_pref);
 
97
-        break;
 
98
-    case CMD_SET_WALLPAPER:
 
99
-        g_free(set_wallpaper);
 
100
-        set_wallpaper = single_inst_get_str(data, NULL);
 
101
-        break;
 
102
-    case CMD_WALLPAPER_MODE:
 
103
-        g_free(wallpaper_mode);
 
104
-        wallpaper_mode = single_inst_get_str(data, NULL);
 
105
-        break;
 
106
-    case CMD_SHOW_PREF:
 
107
-        single_inst_get_int(data, &show_pref);
 
108
-        break;
 
109
-    case CMD_FILES_TO_OPEN:
 
110
-        {
 
111
-            g_strfreev(files_to_open);
 
112
-            n_files_to_open = 0;
 
113
-            files_to_open = single_inst_get_strv(data, &n_files_to_open);
 
114
-        }
 
115
-        break;
 
116
-    case CMD_EOF:
 
117
-        {
 
118
-            int i;
 
119
-            /* canonicalize filename if needed. */
 
120
-            for(i = 0; i < n_files_to_open; ++i)
 
121
-            {
 
122
-                char* file = files_to_open[i];
 
123
-                char* scheme = g_uri_parse_scheme(file);
 
124
-                if(scheme) /* a valid URI */
 
125
-                {
 
126
-                    /* FIXME: should we canonicalize URIs? and how about file:///? */
 
127
-                    g_free(scheme);
 
128
-                }
 
129
-                else /* a file path */
 
130
-                {
 
131
-                    files_to_open[i] = fm_canonicalize_filename(file, ipc_cwd);
 
132
-                    g_free(file);
 
133
-                }
 
134
-            }
 
135
-
 
136
-            /* handle the parsed result and run the main program */
 
137
-            pcmanfm_run();
 
138
-        }
 
139
-        break;
 
140
-    }
 
141
-    return TRUE;
 
142
-}
 
143
-
 
144
-/* we're not the first instance. pass the argv to the existing one. */
 
145
-static void pass_args_to_existing_instance()
 
146
-{
 
147
-    /* send our current working dir to existing instance via IPC. */
 
148
-    ipc_cwd = g_get_current_dir();
 
149
-    single_inst_send_str(CMD_CWD, ipc_cwd);
 
150
-    g_free(ipc_cwd);
 
151
-
 
152
-    single_inst_send_bool(CMD_DESKTOP, show_desktop);
 
153
-    single_inst_send_bool(CMD_DESKTOP_OFF, desktop_off);
 
154
-    single_inst_send_bool(CMD_DESKTOP_PREF, desktop_pref);
 
155
-    single_inst_send_str(CMD_SET_WALLPAPER, set_wallpaper);
 
156
-    single_inst_send_str(CMD_WALLPAPER_MODE, wallpaper_mode);
 
157
-    single_inst_send_int(CMD_SHOW_PREF, show_pref);
 
158
-    /* single_inst_send_bool(CMD_FIND_FILES, find_files); */
 
159
-
 
160
-    single_inst_send_strv(CMD_FILES_TO_OPEN, files_to_open);
 
161
-    single_inst_send_bool(CMD_EOF, TRUE); /* all args have been sent. */
 
162
-
 
163
-    single_inst_finalize();
 
164
-}
 
165
-
 
166
 int main(int argc, char** argv)
 
167
 {
 
168
     FmConfig* config;
 
169
@@ -230,17 +130,10 @@
 
170
         return 1;
 
171
     }
 
172
 
 
173
-    /* ensure that there is only one instance of pcmanfm. */
 
174
-    switch(single_inst_init("pcmanfm", on_single_inst_command))
 
175
-    {
 
176
-    case SINGLE_INST_CLIENT: /* we're not the first instance. */
 
177
-        pass_args_to_existing_instance();
 
178
-        gdk_notify_startup_complete();
 
179
-        return 0;
 
180
-    case SINGLE_INST_ERROR: /* error happened. */
 
181
-        single_inst_finalize();
 
182
-        return 1;
 
183
-    }
 
184
+    /* ensure that there is only one instance of pcmanfm.
 
185
+         if there is an existing instance, command line arguments
 
186
+         will be passed to the existing instance, and exit() will be called here.  */
 
187
+    single_instance_check();
 
188
 
 
189
     if(pipe(signal_pipe) == 0)
 
190
     {
 
191
@@ -274,13 +167,240 @@
 
192
         fm_volume_manager_finalize();
 
193
     }
 
194
 
 
195
-    single_inst_finalize();
 
196
+    single_instance_finalize();
 
197
+
 
198
     fm_gtk_finalize();
 
199
 
 
200
     g_object_unref(config);
 
201
     return 0;
 
202
 }
 
203
 
 
204
+inline static void buf_append_str(GByteArray* buf, const char* str)
 
205
+{
 
206
+    int len;
 
207
+    if(G_LIKELY(str))
 
208
+    {
 
209
+        len = strlen(str) + 1;
 
210
+        g_byte_array_append(buf, (guint8*)&len, sizeof(len));
 
211
+        g_byte_array_append(buf, (guint8*)str, len);
 
212
+    }
 
213
+    else
 
214
+    {
 
215
+        len = 0;
 
216
+        g_byte_array_append(buf, (guint8*)&len, sizeof(len));
 
217
+    }
 
218
+}
 
219
+
 
220
+inline static GByteArray* args_to_ipc_buf()
 
221
+{
 
222
+    int i, len;
 
223
+    GByteArray* buf = g_byte_array_sized_new(4096);
 
224
+    /* send our current working dir to existing instance via IPC. */
 
225
+    ipc_cwd = g_get_current_dir();
 
226
+    buf_append_str(buf, ipc_cwd);
 
227
+    g_free(ipc_cwd);
 
228
+
 
229
+    /* g_byte_array_append(buf, (guint8*)&new_tab, sizeof(new_tab)); */
 
230
+    g_byte_array_append(buf, (guint8*)&show_desktop, sizeof(show_desktop));
 
231
+    g_byte_array_append(buf, (guint8*)&desktop_off, sizeof(desktop_off));
 
232
+    g_byte_array_append(buf, (guint8*)&desktop_pref, sizeof(desktop_pref));
 
233
+    buf_append_str(buf, set_wallpaper);
 
234
+    buf_append_str(buf, wallpaper_mode);
 
235
+    g_byte_array_append(buf, (guint8*)&show_pref, sizeof(show_pref));
 
236
+    g_byte_array_append(buf, (guint8*)&find_files, sizeof(find_files));
 
237
+    g_byte_array_append(buf, (guint8*)&no_desktop, sizeof(no_desktop));
 
238
+
 
239
+    len = files_to_open ? g_strv_length(files_to_open) : 0;
 
240
+    g_byte_array_append(buf, (guint8*)&len, sizeof(len));
 
241
+    for(i = 0; i < len; ++i)
 
242
+        buf_append_str(buf, files_to_open[i]);
 
243
+
 
244
+    return buf;
 
245
+}
 
246
+
 
247
+inline static gboolean buf_read_bool(const char**p)
 
248
+{
 
249
+    gboolean ret;
 
250
+    memcpy(&ret, *p, sizeof(ret));
 
251
+    *p += sizeof(ret);
 
252
+    return ret;
 
253
+}
 
254
+
 
255
+inline static int buf_read_int(const char**p)
 
256
+{
 
257
+    int ret;
 
258
+    memcpy(&ret, *p, sizeof(ret));
 
259
+    *p += sizeof(ret);
 
260
+    return ret;
 
261
+}
 
262
+
 
263
+inline static char* buf_read_str(const char**p)
 
264
+{
 
265
+    char* ret;
 
266
+    int len = buf_read_int(p);
 
267
+    if(len > 0)
 
268
+    {
 
269
+        ret = g_malloc(len);
 
270
+        memcpy(ret, *p, len);
 
271
+        *p += len;
 
272
+    }
 
273
+    else
 
274
+        ret = NULL;
 
275
+    return ret;
 
276
+}
 
277
+
 
278
+inline static void ipc_buf_to_args(GByteArray* buf)
 
279
+{
 
280
+    int i, len;
 
281
+    char* p = buf->data;
 
282
+    char* cwd = buf_read_str(&p);
 
283
+    /* new_tab = buf_read_bool(&p); */
 
284
+    show_desktop = buf_read_bool(&p);
 
285
+    desktop_off = buf_read_bool(&p);
 
286
+    desktop_pref = buf_read_bool(&p);
 
287
+    g_free(set_wallpaper);
 
288
+    set_wallpaper = buf_read_str(&p);
 
289
+    g_free(wallpaper_mode);
 
290
+    wallpaper_mode = buf_read_str(&p);
 
291
+    show_pref = buf_read_int(&p);
 
292
+    find_files = buf_read_bool(&p);
 
293
+    no_desktop = buf_read_bool(&p);
 
294
+
 
295
+    len = buf_read_int(&p);
 
296
+    /* g_debug("len = %d", len); */
 
297
+    if(len > 0)
 
298
+    {
 
299
+        files_to_open = g_new(char*, len + 1);
 
300
+        for(i = 0; i < len; ++i)
 
301
+        {
 
302
+            char* file = buf_read_str(&p);
 
303
+            char* scheme = g_uri_parse_scheme(file);
 
304
+            if(scheme) /* a valid URI */
 
305
+            {
 
306
+                /* FIXME: should we canonicalize URIs? and how about file:///? */
 
307
+                files_to_open[i] = file;
 
308
+                g_free(scheme);
 
309
+            }
 
310
+            else /* a file path */
 
311
+            {
 
312
+                files_to_open[i] = fm_canonicalize_filename(file, cwd);
 
313
+                g_free(file);
 
314
+            }
 
315
+        }
 
316
+        files_to_open[i] = NULL;
 
317
+    }
 
318
+    else
 
319
+        files_to_open = NULL;
 
320
+    g_free(cwd);
 
321
+}
 
322
+
 
323
+gboolean on_socket_event( GIOChannel* ioc, GIOCondition cond, gpointer data )
 
324
+{
 
325
+    int client, r;
 
326
+    socklen_t addr_len = 0;
 
327
+    struct sockaddr_un client_addr ={ 0 };
 
328
+    static char buf[ 1024 ];
 
329
+    GByteArray* args;
 
330
+
 
331
+    if ( cond & G_IO_IN )
 
332
+    {
 
333
+        client = accept( g_io_channel_unix_get_fd( ioc ), (struct sockaddr *)&client_addr, &addr_len );
 
334
+        if ( client != -1 )
 
335
+        {
 
336
+            args = g_byte_array_sized_new(4096);
 
337
+            while( (r = read( client, buf, sizeof(buf) )) > 0 )
 
338
+                g_byte_array_append( args, (guint8*)buf, r);
 
339
+            shutdown( client, 2 );
 
340
+            close( client );
 
341
+            ipc_buf_to_args(args);
 
342
+            g_byte_array_free( args, TRUE );
 
343
+            pcmanfm_run();
 
344
+        }
 
345
+    }
 
346
+    return TRUE;
 
347
+}
 
348
+
 
349
+void get_socket_name( char* buf, int len )
 
350
+{
 
351
+    char* dpy = gdk_get_display();
 
352
+    g_snprintf( buf, len, "/tmp/.pcmanfm-socket%s-%s", dpy, g_get_user_name() );
 
353
+    g_free( dpy );
 
354
+}
 
355
+
 
356
+gboolean single_instance_check()
 
357
+{
 
358
+    struct sockaddr_un addr;
 
359
+    int addr_len;
 
360
+    int ret;
 
361
+    int reuse;
 
362
+
 
363
+    if((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
 
364
+    {
 
365
+        ret = 1;
 
366
+        goto _exit;
 
367
+    }
 
368
+
 
369
+    /* FIXME: use abstract socket */
 
370
+    addr.sun_family = AF_UNIX;
 
371
+    get_socket_name(addr.sun_path, sizeof( addr.sun_path ));
 
372
+#ifdef SUN_LEN
 
373
+    addr_len = SUN_LEN(&addr);
 
374
+#else
 
375
+    addr_len = strlen( addr.sun_path ) + sizeof( addr.sun_family );
 
376
+#endif
 
377
+
 
378
+    /* try to connect to existing instance */
 
379
+    if(connect(sock, (struct sockaddr*)&addr, addr_len) == 0)
 
380
+    {
 
381
+        /* connected successfully */
 
382
+        GByteArray* buf = args_to_ipc_buf();
 
383
+        write(sock, buf->data, buf->len);
 
384
+        g_byte_array_free(buf, TRUE);
 
385
+
 
386
+        shutdown( sock, 2 );
 
387
+        close( sock );
 
388
+        ret = 0;
 
389
+        goto _exit;
 
390
+    }
 
391
+
 
392
+    /* There is no existing server, and we are in the first instance. */
 
393
+    unlink( addr.sun_path ); /* delete old socket file if it exists. */
 
394
+    reuse = 1;
 
395
+    ret = setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse) );
 
396
+    if(bind(sock, (struct sockaddr*)&addr, addr_len) == -1)
 
397
+    {
 
398
+        ret = 1;
 
399
+        goto _exit;
 
400
+    }
 
401
+
 
402
+    io_channel = g_io_channel_unix_new(sock);
 
403
+    g_io_channel_set_encoding(io_channel, NULL, NULL);
 
404
+    g_io_channel_set_buffered(io_channel, FALSE);
 
405
+    g_io_add_watch(io_channel, G_IO_IN,
 
406
+                   (GIOFunc)on_socket_event, NULL);
 
407
+    if(listen(sock, 5) == -1)
 
408
+    {
 
409
+        ret = 1;
 
410
+        goto _exit;
 
411
+    }
 
412
+    return TRUE;
 
413
+
 
414
+_exit:
 
415
+
 
416
+    gdk_notify_startup_complete();
 
417
+    exit( ret );
 
418
+}
 
419
+
 
420
+void single_instance_finalize()
 
421
+{
 
422
+    char lock_file[256];
 
423
+    shutdown(sock, 2);
 
424
+    g_io_channel_unref(io_channel);
 
425
+    close(sock);
 
426
+    get_socket_name(lock_file, sizeof( lock_file ));
 
427
+    unlink(lock_file);
 
428
+}
 
429
+
 
430
 static FmJobErrorAction on_file_info_job_error(FmFileInfoJob* job, GError* err, FmJobErrorSeverity severity, gpointer user_data)
 
431
 {
 
432
     if(err->domain == G_IO_ERROR)