diff --git a/librb/configure.ac b/librb/configure.ac index 127214d36..f2e5acbcf 100644 --- a/librb/configure.ac +++ b/librb/configure.ac @@ -211,8 +211,9 @@ AC_CHECK_TYPE([sa_family_t], [], dnl check for various functions... -AC_CHECK_FUNCS([snprintf vsnprintf socketpair gettimeofday writev sendmsg gmtime_r strtok_r usleep posix_spawn strlcpy strlcat strnlen fstat signalfd select poll kevent port_create epoll_ctl arc4random getrusage timerfd_create]) +AC_CHECK_FUNCS([snprintf vsnprintf socketpair gettimeofday writev sendmsg gmtime_r strtok_r usleep posix_spawn getexecname strlcpy strlcat strnlen fstat signalfd select poll kevent port_create epoll_ctl arc4random getrusage timerfd_create]) +AC_SEARCH_LIBS(dlinfo, dl, AC_DEFINE(HAVE_DLINFO, 1, [Define if you have dlinfo])) AC_SEARCH_LIBS(nanosleep, rt posix4, AC_DEFINE(HAVE_NANOSLEEP, 1, [Define if you have nanosleep])) AC_SEARCH_LIBS(timer_create, rt, AC_DEFINE(HAVE_TIMER_CREATE, 1, [Define if you have timer_create])) RB_CHECK_TIMER_CREATE diff --git a/librb/include/rb_tools.h b/librb/include/rb_tools.h index 9a2e29499..31edb9f12 100644 --- a/librb/include/rb_tools.h +++ b/librb/include/rb_tools.h @@ -371,5 +371,6 @@ void rb_zstring_append_from_c(rb_zstring_t *zs, const char *buf, size_t len); char *rb_zstring_to_c(rb_zstring_t *zs, char *buf, size_t len); char *rb_zstring_to_c_alloc(rb_zstring_t *zs); size_t rb_zstring_to_ptr(rb_zstring_t *zs, void **ptr); +const char *rb_path_to_self(void); #endif /* __TOOLS_H__ */ diff --git a/librb/src/export-syms.txt b/librb/src/export-syms.txt index ecf64e40c..7a1b0cc5b 100644 --- a/librb/src/export-syms.txt +++ b/librb/src/export-syms.txt @@ -188,3 +188,4 @@ rb_zstring_serialized rb_zstring_to_c rb_zstring_to_c_alloc rb_zstring_to_ptr +rb_path_to_self diff --git a/librb/src/unix.c b/librb/src/unix.c index 31ecac352..10c8051e0 100644 --- a/librb/src/unix.c +++ b/librb/src/unix.c @@ -26,19 +26,23 @@ #include #include - #ifndef _WIN32 #include +#ifdef HAVE_DLINFO +# include +# include +#endif + +#ifdef __APPLE__ +#include +#include +#endif #if defined(HAVE_SPAWN_H) && defined(HAVE_POSIX_SPAWN) #include -#ifdef __APPLE__ -#include -#endif - #ifndef __APPLE__ extern char **environ; #endif @@ -151,5 +155,36 @@ rb_getpid(void) return getpid(); } +const char * +rb_path_to_self(void) +{ + static char path_buf[4096]; +#if defined(HAVE_GETEXECNAME) + char *s = getexecname(); + if (s == NULL) + return NULL; + realpath(s, path_buf); + return path_buf; +#elif defined(HAVE_DLINFO) + struct link_map *map = NULL; + dlinfo(RTLD_SELF, RTLD_DI_LINKMAP, &map); + if (map == NULL) + return NULL; + realpath(map->l_name, path_buf); +#elif defined(__linux__) + if (readlink("/proc/self/exe", path_buf, sizeof path_buf) != -1) + return path_buf; + return NULL; +#elif defined(__APPLE__) + char tmp_path[4096]; + uint32_t pathlen = 4096; + + if (_NSGetExecutablePath(tmp_path, &pathlen) < 0) + return NULL; + + realpath(tmp_path, path_buf); + return path_buf; +#endif +} #endif /* !WIN32 */ diff --git a/librb/src/win32.c b/librb/src/win32.c index b1011a50d..bf0635fd7 100644 --- a/librb/src/win32.c +++ b/librb/src/win32.c @@ -614,6 +614,15 @@ rb_strerror(int error) rb_strlcpy(buf, _rb_strerror(error), sizeof(buf)); return buf; } + +const char * +rb_path_to_self(void) +{ + static char path_buf[MAX_PATH]; + GetModuleFileName(NULL, exepath, MAX_PATH); + return path_buf; +} + #else /* win32 not supported */ int rb_init_netio_win32(void)