librb: add rb_path_to_self(), which provides fairly reliable runtime path detection

This commit is contained in:
William Pitcock 2016-03-21 21:07:53 -05:00
parent 427ed8ead6
commit 790e4dce4e
5 changed files with 53 additions and 6 deletions

View file

@ -211,8 +211,9 @@ AC_CHECK_TYPE([sa_family_t], [],
dnl check for various functions... 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(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])) AC_SEARCH_LIBS(timer_create, rt, AC_DEFINE(HAVE_TIMER_CREATE, 1, [Define if you have timer_create]))
RB_CHECK_TIMER_CREATE RB_CHECK_TIMER_CREATE

View file

@ -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(rb_zstring_t *zs, char *buf, size_t len);
char *rb_zstring_to_c_alloc(rb_zstring_t *zs); char *rb_zstring_to_c_alloc(rb_zstring_t *zs);
size_t rb_zstring_to_ptr(rb_zstring_t *zs, void **ptr); size_t rb_zstring_to_ptr(rb_zstring_t *zs, void **ptr);
const char *rb_path_to_self(void);
#endif /* __TOOLS_H__ */ #endif /* __TOOLS_H__ */

View file

@ -188,3 +188,4 @@ rb_zstring_serialized
rb_zstring_to_c rb_zstring_to_c
rb_zstring_to_c_alloc rb_zstring_to_c_alloc
rb_zstring_to_ptr rb_zstring_to_ptr
rb_path_to_self

View file

@ -26,19 +26,23 @@
#include <librb_config.h> #include <librb_config.h>
#include <rb_lib.h> #include <rb_lib.h>
#ifndef _WIN32 #ifndef _WIN32
#include <sys/wait.h> #include <sys/wait.h>
#ifdef HAVE_DLINFO
# include <link.h>
# include <dlfcn.h>
#endif
#ifdef __APPLE__
#include <mach-o/dyld.h>
#include <crt_externs.h>
#endif
#if defined(HAVE_SPAWN_H) && defined(HAVE_POSIX_SPAWN) #if defined(HAVE_SPAWN_H) && defined(HAVE_POSIX_SPAWN)
#include <spawn.h> #include <spawn.h>
#ifdef __APPLE__
#include <crt_externs.h>
#endif
#ifndef __APPLE__ #ifndef __APPLE__
extern char **environ; extern char **environ;
#endif #endif
@ -151,5 +155,36 @@ rb_getpid(void)
return getpid(); 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 */ #endif /* !WIN32 */

View file

@ -614,6 +614,15 @@ rb_strerror(int error)
rb_strlcpy(buf, _rb_strerror(error), sizeof(buf)); rb_strlcpy(buf, _rb_strerror(error), sizeof(buf));
return 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 */ #else /* win32 not supported */
int int
rb_init_netio_win32(void) rb_init_netio_win32(void)