summaryrefslogtreecommitdiff
path: root/extra/pcmanfm/revert-new-IPC.patch
diff options
context:
space:
mode:
Diffstat (limited to 'extra/pcmanfm/revert-new-IPC.patch')
-rw-r--r--extra/pcmanfm/revert-new-IPC.patch432
1 files changed, 432 insertions, 0 deletions
diff --git a/extra/pcmanfm/revert-new-IPC.patch b/extra/pcmanfm/revert-new-IPC.patch
new file mode 100644
index 000000000..fa64fde42
--- /dev/null
+++ b/extra/pcmanfm/revert-new-IPC.patch
@@ -0,0 +1,432 @@
+diff -Naur pcmanfm-20101030_10ae31a.orig/src/Makefile.am pcmanfm-20101030_10ae31a/src/Makefile.am
+--- pcmanfm-20101030_10ae31a.orig/src/Makefile.am 2010-10-30 20:36:02.000000000 +0200
++++ pcmanfm-20101030_10ae31a/src/Makefile.am 2010-10-31 09:13:48.000000000 +0100
+@@ -16,7 +16,6 @@
+ pref.c pref.h \
+ utils.c utils.h \
+ gseal-gtk-compat.h \
+- single-inst.c single-inst.h \
+ $(NULL)
+
+ EXTRA_DIST= \
+diff -Naur pcmanfm-20101030_10ae31a.orig/src/pcmanfm.c pcmanfm-20101030_10ae31a/src/pcmanfm.c
+--- pcmanfm-20101030_10ae31a.orig/src/pcmanfm.c 2010-10-30 20:36:02.000000000 +0200
++++ pcmanfm-20101030_10ae31a/src/pcmanfm.c 2010-10-31 09:25:45.000000000 +0100
+@@ -31,6 +31,8 @@
+ #include <string.h>
+ /* socket is used to keep single instance */
+ #include <sys/types.h>
++#include <sys/socket.h>
++#include <sys/un.h>
+ #include <signal.h>
+ #include <unistd.h> /* for getcwd */
+
+@@ -41,13 +43,14 @@
+ #include "volume-manager.h"
+ #include "pref.h"
+ #include "pcmanfm.h"
+-#include "single-inst.h"
++
++static int sock;
++GIOChannel* io_channel = NULL;
+
+ static int signal_pipe[2] = {-1, -1};
+ gboolean daemon_mode = FALSE;
+
+ static char** files_to_open = NULL;
+-static int n_files_to_open = 0;
+ static char* profile = NULL;
+ static gboolean no_desktop = FALSE;
+ static gboolean show_desktop = FALSE;
+@@ -80,25 +83,13 @@
+ { NULL }
+ };
+
+-/* single instance command id */
+-enum {
+- CMD_INVALID,
+- CMD_CWD,
+- CMD_PROFILE,
+- CMD_DESKTOP,
+- CMD_DESKTOP_OFF,
+- CMD_DAEMON_MODE,
+- CMD_DESKTOP_PREF,
+- CMD_SET_WALLPAPER,
+- CMD_WALLPAPER_MODE,
+- CMD_SHOW_PREF,
+- CMD_FILES_TO_OPEN,
+- CMD_EOF
+-};
+-
+ static const char* valid_wallpaper_modes[] = {"color", "stretch", "fit", "center", "tile"};
+
++static gboolean single_instance_check();
++static void single_instance_finalize();
++static void get_socket_name(char* buf, int len);
+ static gboolean pcmanfm_run();
++static gboolean on_socket_event(GIOChannel* ioc, GIOCondition cond, gpointer data);
+
+ /* it's not safe to call gtk+ functions in unix signal handler
+ * since the process is interrupted here and the state of gtk+ is unpredictable. */
+@@ -121,97 +112,6 @@
+ return TRUE;
+ }
+
+-static gboolean on_single_inst_command(int cmd, SingleInstCmdData* data)
+-{
+- switch(cmd)
+- {
+- case CMD_CWD:
+- g_free(ipc_cwd);
+- ipc_cwd = single_inst_get_str(data, NULL);
+- break;
+- case CMD_PROFILE:
+- /* Not supported */
+- break;
+- case CMD_DESKTOP:
+- single_inst_get_bool(data, &show_desktop);
+- break;
+- case CMD_DESKTOP_OFF:
+- single_inst_get_bool(data, &desktop_off);
+- break;
+- case CMD_DAEMON_MODE:
+- /* Not supported */
+- break;
+- case CMD_DESKTOP_PREF:
+- single_inst_get_bool(data, &desktop_pref);
+- break;
+- case CMD_SET_WALLPAPER:
+- g_free(set_wallpaper);
+- set_wallpaper = single_inst_get_str(data, NULL);
+- break;
+- case CMD_WALLPAPER_MODE:
+- g_free(wallpaper_mode);
+- wallpaper_mode = single_inst_get_str(data, NULL);
+- break;
+- case CMD_SHOW_PREF:
+- single_inst_get_int(data, &show_pref);
+- break;
+- case CMD_FILES_TO_OPEN:
+- {
+- g_strfreev(files_to_open);
+- n_files_to_open = 0;
+- files_to_open = single_inst_get_strv(data, &n_files_to_open);
+- }
+- break;
+- case CMD_EOF:
+- {
+- int i;
+- /* canonicalize filename if needed. */
+- for(i = 0; i < n_files_to_open; ++i)
+- {
+- char* file = files_to_open[i];
+- char* scheme = g_uri_parse_scheme(file);
+- if(scheme) /* a valid URI */
+- {
+- /* FIXME: should we canonicalize URIs? and how about file:///? */
+- g_free(scheme);
+- }
+- else /* a file path */
+- {
+- files_to_open[i] = fm_canonicalize_filename(file, ipc_cwd);
+- g_free(file);
+- }
+- }
+-
+- /* handle the parsed result and run the main program */
+- pcmanfm_run();
+- }
+- break;
+- }
+- return TRUE;
+-}
+-
+-/* we're not the first instance. pass the argv to the existing one. */
+-static void pass_args_to_existing_instance()
+-{
+- /* send our current working dir to existing instance via IPC. */
+- ipc_cwd = g_get_current_dir();
+- single_inst_send_str(CMD_CWD, ipc_cwd);
+- g_free(ipc_cwd);
+-
+- single_inst_send_bool(CMD_DESKTOP, show_desktop);
+- single_inst_send_bool(CMD_DESKTOP_OFF, desktop_off);
+- single_inst_send_bool(CMD_DESKTOP_PREF, desktop_pref);
+- single_inst_send_str(CMD_SET_WALLPAPER, set_wallpaper);
+- single_inst_send_str(CMD_WALLPAPER_MODE, wallpaper_mode);
+- single_inst_send_int(CMD_SHOW_PREF, show_pref);
+- /* single_inst_send_bool(CMD_FIND_FILES, find_files); */
+-
+- single_inst_send_strv(CMD_FILES_TO_OPEN, files_to_open);
+- single_inst_send_bool(CMD_EOF, TRUE); /* all args have been sent. */
+-
+- single_inst_finalize();
+-}
+-
+ int main(int argc, char** argv)
+ {
+ FmConfig* config;
+@@ -230,17 +130,10 @@
+ return 1;
+ }
+
+- /* ensure that there is only one instance of pcmanfm. */
+- switch(single_inst_init("pcmanfm", on_single_inst_command))
+- {
+- case SINGLE_INST_CLIENT: /* we're not the first instance. */
+- pass_args_to_existing_instance();
+- gdk_notify_startup_complete();
+- return 0;
+- case SINGLE_INST_ERROR: /* error happened. */
+- single_inst_finalize();
+- return 1;
+- }
++ /* ensure that there is only one instance of pcmanfm.
++ if there is an existing instance, command line arguments
++ will be passed to the existing instance, and exit() will be called here. */
++ single_instance_check();
+
+ if(pipe(signal_pipe) == 0)
+ {
+@@ -274,13 +167,240 @@
+ fm_volume_manager_finalize();
+ }
+
+- single_inst_finalize();
++ single_instance_finalize();
++
+ fm_gtk_finalize();
+
+ g_object_unref(config);
+ return 0;
+ }
+
++inline static void buf_append_str(GByteArray* buf, const char* str)
++{
++ int len;
++ if(G_LIKELY(str))
++ {
++ len = strlen(str) + 1;
++ g_byte_array_append(buf, (guint8*)&len, sizeof(len));
++ g_byte_array_append(buf, (guint8*)str, len);
++ }
++ else
++ {
++ len = 0;
++ g_byte_array_append(buf, (guint8*)&len, sizeof(len));
++ }
++}
++
++inline static GByteArray* args_to_ipc_buf()
++{
++ int i, len;
++ GByteArray* buf = g_byte_array_sized_new(4096);
++ /* send our current working dir to existing instance via IPC. */
++ ipc_cwd = g_get_current_dir();
++ buf_append_str(buf, ipc_cwd);
++ g_free(ipc_cwd);
++
++ /* g_byte_array_append(buf, (guint8*)&new_tab, sizeof(new_tab)); */
++ g_byte_array_append(buf, (guint8*)&show_desktop, sizeof(show_desktop));
++ g_byte_array_append(buf, (guint8*)&desktop_off, sizeof(desktop_off));
++ g_byte_array_append(buf, (guint8*)&desktop_pref, sizeof(desktop_pref));
++ buf_append_str(buf, set_wallpaper);
++ buf_append_str(buf, wallpaper_mode);
++ g_byte_array_append(buf, (guint8*)&show_pref, sizeof(show_pref));
++ g_byte_array_append(buf, (guint8*)&find_files, sizeof(find_files));
++ g_byte_array_append(buf, (guint8*)&no_desktop, sizeof(no_desktop));
++
++ len = files_to_open ? g_strv_length(files_to_open) : 0;
++ g_byte_array_append(buf, (guint8*)&len, sizeof(len));
++ for(i = 0; i < len; ++i)
++ buf_append_str(buf, files_to_open[i]);
++
++ return buf;
++}
++
++inline static gboolean buf_read_bool(const char**p)
++{
++ gboolean ret;
++ memcpy(&ret, *p, sizeof(ret));
++ *p += sizeof(ret);
++ return ret;
++}
++
++inline static int buf_read_int(const char**p)
++{
++ int ret;
++ memcpy(&ret, *p, sizeof(ret));
++ *p += sizeof(ret);
++ return ret;
++}
++
++inline static char* buf_read_str(const char**p)
++{
++ char* ret;
++ int len = buf_read_int(p);
++ if(len > 0)
++ {
++ ret = g_malloc(len);
++ memcpy(ret, *p, len);
++ *p += len;
++ }
++ else
++ ret = NULL;
++ return ret;
++}
++
++inline static void ipc_buf_to_args(GByteArray* buf)
++{
++ int i, len;
++ char* p = buf->data;
++ char* cwd = buf_read_str(&p);
++ /* new_tab = buf_read_bool(&p); */
++ show_desktop = buf_read_bool(&p);
++ desktop_off = buf_read_bool(&p);
++ desktop_pref = buf_read_bool(&p);
++ g_free(set_wallpaper);
++ set_wallpaper = buf_read_str(&p);
++ g_free(wallpaper_mode);
++ wallpaper_mode = buf_read_str(&p);
++ show_pref = buf_read_int(&p);
++ find_files = buf_read_bool(&p);
++ no_desktop = buf_read_bool(&p);
++
++ len = buf_read_int(&p);
++ /* g_debug("len = %d", len); */
++ if(len > 0)
++ {
++ files_to_open = g_new(char*, len + 1);
++ for(i = 0; i < len; ++i)
++ {
++ char* file = buf_read_str(&p);
++ char* scheme = g_uri_parse_scheme(file);
++ if(scheme) /* a valid URI */
++ {
++ /* FIXME: should we canonicalize URIs? and how about file:///? */
++ files_to_open[i] = file;
++ g_free(scheme);
++ }
++ else /* a file path */
++ {
++ files_to_open[i] = fm_canonicalize_filename(file, cwd);
++ g_free(file);
++ }
++ }
++ files_to_open[i] = NULL;
++ }
++ else
++ files_to_open = NULL;
++ g_free(cwd);
++}
++
++gboolean on_socket_event( GIOChannel* ioc, GIOCondition cond, gpointer data )
++{
++ int client, r;
++ socklen_t addr_len = 0;
++ struct sockaddr_un client_addr ={ 0 };
++ static char buf[ 1024 ];
++ GByteArray* args;
++
++ if ( cond & G_IO_IN )
++ {
++ client = accept( g_io_channel_unix_get_fd( ioc ), (struct sockaddr *)&client_addr, &addr_len );
++ if ( client != -1 )
++ {
++ args = g_byte_array_sized_new(4096);
++ while( (r = read( client, buf, sizeof(buf) )) > 0 )
++ g_byte_array_append( args, (guint8*)buf, r);
++ shutdown( client, 2 );
++ close( client );
++ ipc_buf_to_args(args);
++ g_byte_array_free( args, TRUE );
++ pcmanfm_run();
++ }
++ }
++ return TRUE;
++}
++
++void get_socket_name( char* buf, int len )
++{
++ char* dpy = gdk_get_display();
++ g_snprintf( buf, len, "/tmp/.pcmanfm-socket%s-%s", dpy, g_get_user_name() );
++ g_free( dpy );
++}
++
++gboolean single_instance_check()
++{
++ struct sockaddr_un addr;
++ int addr_len;
++ int ret;
++ int reuse;
++
++ if((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
++ {
++ ret = 1;
++ goto _exit;
++ }
++
++ /* FIXME: use abstract socket */
++ addr.sun_family = AF_UNIX;
++ get_socket_name(addr.sun_path, sizeof( addr.sun_path ));
++#ifdef SUN_LEN
++ addr_len = SUN_LEN(&addr);
++#else
++ addr_len = strlen( addr.sun_path ) + sizeof( addr.sun_family );
++#endif
++
++ /* try to connect to existing instance */
++ if(connect(sock, (struct sockaddr*)&addr, addr_len) == 0)
++ {
++ /* connected successfully */
++ GByteArray* buf = args_to_ipc_buf();
++ write(sock, buf->data, buf->len);
++ g_byte_array_free(buf, TRUE);
++
++ shutdown( sock, 2 );
++ close( sock );
++ ret = 0;
++ goto _exit;
++ }
++
++ /* There is no existing server, and we are in the first instance. */
++ unlink( addr.sun_path ); /* delete old socket file if it exists. */
++ reuse = 1;
++ ret = setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse) );
++ if(bind(sock, (struct sockaddr*)&addr, addr_len) == -1)
++ {
++ ret = 1;
++ goto _exit;
++ }
++
++ io_channel = g_io_channel_unix_new(sock);
++ g_io_channel_set_encoding(io_channel, NULL, NULL);
++ g_io_channel_set_buffered(io_channel, FALSE);
++ g_io_add_watch(io_channel, G_IO_IN,
++ (GIOFunc)on_socket_event, NULL);
++ if(listen(sock, 5) == -1)
++ {
++ ret = 1;
++ goto _exit;
++ }
++ return TRUE;
++
++_exit:
++
++ gdk_notify_startup_complete();
++ exit( ret );
++}
++
++void single_instance_finalize()
++{
++ char lock_file[256];
++ shutdown(sock, 2);
++ g_io_channel_unref(io_channel);
++ close(sock);
++ get_socket_name(lock_file, sizeof( lock_file ));
++ unlink(lock_file);
++}
++
+ static FmJobErrorAction on_file_info_job_error(FmFileInfoJob* job, GError* err, FmJobErrorSeverity severity, gpointer user_data)
+ {
+ if(err->domain == G_IO_ERROR)