ruby.c: replace with real path

* ruby.c (dladdr_path): replace the executable path with symlinked
  real path.  dladdr(3) on Linux returns the argv[0] as dli_fname
  instead of the real path, for a symbol defined in the executable
  file itself.  [Bug #10776]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49394 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2015-01-24 12:24:27 +00:00
Родитель 9a15c7c84a
Коммит c3ad34c7fa
2 изменённых файлов: 29 добавлений и 13 удалений

4
file.c
Просмотреть файл

@ -2745,7 +2745,7 @@ rb_file_s_symlink(VALUE klass, VALUE from, VALUE to)
#endif
#ifdef HAVE_READLINK
static VALUE rb_readlink(VALUE path);
VALUE rb_readlink(VALUE path);
/*
* call-seq:
@ -2764,7 +2764,7 @@ rb_file_s_readlink(VALUE klass, VALUE path)
return rb_readlink(path);
}
static VALUE
VALUE
rb_readlink(VALUE path)
{
int size = 100;

38
ruby.c
Просмотреть файл

@ -364,6 +364,32 @@ ruby_init_loadpath(void)
ruby_init_loadpath_safe(0);
}
#if defined(HAVE_DLADDR)
static VALUE
dladdr_path(const void* addr)
{
Dl_info dli;
VALUE fname, path;
if (!dladdr(addr, &dli)) {
return rb_str_new(0, 0);
}
#ifdef __linux__
else if (dli.dli_fname == origarg.argv[0]) {
VALUE rb_readlink(VALUE);
fname = rb_str_new_cstr("/proc/self/exe");
path = rb_readlink(fname);
}
#endif
else {
fname = rb_str_new_cstr(dli.dli_fname);
path = rb_realpath_internal(Qnil, fname, 1);
}
rb_str_resize(fname, 0);
return path;
}
#endif
void
ruby_init_loadpath_safe(int safe_level)
{
@ -392,17 +418,7 @@ ruby_init_loadpath_safe(int safe_level)
#elif defined(__EMX__)
_execname(libpath, sizeof(libpath) - 1);
#elif defined(HAVE_DLADDR)
Dl_info dli;
if (dladdr((void *)(VALUE)expand_include_path, &dli)) {
char fbuf[MAXPATHLEN];
char *f = dln_find_file_r(dli.dli_fname, getenv(PATH_ENV), fbuf, sizeof(fbuf));
VALUE fname = rb_str_new_cstr(f ? f : dli.dli_fname);
rb_str_freeze(fname);
sopath = rb_realpath_internal(Qnil, fname, 1);
}
else {
sopath = rb_str_new(0, 0);
}
sopath = dladdr_path((void *)(VALUE)expand_include_path);
libpath = RSTRING_PTR(sopath);
#endif