forked from enlightenment/efl
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 :)
This commit is contained in:
parent
9bb1ef2708
commit
9ab6c58530
|
@ -151,7 +151,7 @@ handle_run(int fd, unsigned long bytes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
elm_quicklaunch_prepare(argc, argv);
|
elm_quicklaunch_prepare(argc, argv, cwd);
|
||||||
elm_quicklaunch_fork(argc, argv, cwd, post_fork, NULL);
|
elm_quicklaunch_fork(argc, argv, cwd, post_fork, NULL);
|
||||||
elm_quicklaunch_cleanup();
|
elm_quicklaunch_cleanup();
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,7 +143,11 @@ extern EAPI double _elm_startup_time;
|
||||||
#ifndef ELM_LIB_QUICKLAUNCH
|
#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 */
|
#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
|
#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
|
#endif
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
@ -270,7 +274,7 @@ EAPI void elm_quicklaunch_seed(void);
|
||||||
/**
|
/**
|
||||||
* Exposed symbol used only by macros and should not be used by apps
|
* 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
|
* 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
|
* 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).
|
* Set a new policy's value (for a given policy group/identifier).
|
||||||
|
|
|
@ -843,23 +843,21 @@ static int (*qr_main)(int argc,
|
||||||
|
|
||||||
EAPI Eina_Bool
|
EAPI Eina_Bool
|
||||||
elm_quicklaunch_prepare(int argc,
|
elm_quicklaunch_prepare(int argc,
|
||||||
char **argv)
|
char **argv,
|
||||||
|
const char *cwd)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_FORK
|
#ifdef HAVE_FORK
|
||||||
char *exe;
|
char *exe, *exe2, *p;
|
||||||
|
char *exename;
|
||||||
|
|
||||||
if (argc <= 0 || argv == NULL) return EINA_FALSE;
|
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)
|
if (!exe)
|
||||||
{
|
{
|
||||||
ERR("requested quicklaunch binary '%s' does not exist\n", argv[0]);
|
ERR("requested quicklaunch binary '%s' does not exist\n", argv[0]);
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
char *exe2, *p;
|
|
||||||
char *exename;
|
|
||||||
|
|
||||||
exe2 = malloc(strlen(exe) + 1 + 7 + strlen(LIBEXT));
|
exe2 = malloc(strlen(exe) + 1 + 7 + strlen(LIBEXT));
|
||||||
strcpy(exe2, exe);
|
strcpy(exe2, exe);
|
||||||
|
@ -872,34 +870,60 @@ elm_quicklaunch_prepare(int argc,
|
||||||
strcat(p, "../lib/");
|
strcat(p, "../lib/");
|
||||||
strcat(p, exename);
|
strcat(p, exename);
|
||||||
strcat(p, LIBEXT);
|
strcat(p, LIBEXT);
|
||||||
if (!access(exe2, R_OK | X_OK))
|
if (access(exe2, R_OK | X_OK) != 0)
|
||||||
{
|
{
|
||||||
free(exe);
|
|
||||||
exe = exe2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
free(exe2);
|
free(exe2);
|
||||||
|
exe2 = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Try linking to executable first. Works with PIE files. */
|
||||||
qr_handle = dlopen(exe, RTLD_NOW | RTLD_GLOBAL);
|
qr_handle = dlopen(exe, RTLD_NOW | RTLD_GLOBAL);
|
||||||
if (!qr_handle)
|
if (qr_handle)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "dlerr: %s\n", dlerror());
|
INF("dlopen('%s') = %p", exe, qr_handle);
|
||||||
WRN("dlopen('%s') failed: %s", exe, dlerror());
|
qr_main = dlsym(qr_handle, "elm_main");
|
||||||
|
if (qr_main)
|
||||||
|
{
|
||||||
|
INF("dlsym(%p, 'elm_main') = %p", qr_handle, qr_main);
|
||||||
|
free(exe2);
|
||||||
|
free(exe);
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
dlclose(qr_handle);
|
||||||
|
qr_handle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!exe2)
|
||||||
|
{
|
||||||
|
WRN("not quicklauncher capable: '%s'", exe);
|
||||||
free(exe);
|
free(exe);
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
}
|
}
|
||||||
INF("dlopen('%s') = %p", exe, qr_handle);
|
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", exe2, dlerror());
|
||||||
|
free(exe2);
|
||||||
|
return EINA_FALSE;
|
||||||
|
}
|
||||||
|
INF("dlopen('%s') = %p", exe2, qr_handle);
|
||||||
qr_main = dlsym(qr_handle, "elm_main");
|
qr_main = dlsym(qr_handle, "elm_main");
|
||||||
INF("dlsym(%p, 'elm_main') = %p", qr_handle, qr_main);
|
INF("dlsym(%p, 'elm_main') = %p", qr_handle, qr_main);
|
||||||
if (!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);
|
dlclose(qr_handle);
|
||||||
qr_handle = NULL;
|
qr_handle = NULL;
|
||||||
free(exe);
|
free(exe2);
|
||||||
return EINA_FALSE;
|
return EINA_FALSE;
|
||||||
}
|
}
|
||||||
free(exe);
|
free(exe2);
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
#else
|
#else
|
||||||
(void)argc;
|
(void)argc;
|
||||||
|
@ -1018,16 +1042,17 @@ elm_quicklaunch_fallback(int argc,
|
||||||
char **argv)
|
char **argv)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
char cwd[PATH_MAX];
|
||||||
elm_quicklaunch_init(argc, argv);
|
elm_quicklaunch_init(argc, argv);
|
||||||
elm_quicklaunch_sub_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);
|
ret = qr_main(argc, argv);
|
||||||
exit(ret);
|
exit(ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI char *
|
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 char *path = NULL;
|
||||||
static Eina_List *pathlist = NULL;
|
static Eina_List *pathlist = NULL;
|
||||||
|
@ -1035,8 +1060,13 @@ elm_quicklaunch_exe_path_get(const char *exe)
|
||||||
const Eina_List *l;
|
const Eina_List *l;
|
||||||
char buf[PATH_MAX];
|
char buf[PATH_MAX];
|
||||||
if (exe[0] == '/') return strdup(exe);
|
if (exe[0] == '/') 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] == '/')) return strdup(exe);
|
||||||
if ((exe[0] == '.') && (exe[1] == '.') && (exe[2] == '/')) return strdup(exe);
|
if ((exe[0] == '.') && (exe[1] == '.') && (exe[2] == '/')) return strdup(exe);
|
||||||
|
}
|
||||||
if (!path)
|
if (!path)
|
||||||
{
|
{
|
||||||
const char *p, *pp;
|
const char *p, *pp;
|
||||||
|
|
Loading…
Reference in New Issue