Fix rz_path_prefix not working when BINDIR is at the root directory or several folders deep (#2332)
* Add an option to provide a custom prefix for portable binaries * Use bindir's depth to find the portable root path in rz_path_prefix * Skip the prefix folder check if we are not in bindir
This commit is contained in:
parent
0549b2b5fb
commit
b744c8749a
5 changed files with 80 additions and 16 deletions
|
|
@ -20,6 +20,7 @@
|
|||
#define HAVE_EXECVP @HAVE_EXECVP@
|
||||
#define HAVE_EXECL @HAVE_EXECL@
|
||||
#define HAVE_SYSTEM @HAVE_SYSTEM@
|
||||
#define HAVE_REALPATH @HAVE_REALPATH@
|
||||
#define HAVE_PIPE2 @HAVE_PIPE2@
|
||||
#define HAVE_ENVIRON @HAVE_ENVIRON@
|
||||
#define HAVE_OPENPTY @HAVE_OPENPTY@
|
||||
|
|
@ -54,6 +55,8 @@
|
|||
#define RZ_DATDIR "@DATADIR@"
|
||||
#define RZ_WWWROOT "@WWWROOT@"
|
||||
|
||||
#define RZ_BINDIR_DEPTH @BINDIR_DEPTH@
|
||||
|
||||
#define RZ_PLUGINS "@PLUGINS@"
|
||||
#define RZ_DATADIR "@DATADIR_RZ@"
|
||||
#define RZ_SDB "@SDB@"
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ RZ_API RZ_OWN char *rz_path_home_history(void);
|
|||
|
||||
RZ_API RZ_OWN char *rz_path_home_expand(RZ_NULLABLE const char *path);
|
||||
|
||||
RZ_API RZ_OWN char *rz_path_realpath(RZ_NULLABLE const char *path);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ RZ_API char *rz_file_abspath_rel(const char *cwd, const char *file) {
|
|||
ret = tmp;
|
||||
}
|
||||
#endif
|
||||
#if __UNIX__
|
||||
#if HAVE_REALPATH
|
||||
char rp[PATH_MAX] = { 0 };
|
||||
char *abspath = realpath(ret, rp); // second arg == NULL is only an extension
|
||||
if (abspath) {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include <rz_util/rz_file.h>
|
||||
#include <rz_util/rz_sys.h>
|
||||
#include <rz_util/rz_str.h>
|
||||
#include <rz_util/rz_utf8.h>
|
||||
|
||||
/**
|
||||
* \brief Return \p path prefixed by the Rizin install prefix
|
||||
|
|
@ -15,23 +16,37 @@
|
|||
RZ_API RZ_OWN char *rz_path_prefix(RZ_NULLABLE const char *path) {
|
||||
#if RZ_IS_PORTABLE
|
||||
char *pid_to_path = rz_sys_pid_to_path(rz_sys_getpid());
|
||||
if (pid_to_path) {
|
||||
char *t = rz_file_dirname(pid_to_path);
|
||||
free(pid_to_path);
|
||||
// When rz_path_prefix is called from a unit test or from a
|
||||
// not-yet-instazled rizin binary this would return the wrong path.
|
||||
// In those cases, just return RZ_PREFIX.
|
||||
char *result = NULL;
|
||||
if (rz_str_endswith(t, RZ_SYS_DIR RZ_BINDIR)) {
|
||||
char *r = rz_file_dirname(t);
|
||||
result = rz_file_path_join(r, path);
|
||||
free(r);
|
||||
if (!pid_to_path) {
|
||||
goto prefix;
|
||||
}
|
||||
char *bindir = rz_path_realpath(RZ_JOIN_2_PATHS(RZ_PREFIX, RZ_BINDIR));
|
||||
if (!bindir) {
|
||||
goto prefix;
|
||||
}
|
||||
|
||||
char *it = rz_file_dirname(pid_to_path);
|
||||
free(pid_to_path);
|
||||
|
||||
bool in_bindir = rz_str_endswith(it, rz_file_basename(bindir));
|
||||
free(bindir);
|
||||
// When rz_path_prefix is called from a unit test or from a
|
||||
// not-yet-installed rizin binary this would return the wrong path.
|
||||
// In those cases, just return RZ_PREFIX.
|
||||
if (in_bindir) {
|
||||
for (int i = 0; i < RZ_BINDIR_DEPTH; i++) {
|
||||
char *tmp = it;
|
||||
it = rz_file_dirname(tmp);
|
||||
free(tmp);
|
||||
}
|
||||
free(t);
|
||||
if (result) {
|
||||
|
||||
if (rz_file_is_directory(it)) {
|
||||
char *result = rz_file_path_join(it, path);
|
||||
free(it);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
free(it);
|
||||
prefix:
|
||||
#endif
|
||||
return rz_file_path_join(RZ_PREFIX, path);
|
||||
}
|
||||
|
|
@ -180,3 +195,33 @@ RZ_API RZ_OWN char *rz_path_home_expand(RZ_NULLABLE const char *path) {
|
|||
|
||||
return rz_path_home(path + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return a canonicalized absolute path. Expands all symbolic links and resolves
|
||||
* references to /./, /../ and extra '/' characters.
|
||||
*
|
||||
* \param path Original file path.
|
||||
* \return New canonicalized absolute path.
|
||||
*/
|
||||
RZ_API RZ_OWN char *rz_path_realpath(RZ_NULLABLE const char *path) {
|
||||
if (!path) {
|
||||
return NULL;
|
||||
}
|
||||
#if HAVE_REALPATH
|
||||
char buf[PATH_MAX] = { 0 };
|
||||
const char *rp = realpath(path, buf);
|
||||
if (rp) {
|
||||
return strdup(rp);
|
||||
}
|
||||
#elif __WINDOWS__
|
||||
wchar_t buf[MAX_PATH] = { 0 };
|
||||
|
||||
wchar_t *wpath = rz_utf8_to_utf16(path);
|
||||
DWORD len = GetFullPathNameW(wpath, MAX_PATH, buf, NULL);
|
||||
free(wpath);
|
||||
if (len > 0 && len < MAX_PATH - 1) {
|
||||
return rz_utf16_to_utf8_l(buf, len);
|
||||
}
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
18
meson.build
18
meson.build
|
|
@ -1,7 +1,7 @@
|
|||
project('rizin', 'c',
|
||||
version: 'v0.4.0-git',
|
||||
license: 'LGPL3',
|
||||
meson_version: '>=0.55.3',
|
||||
meson_version: '>=0.58.0',
|
||||
default_options: [
|
||||
'buildtype=debugoptimized',
|
||||
'b_vscrt=from_buildtype',
|
||||
|
|
@ -214,6 +214,12 @@ else
|
|||
rizin_bindings = rizin_libdir / 'rizin-bindings'
|
||||
endif
|
||||
|
||||
# Calcualte BINDIR's depth to be able to find the root directory during runtime
|
||||
# in portable builds
|
||||
py_cmd = 'import os; print(len(os.path.normpath(r"@0@").split(os.sep)) - len(os.path.normpath(r"@1@").split(os.sep)))'.format(rizin_prefix / rizin_bindir, rizin_prefix)
|
||||
py_cmd = run_command(py3_exe, '-c', py_cmd)
|
||||
bindir_depth = py_cmd.stdout().strip()
|
||||
|
||||
opts_overwrite = [
|
||||
'rizin_wwwroot',
|
||||
'rizin_sdb',
|
||||
|
|
@ -379,6 +385,7 @@ userconf.set10('USE_LIB_XXHASH', xxhash_dep.found())
|
|||
userconf.set10('DEBUGGER', has_debugger)
|
||||
userconf.set('PREFIX', rizin_prefix)
|
||||
userconf.set('BINDIR', rizin_bindir)
|
||||
userconf.set('BINDIR_DEPTH', bindir_depth)
|
||||
userconf.set('LIBDIR', rizin_libdir)
|
||||
userconf.set('INCLUDEDIR', rizin_incdir)
|
||||
userconf.set('DATADIR_RZ', rizin_datdir_rz)
|
||||
|
|
@ -456,6 +463,7 @@ foreach item : [
|
|||
['execvp', '#include <unistd.h>', []],
|
||||
['execl', '#include <unistd.h>', []],
|
||||
['system', '#include <stdlib.h>', []],
|
||||
['realpath', '#include <stdlib.h>', []],
|
||||
['fork', '#include <unistd.h>', []],
|
||||
['nice', '#include <unistd.h>', []],
|
||||
['copyfile', '#include <copyfile.h>', []],
|
||||
|
|
@ -610,7 +618,13 @@ rpath_exe = ''
|
|||
rpath_lib = ''
|
||||
rpath_summary = 'disabled'
|
||||
if use_rpath
|
||||
rpath_exe = '$ORIGIN/../' + get_option('libdir')
|
||||
# Use bindir depth to create a path to the rootdir from bindir
|
||||
path_to_rootdir=''
|
||||
foreach i : range(bindir_depth.to_int())
|
||||
path_to_rootdir += '../'
|
||||
endforeach
|
||||
|
||||
rpath_exe = '$ORIGIN/' + path_to_rootdir + get_option('libdir')
|
||||
rpath_lib = '$ORIGIN'
|
||||
rpath_summary = 'relative'
|
||||
elif use_rpath_absolute
|
||||
|
|
|
|||
Loading…
Reference in a new issue