mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
ruby.c: runtime_libruby_path
* ruby.c (runtime_libruby_path): hoisted out platform dependent routine to get the loaded runtime library path. cygwin_conv_path does path separator and WCHAR to UTF-8 conversions too. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63476 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
c8d17d71d7
commit
68b87aedde
1 changed files with 51 additions and 49 deletions
100
ruby.c
100
ruby.c
|
@ -470,12 +470,57 @@ ruby_init_loadpath(void)
|
||||||
ruby_init_loadpath_safe(0);
|
ruby_init_loadpath_safe(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(LOAD_RELATIVE) && defined(HAVE_DLADDR) && !defined(__CYGWIN__)
|
#if defined(LOAD_RELATIVE)
|
||||||
static VALUE
|
static VALUE
|
||||||
dladdr_path(const void* addr)
|
runtime_libruby_path(void)
|
||||||
{
|
{
|
||||||
|
#if defined _WIN32 || defined __CYGWIN__
|
||||||
|
DWORD len = RSTRING_EMBED_LEN_MAX, ret;
|
||||||
|
VALUE path;
|
||||||
|
VALUE wsopath = rb_str_new(0, len*sizeof(WCHAR));
|
||||||
|
WCHAR *wlibpath;
|
||||||
|
char *libpath;
|
||||||
|
|
||||||
|
while (wlibpath = (WCHAR *)RSTRING_PTR(wsopath),
|
||||||
|
ret = GetModuleFileNameW(libruby, wlibpath, len),
|
||||||
|
(ret == len))
|
||||||
|
{
|
||||||
|
rb_str_modify_expand(wsopath, len*sizeof(WCHAR));
|
||||||
|
rb_str_set_len(wsopath, (len += len)*sizeof(WCHAR));
|
||||||
|
}
|
||||||
|
if (!ret || ret > len) rb_fatal("failed to get module file name");
|
||||||
|
#if defined __CYGWIN__
|
||||||
|
{
|
||||||
|
const int win_to_posix = CCP_WIN_W_TO_POSIX | CCP_RELATIVE;
|
||||||
|
size_t newsize = cygwin_conv_path(win_to_posix, wlibpath, 0, 0);
|
||||||
|
if (!newsize) rb_fatal("failed to convert module path to cygwin");
|
||||||
|
path = rb_str_new(0, newsize);
|
||||||
|
libpath = RSTRING_PTR(path);
|
||||||
|
if (cygwin_conv_path(win_to_posix, wlibpath, libpath, newsize)) {
|
||||||
|
rb_str_resize(path, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
DWORD i;
|
||||||
|
for (len = ret, i = 0; i < len; ++i) {
|
||||||
|
if (wlibpath[i] == L'\\') {
|
||||||
|
wlibpath[i] = L'/';
|
||||||
|
ret = i+1; /* chop after the last separator */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
len = WideCharToMultiByte(CP_UTF8, 0, wlibpath, ret, NULL, 0, NULL, NULL);
|
||||||
|
path = rb_utf8_str_new(0, len);
|
||||||
|
libpath = RSTRING_PTR(path);
|
||||||
|
WideCharToMultiByte(CP_UTF8, 0, wlibpath, ret, libpath, len, NULL, NULL);
|
||||||
|
#endif
|
||||||
|
rb_str_resize(wsopath, 0);
|
||||||
|
return path;
|
||||||
|
#elif defined(HAVE_DLADDR)
|
||||||
Dl_info dli;
|
Dl_info dli;
|
||||||
VALUE fname, path;
|
VALUE fname, path;
|
||||||
|
const void* addr = (void *)(VALUE)expand_include_path;
|
||||||
|
|
||||||
if (!dladdr(addr, &dli)) {
|
if (!dladdr(addr, &dli)) {
|
||||||
return rb_str_new(0, 0);
|
return rb_str_new(0, 0);
|
||||||
|
@ -492,6 +537,9 @@ dladdr_path(const void* addr)
|
||||||
}
|
}
|
||||||
rb_str_resize(fname, 0);
|
rb_str_resize(fname, 0);
|
||||||
return path;
|
return path;
|
||||||
|
#else
|
||||||
|
# error relative load path is not supported on this platform.
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -527,55 +575,9 @@ ruby_init_loadpath_safe(int safe_level)
|
||||||
size_t baselen;
|
size_t baselen;
|
||||||
const char *p;
|
const char *p;
|
||||||
|
|
||||||
#if defined _WIN32 || defined __CYGWIN__
|
sopath = runtime_libruby_path();
|
||||||
{
|
|
||||||
DWORD len = RSTRING_EMBED_LEN_MAX, ret, i;
|
|
||||||
VALUE wsopath = rb_str_new(0, len*sizeof(WCHAR));
|
|
||||||
WCHAR *wlibpath;
|
|
||||||
while (wlibpath = (WCHAR *)RSTRING_PTR(wsopath),
|
|
||||||
ret = GetModuleFileNameW(libruby, wlibpath, len),
|
|
||||||
(ret == len))
|
|
||||||
{
|
|
||||||
rb_str_modify_expand(wsopath, len*sizeof(WCHAR));
|
|
||||||
rb_str_set_len(wsopath, (len += len)*sizeof(WCHAR));
|
|
||||||
}
|
|
||||||
if (!ret || ret > len) rb_fatal("failed to get module file name");
|
|
||||||
for (len = ret, i = 0; i < len; ++i) {
|
|
||||||
if (wlibpath[i] == L'\\') {
|
|
||||||
wlibpath[i] = L'/';
|
|
||||||
ret = i+1; /* chop after the last separator */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
len = WideCharToMultiByte(CP_UTF8, 0, wlibpath, ret, NULL, 0, NULL, NULL);
|
|
||||||
sopath = rb_utf8_str_new(0, len);
|
|
||||||
libpath = RSTRING_PTR(sopath);
|
|
||||||
WideCharToMultiByte(CP_UTF8, 0, wlibpath, ret, libpath, len, NULL, NULL);
|
|
||||||
rb_str_resize(wsopath, 0);
|
|
||||||
}
|
|
||||||
#elif defined(HAVE_DLADDR)
|
|
||||||
sopath = dladdr_path((void *)(VALUE)expand_include_path);
|
|
||||||
libpath = RSTRING_PTR(sopath);
|
libpath = RSTRING_PTR(sopath);
|
||||||
#else
|
|
||||||
# error relative load path is not supported on this platform.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined DOSISH && !defined _WIN32
|
|
||||||
translit_char(libpath, '\\', '/');
|
|
||||||
#elif defined __CYGWIN__
|
|
||||||
{
|
|
||||||
const int win_to_posix = CCP_WIN_A_TO_POSIX | CCP_RELATIVE;
|
|
||||||
size_t newsize = cygwin_conv_path(win_to_posix, libpath, 0, 0);
|
|
||||||
if (newsize > 0) {
|
|
||||||
VALUE rubylib = rb_str_new(0, newsize);
|
|
||||||
char *p2 = RSTRING_PTR(rubylib);
|
|
||||||
if (cygwin_conv_path(win_to_posix, libpath, p2, newsize) == 0) {
|
|
||||||
rb_str_resize(sopath, 0);
|
|
||||||
sopath = rubylib;
|
|
||||||
libpath = p2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
p = strrchr(libpath, '/');
|
p = strrchr(libpath, '/');
|
||||||
if (p) {
|
if (p) {
|
||||||
static const char bindir[] = "/bin";
|
static const char bindir[] = "/bin";
|
||||||
|
|
Loading…
Reference in a new issue