jpeg pushed a commit to branch master.

http://git.enlightenment.org/core/elementary.git/commit/?id=876f8bccc7fed2f8511c9bdbe1c0e21be30290ca

commit 876f8bccc7fed2f8511c9bdbe1c0e21be30290ca
Author: Jean-Philippe Andre <jp.an...@samsung.com>
Date:   Mon Nov 4 15:12:51 2013 +0900

    elm/quicklaunch: Improve executable path search
    
    Always search executable based on CWD if possible.
    This way, elementary_run behaves more like sh where all of
    sh script, sh ./script and sh `pwd`/script will work.
    
    Also, remove quicklaunch-specific ELM_MAIN.
    This needs some doc, but compiling with -fpie and -pie is much
    better.
    
    Note: There's an API/ABI break here, BUT these APIs are marked
    as not to be used outside macros. And there isn't any macro
    using them :)
---
 src/bin/quicklaunch.c |  2 +-
 src/lib/elm_general.h | 10 ++++--
 src/lib/elm_main.c    | 96 +++++++++++++++++++++++++++++++++------------------
 3 files changed, 71 insertions(+), 37 deletions(-)

diff --git a/src/bin/quicklaunch.c b/src/bin/quicklaunch.c
index 2a811d2..f79770c 100644
--- a/src/bin/quicklaunch.c
+++ b/src/bin/quicklaunch.c
@@ -151,7 +151,7 @@ handle_run(int fd, unsigned long bytes)
           }
      }
 #endif
-   elm_quicklaunch_prepare(argc, argv);
+   elm_quicklaunch_prepare(argc, argv, cwd);
    elm_quicklaunch_fork(argc, argv, cwd, post_fork, NULL);
    elm_quicklaunch_cleanup();
 }
diff --git a/src/lib/elm_general.h b/src/lib/elm_general.h
index 7876af4..14d8776 100644
--- a/src/lib/elm_general.h
+++ b/src/lib/elm_general.h
@@ -143,7 +143,11 @@ extern EAPI double _elm_startup_time;
 #ifndef ELM_LIB_QUICKLAUNCH
 #define ELM_MAIN() int main(int argc, char **argv) { int ret; 
_elm_startup_time = ecore_time_unix_get(); elm_init(argc, argv); ret = 
elm_main(argc, argv); return ret; } /**< macro to be used after the elm_main() 
function */
 #else
-#define ELM_MAIN() int main(int argc, char **argv) { _elm_startup_time = 
ecore_time_unix_get(); return elm_quicklaunch_fallback(argc, argv); } /**< 
macro to be used after the elm_main() function */
+/** @deprecated macro to be used after the elm_main() function.
+ * Do not define ELM_LIB_QUICKLAUNCH
+ * Compile your programs with -fpie and -pie -rdynamic instead, to generate a 
single binary (linkable executable).
+ */
+#define ELM_MAIN() int main(int argc, char **argv) { _elm_startup_time = 
ecore_time_unix_get(); return elm_quicklaunch_fallback(argc, argv); }
 #endif
 
 /**************************************************************************/
@@ -270,7 +274,7 @@ EAPI void      elm_quicklaunch_seed(void);
 /**
  * Exposed symbol used only by macros and should not be used by apps
  */
-EAPI Eina_Bool elm_quicklaunch_prepare(int argc, char **argv);
+EAPI Eina_Bool elm_quicklaunch_prepare(int argc, char **argv, const char *cwd);
 
 /**
  * Exposed symbol used only by macros and should not be used by apps
@@ -290,7 +294,7 @@ EAPI int       elm_quicklaunch_fallback(int argc, char 
**argv);
 /**
  * Exposed symbol used only by macros and should not be used by apps
  */
-EAPI char     *elm_quicklaunch_exe_path_get(const char *exe);
+EAPI char     *elm_quicklaunch_exe_path_get(const char *exe, const char *cwd);
 
 /**
  * Set a new policy's value (for a given policy group/identifier).
diff --git a/src/lib/elm_main.c b/src/lib/elm_main.c
index ebf538b..927481f 100644
--- a/src/lib/elm_main.c
+++ b/src/lib/elm_main.c
@@ -843,63 +843,87 @@ static int (*qr_main)(int    argc,
 
 EAPI Eina_Bool
 elm_quicklaunch_prepare(int    argc,
-                        char **argv)
+                        char **argv,
+                        const char *cwd)
 {
 #ifdef HAVE_FORK
-   char *exe;
+   char *exe, *exe2, *p;
+   char *exename;
 
    if (argc <= 0 || argv == NULL) return EINA_FALSE;
 
-   exe = elm_quicklaunch_exe_path_get(argv[0]);
+   exe = elm_quicklaunch_exe_path_get(argv[0], cwd);
    if (!exe)
      {
         ERR("requested quicklaunch binary '%s' does not exist\n", argv[0]);
         return EINA_FALSE;
      }
-   else
+
+   exe2 = malloc(strlen(exe) + 1 + 7 + strlen(LIBEXT));
+   strcpy(exe2, exe);
+   p = strrchr(exe2, '/');
+   if (p) p++;
+   else p = exe2;
+   exename = alloca(strlen(p) + 1);
+   strcpy(exename, p);
+   *p = 0;
+   strcat(p, "../lib/");
+   strcat(p, exename);
+   strcat(p, LIBEXT);
+   if (access(exe2, R_OK | X_OK) != 0)
+     {
+        free(exe2);
+        exe2 = NULL;
+     }
+
+   /* Try linking to executable first. Works with PIE files. */
+   qr_handle = dlopen(exe, RTLD_NOW | RTLD_GLOBAL);
+   if (qr_handle)
      {
-        char *exe2, *p;
-        char *exename;
-
-        exe2 = malloc(strlen(exe) + 1 + 7 + strlen(LIBEXT));
-        strcpy(exe2, exe);
-        p = strrchr(exe2, '/');
-        if (p) p++;
-        else p = exe2;
-        exename = alloca(strlen(p) + 1);
-        strcpy(exename, p);
-        *p = 0;
-        strcat(p, "../lib/");
-        strcat(p, exename);
-        strcat(p, LIBEXT);
-        if (!access(exe2, R_OK | X_OK))
+        INF("dlopen('%s') = %p", exe, qr_handle);
+        qr_main = dlsym(qr_handle, "elm_main");
+        if (qr_main)
           {
+             INF("dlsym(%p, 'elm_main') = %p", qr_handle, qr_main);
+             free(exe2);
              free(exe);
-             exe = exe2;
+             return EINA_TRUE;
           }
-        else
-          free(exe2);
+        dlclose(qr_handle);
+        qr_handle = NULL;
      }
-   qr_handle = dlopen(exe, RTLD_NOW | RTLD_GLOBAL);
+
+   if (!exe2)
+     {
+        WRN("not quicklauncher capable: '%s'", exe);
+        free(exe);
+        return EINA_FALSE;
+     }
+   free(exe);
+
+   /* Open companion .so file.
+    * Support for legacy quicklaunch apps with separate library.
+    */
+   qr_handle = dlopen(exe2, RTLD_NOW | RTLD_GLOBAL);
    if (!qr_handle)
      {
         fprintf(stderr, "dlerr: %s\n", dlerror());
-        WRN("dlopen('%s') failed: %s", exe, dlerror());
-        free(exe);
+        WRN("dlopen('%s') failed: %s", exe2, dlerror());
+        free(exe2);
         return EINA_FALSE;
      }
-   INF("dlopen('%s') = %p", exe, qr_handle);
+   INF("dlopen('%s') = %p", exe2, qr_handle);
    qr_main = dlsym(qr_handle, "elm_main");
    INF("dlsym(%p, 'elm_main') = %p", qr_handle, qr_main);
    if (!qr_main)
      {
-        WRN("not quicklauncher capable: no elm_main in '%s'", exe);
+        WRN("not quicklauncher capable: no elm_main in '%s'", exe2);
         dlclose(qr_handle);
         qr_handle = NULL;
-        free(exe);
+        free(exe2);
         return EINA_FALSE;
      }
-   free(exe);
+   free(exe2);
    return EINA_TRUE;
 #else
    (void)argc;
@@ -1018,16 +1042,17 @@ elm_quicklaunch_fallback(int    argc,
                          char **argv)
 {
    int ret;
+   char cwd[PATH_MAX];
    elm_quicklaunch_init(argc, argv);
    elm_quicklaunch_sub_init(argc, argv);
-   elm_quicklaunch_prepare(argc, argv);
+   elm_quicklaunch_prepare(argc, argv, getcwd(cwd, sizeof(cwd)));
    ret = qr_main(argc, argv);
    exit(ret);
    return ret;
 }
 
 EAPI char *
-elm_quicklaunch_exe_path_get(const char *exe)
+elm_quicklaunch_exe_path_get(const char *exe, const char *cwd)
 {
    static char *path = NULL;
    static Eina_List *pathlist = NULL;
@@ -1035,8 +1060,13 @@ elm_quicklaunch_exe_path_get(const char *exe)
    const Eina_List *l;
    char buf[PATH_MAX];
    if (exe[0] == '/') return strdup(exe);
-   if ((exe[0] == '.') && (exe[1] == '/')) return strdup(exe);
-   if ((exe[0] == '.') && (exe[1] == '.') && (exe[2] == '/')) return 
strdup(exe);
+   if (cwd)
+     pathlist = eina_list_append(pathlist, eina_stringshare_add(cwd));
+   else
+     {
+        if ((exe[0] == '.') && (exe[1] == '/')) return strdup(exe);
+        if ((exe[0] == '.') && (exe[1] == '.') && (exe[2] == '/')) return 
strdup(exe);
+     }
    if (!path)
      {
         const char *p, *pp;

-- 


Reply via email to