summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-01-24 12:24:27 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-01-24 12:24:27 +0000
commitc3ad34c7fa7222ef6003ca83a3d9b17c80caa9ef (patch)
tree412d0056f7f50370f2e3971a9ea41fb4bca864cc
parent9a15c7c84a7871bf05e4d136df72ab5cc03cd6ca (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.c4
-rw-r--r--ruby.c38
2 files changed, 29 insertions, 13 deletions
diff --git a/file.c b/file.c
index dd05bb7038..01370030fe 100644
--- a/file.c
+++ b/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;
diff --git a/ruby.c b/ruby.c
index 9014ccdc24..51a606f8bc 100644
--- a/ruby.c
+++ b/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