Attached is a patch showing how we can run executable files using
g_spawn_async. Using g_app_info_new_from_commandline is unworkable
because it needs escaping a general filename into a command-line. The
only real solution is to completely cut out such escaping and parsing
and pass the filename directly to g_spawn_async.

Only the first hunk of the patch is relevant. The rest of the patch was
only needed to actually build the package (as it is currently FTBFS).
Description: Illustrative only patch for Bug#624015
 Run executable files using g_spawn_async.
 Using g_app_info_new_from_commandline is unworkable and needs escaping
 a general filename into a command-line. The only real solution is to
 completely cut out such escaping and parsing and pass the filename directly
 to g_spawn_async.
 .
 The person named in the Author field signed this changelog entry.
Author: ulrik
Bug-Debian: http://bugs.debian.org/624015

---
The information above should follow the Patch Tagging Guidelines, please
checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
are templates for supplementary fields that you might want to add:

Origin: <vendor|upstream|other>, <url of original patch>
Bug: <url in upstream bugtracker>
Bug-Debian: http://bugs.debian.org/<bugnumber>
Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
Forwarded: <no|not-needed|url proving that it has been forwarded>
Reviewed-By: <name and email of someone who approved the patch>
Last-Update: <YYYY-MM-DD>

--- libfm-0.1.14.orig/src/base/fm-file-launcher.c
+++ libfm-0.1.14/src/base/fm-file-launcher.c
@@ -172,19 +172,18 @@ gboolean fm_launch_files(GAppLaunchConte
                     /* FIXME: we need to use eaccess/euidaccess here. */
                     if(g_file_test(filename, G_FILE_TEST_IS_EXECUTABLE))
                     {
-                        app = g_app_info_create_from_commandline(filename, NULL, 0, NULL);
-                        if(app)
-                        {
-                            if(!g_app_info_launch(app, NULL, ctx, &err))
-                            {
-                                if(launcher->error)
-                                    launcher->error(ctx, err, user_data);
-                                g_error_free(err);
-                                err = NULL;
-                            }
-                            g_object_unref(app);
-                            continue;
+                        gchar *appargv[] = { filename, NULL };
+
+                        if(!g_spawn_async(NULL, appargv, NULL, 0, NULL, NULL,
+                                          NULL, &err)) {
+                            /* XXX: NULL app launch ctx */
+                            if(launcher->error)
+                                launcher->error(NULL, err, user_data);
+                            g_error_free(err);
+                            err = NULL;
                         }
+
+                        continue;
                     }
                     g_free(filename);
                 }
--- libfm-0.1.14.orig/src/gio/fm-app-lookup.c
+++ libfm-0.1.14/src/gio/fm-app-lookup.c
@@ -25,151 +25,3 @@
 
 #include "fm-app-lookup.h"
 #include <gio/gdesktopappinfo.h>
-
-#ifndef G_IMPLEMENT_INTERFACE_DYNAMIC /* this macro is only provided in glib > 2.24 */
-    #define G_IMPLEMENT_INTERFACE_DYNAMIC(TYPE_IFACE, iface_init)       { \
-      const GInterfaceInfo g_implement_interface_info = { \
-        (GInterfaceInitFunc) iface_init, NULL, NULL      \
-      }; \
-      g_type_module_add_interface (type_module, g_define_type_id, TYPE_IFACE, &g_implement_interface_info); \
-    }
-#endif
-
-static void app_lookup_iface_init(GDesktopAppInfoLookupIface *iface);
-static GObject* fm_app_lookup_constructor(GType type, guint n_props, GObjectConstructParam *props);
-static void fm_app_lookup_finalize  			(GObject *object);
-static GAppInfo *get_default_for_uri_scheme(GDesktopAppInfoLookup *lookup, const char *scheme);
-
-G_DEFINE_DYNAMIC_TYPE_EXTENDED(FmAppLookup, fm_app_lookup, G_TYPE_OBJECT, 0,
-    G_IMPLEMENT_INTERFACE_DYNAMIC(G_TYPE_DESKTOP_APP_INFO_LOOKUP, app_lookup_iface_init))
-
-
-static void fm_app_lookup_class_init(FmAppLookupClass *klass)
-{
-	GObjectClass *g_object_class;
-	g_object_class = G_OBJECT_CLASS(klass);
-    g_object_class->constructor = fm_app_lookup_constructor;
-	g_object_class->finalize = fm_app_lookup_finalize;
-}
-
-static void fm_app_lookup_class_finalize(FmAppLookupClass *klass)
-{
-}
-
-GObject* fm_app_lookup_constructor(GType type, guint n_props, GObjectConstructParam *props)
-{
-    GObject* obj;
-    /* call parent constructor. */
-    obj = G_OBJECT_CLASS(fm_app_lookup_parent_class)->constructor(type, n_props, props);
-    return obj;
-}
-
-static void fm_app_lookup_finalize(GObject *object)
-{
-	FmAppLookup *self;
-
-	g_return_if_fail(object != NULL);
-	g_return_if_fail(FM_IS_APP_LOOKUP(object));
-
-	self = FM_APP_LOOKUP(object);
-	G_OBJECT_CLASS(fm_app_lookup_parent_class)->finalize(object);
-}
-
-
-static void fm_app_lookup_init(FmAppLookup *self)
-{
-
-}
-
-void fm_app_lookup_register(GIOModule *module)
-{
-    gint priority;
-    fm_app_lookup_register_type(G_TYPE_MODULE (module));
-    /* check if we're in gnome, if true, use lower priority.
-     * otherwise, use a high priority to override gvfs gconf module.
-     * priority of the gconf module of gvfs is 10. */
-    if(G_UNLIKELY(g_getenv("GNOME_DESKTOP_SESSION_ID"))) /* we're in Gnome */
-        priority = 9;
-    else /* we're in other desktop envionments */
-        priority = 90;
-
-    g_io_extension_point_implement(G_DESKTOP_APP_INFO_LOOKUP_EXTENSION_POINT_NAME,
-                                         FM_TYPE_APP_LOOKUP, "libfm-applookup", priority);
-
-    /* TODO: implement our own G_NATIVE_VOLUME_MONITOR_EXTENSION_POINT_NAME */
-}
-
-static void app_lookup_iface_init(GDesktopAppInfoLookupIface *iface)
-{
-    iface->get_default_for_uri_scheme = get_default_for_uri_scheme;
-}
-
-/* FIXME: implement our own browser lookup method not depending on gconf. */
-GAppInfo *get_default_for_uri_scheme(GDesktopAppInfoLookup *lookup, const char *scheme)
-{
-    GAppInfo* app;
-    GKeyFile* kf;
-    const char* key;
-    char* fname;
-    char* desktop_id = NULL;
-
-    /* web browser */
-    if(g_ascii_strcasecmp(scheme, "http")==0 || g_ascii_strcasecmp(scheme, "https")==0)
-        key = "WebBrowser";
-    else if(g_ascii_strcasecmp(scheme, "mailto")==0)
-        key = "MailClient";
-    else /* we don't know this */
-        return NULL;
-
-    kf = g_key_file_new();
-
-    /* try user config first */
-    fname = g_build_filename(g_get_user_config_dir(), "libfm/pref-apps.conf", NULL);
-    if(g_key_file_load_from_file(kf, fname, 0, NULL))
-    {
-        desktop_id = g_key_file_get_string(kf, "Preferred Applications", key, NULL);
-        if(desktop_id && !*desktop_id)
-        {
-            g_free(desktop_id);
-            desktop_id = NULL;
-        }
-    }
-    g_free(fname);
-
-    if(!desktop_id) /* system-wide */
-    {
-        const gchar* const *dirs = g_get_system_config_dirs();
-        int i, n;
-        if(g_key_file_load_from_file(kf, fname, 0, NULL))
-            desktop_id = g_key_file_get_string(kf, "Preferred Applications", key, NULL);
-        n = g_strv_length(dirs);
-        for( i = n - 1; i > 0; --i )
-        {
-            fname = g_build_filename(dirs[i], "libfm/pref-apps.conf", NULL);
-            if( g_key_file_load_from_file(kf, fname, 0, NULL) )
-                desktop_id = g_key_file_get_string(kf, "Preferred Applications", key, NULL);
-            g_free(fname);
-            if(desktop_id)
-            {
-                if(*desktop_id)
-                    break;
-                else
-                {
-                    g_free(desktop_id);
-                    desktop_id = NULL;
-                }
-            }
-        }
-    }
-
-    g_key_file_free(kf);
-
-    if(!desktop_id)
-        return NULL;
-
-    app = g_desktop_app_info_new(desktop_id);
-
-    g_free(desktop_id);
-
-    return app;
-}
--- libfm-0.1.14.orig/src/gio/fm-app-lookup.h
+++ libfm-0.1.14/src/gio/fm-app-lookup.h
@@ -24,34 +24,10 @@
 #define __FM_APP_LOOKUP_H__
 
 #include <gio/gio.h>
+#include <gio/gdesktopappinfo.h>
 
 G_BEGIN_DECLS
 
-#define FM_TYPE_APP_LOOKUP				(fm_app_lookup_get_type())
-#define FM_APP_LOOKUP(obj)				(G_TYPE_CHECK_INSTANCE_CAST((obj),\
-			FM_TYPE_APP_LOOKUP, FmAppLookup))
-#define FM_APP_LOOKUP_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST((klass),\
-			FM_TYPE_APP_LOOKUP, FmAppLookupClass))
-#define FM_IS_APP_LOOKUP(obj)			(G_TYPE_CHECK_INSTANCE_TYPE((obj),\
-			FM_TYPE_APP_LOOKUP))
-#define FM_IS_APP_LOOKUP_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE((klass),\
-			FM_TYPE_APP_LOOKUP))
-
-typedef struct _FmAppLookup			FmAppLookup;
-typedef struct _FmAppLookupClass		FmAppLookupClass;
-
-struct _FmAppLookup
-{
-	GObject parent;
-};
-
-struct _FmAppLookupClass
-{
-	GObjectClass parent_class;
-};
-
-GType fm_app_lookup_get_type(void);
-void fm_app_lookup_register(GIOModule *module);
 
 G_END_DECLS
 
--- libfm-0.1.14.orig/src/gio/module.c
+++ libfm-0.1.14/src/gio/module.c
@@ -33,19 +33,9 @@
 
 void g_io_module_load (GIOModule *module)
 {
-    bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR);
-    bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-    fm_app_lookup_register (module);
 }
 
 void g_io_module_unload (GIOModule *module)
 {
 }
 
-char** g_io_module_query (void)
-{
-    char** eps = g_new(char*, 2);
-    eps[0] = g_strdup(G_DESKTOP_APP_INFO_LOOKUP_EXTENSION_POINT_NAME);
-    eps[1] = NULL;
-    return eps;
-}
--- libfm-0.1.14.orig/src/tests/Makefile.in
+++ libfm-0.1.14/src/tests/Makefile.in
@@ -130,7 +130,7 @@ INTLTOOL_MERGE = @INTLTOOL_MERGE@
 INTLTOOL_PERL = @INTLTOOL_PERL@
 INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
 LD = @LD@
-LDFLAGS = @LDFLAGS@
+LDFLAGS = @LDFLAGS@ -lgobject-2.0
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LIBTOOL = @LIBTOOL@
--- libfm-0.1.14.orig/src/tests/test-fm-path.c
+++ libfm-0.1.14/src/tests/test-fm-path.c
@@ -7,7 +7,7 @@
 
 #define TEST_PARSING(func, str_to_parse, ...) \
     G_STMT_START { \
-        char* expected[] = {__VA_ARGS__}; \
+        const char* expected[] = {__VA_ARGS__}; \
         test_parsing(func, str_to_parse, expected, G_N_ELEMENTS(expected)); \
     } G_STMT_END
 

Reply via email to