diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-01-24 12:24:27 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-01-24 12:24:27 +0000 |
commit | c3ad34c7fa7222ef6003ca83a3d9b17c80caa9ef (patch) | |
tree | 412d0056f7f50370f2e3971a9ea41fb4bca864cc | |
parent | 9a15c7c84a7871bf05e4d136df72ab5cc03cd6ca (diff) |
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
-rw-r--r-- | file.c | 4 | ||||
-rw-r--r-- | ruby.c | 38 |
2 files changed, 29 insertions, 13 deletions
@@ -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; @@ -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 |