[arch-commits] Commit in pcmanfm/trunk (revert-new-IPC.patch)

Angel Velásquez angvp at archlinux.org
Sun Nov 7 15:46:46 UTC 2010


    Date: Sunday, November 7, 2010 @ 10:46:45
  Author: angvp
Revision: 98316

Applying patch for FS#21466

Added:
  pcmanfm/trunk/revert-new-IPC.patch

----------------------+
 revert-new-IPC.patch |  432 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 432 insertions(+)

Added: revert-new-IPC.patch
===================================================================
--- revert-new-IPC.patch	                        (rev 0)
+++ revert-new-IPC.patch	2010-11-07 15:46:45 UTC (rev 98316)
@@ -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)




More information about the arch-commits mailing list