Hi,
At Wed, 3 Mar 2004 01:05:21 +0900,
David Garamond wrote in [ruby-talk:94067]:
Is there a binary .tar.gz or a relocatable RPM for ruby 1.8.x which can
be installed onto a custom per-user directory without requiring root
privilege? I find it easy to do this with the mswin32 version.
Ruby embeds absolute load paths, for the sake of UNIX tradition
and security issue.
However, it might not be major problem if $SAFE == 0, so you
could make relocatable binary with the following path and
--enable-load-relative configure option, if you use /proc fs on
linux.
* configure.in (load-relative): separate load-relative feature from
platform.
* ruby.c (ruby_init_loadpath): appendant to load-relative feature.
[ruby-talk:94067]
Index: configure.in
===================================================================
RCS file: /cvs/ruby/src/ruby/configure.in,v
retrieving revision 1.226
diff -u -2 -p -d -r1.226 configure.in
--- configure.in 16 Feb 2004 06:45:31 -0000 1.226
+++ configure.in 3 Mar 2004 01:52:44 -0000
@@ -1387,13 +1387,27 @@ case "$target_os" in
;;
esac
+
+AC_ARG_ENABLE(load-relative,
+ [ --enable-load-relative enable initial load path relative to ruby],
+ [loadrelative=$enableval], [loadrelative=no])
+
case "$target_os" in
cygwin*|mingw*|*djgpp*|os2-emx*)
- RUBY_LIB_PREFIX="/lib/ruby"
+ loadrelative=yes
+ ;;
+ linux*)
;;
*)
- RUBY_LIB_PREFIX="${prefix}/lib/ruby"
+ loadrelative=no
;;
esac
-RUBY_LIB_PATH="${RUBY_LIB_PREFIX}/${MAJOR}.${MINOR}"
+if test "x$loadrelative" = xyes; then
+ AC_DEFINE(LOAD_RELATIVE, 1)
+ AC_DEFINE_UNQUOTED(RUBY_PREFIX, "${prefix}")
+ RUBY_PREFIX=""
+else
+ RUBY_PREFIX="${prefix}"
+fi
+RUBY_LIB_PATH="${RUBY_PREFIX}/lib/ruby/${MAJOR}.${MINOR}"
AC_ARG_WITH(sitedir,
@@ -1402,11 +1416,6 @@ AC_ARG_WITH(sitedir,
[sitedir='${prefix}/lib/ruby/site_ruby'])
SITE_DIR="`eval \"echo ${sitedir}\"`"
-case "$target_os" in
- cygwin*|mingw*|*djgpp*|os2-emx*)
- RUBY_SITE_LIB_PATH="`expr "$SITE_DIR" : "$prefix\(/.*\)"`" ||
- RUBY_SITE_LIB_PATH="$SITE_DIR";;
- *)
- RUBY_SITE_LIB_PATH="$SITE_DIR";;
-esac
+RUBY_SITE_LIB_PATH="${RUBY_PREFIX}`expr "$SITE_DIR" : "$prefix\(/.*\)"`" ||
+RUBY_SITE_LIB_PATH="$SITE_DIR"
RUBY_SITE_LIB_PATH2="${RUBY_SITE_LIB_PATH}/${MAJOR}.${MINOR}"
Index: ruby.c
===================================================================
RCS file: /cvs/ruby/src/ruby/ruby.c,v
retrieving revision 1.86
diff -u -2 -p -d -r1.86 ruby.c
--- ruby.c 21 Jan 2004 16:47:14 -0000 1.86
+++ ruby.c 3 Mar 2004 01:58:56 -0000
@@ -233,4 +233,37 @@ translate_char(p, from, to)
#endif
+#if defined LOAD_RELATIVE && defined RUBY_PREFIX
+#ifdef __linux__
+static char *
+getlibpath(lib, size, pos)
+ char *lib;
+ int size;
+ long pos;
+{
+ FILE *maps = fopen("/proc/self/maps", "r");
+ long start, end;
+ char *p;
+
+ if (!maps) return 0;
+ *lib = 0;
+ while (fscanf(maps, "%x-%x", &start, &end) == 2) {
+ if (start <= pos && pos < end) {
+ fscanf(maps, " %*s %*s %*s %*s ");
+ fgets(lib, size, maps);
+ fclose(maps);
+ p = strchr(lib, '\n');
+ if (p) *p = 0;
+ return lib;
+ }
+ else {
+ fscanf(maps, "%*[^\n]\n");
+ }
+ }
+ fclose(maps);
+ return 0;
+}
+#endif
+#endif
+
void
ruby_init_loadpath()
@@ -258,4 +291,11 @@ ruby_init_loadpath()
#elif defined(__EMX__)
_execname(libpath, FILENAME_MAX);
+#elif defined(RUBY_PREFIX)
+ if (rb_safe_level() > 0 ||
+ !getlibpath(libpath, sizeof libpath, (long)ruby_init_loadpath)) {
+ strncpy(libpath, RUBY_PREFIX, sizeof libpath);
+ p = libpath + strlen(libpath);
+ goto init;
+ }
#endif
@@ -267,5 +307,6 @@ ruby_init_loadpath()
if (p) {
*p = 0;
- if (p-libpath > 3 && !strcasecmp(p-4, "/bin")) {
+ if (p-libpath > 3 &&
+ !(strcasecmp(p-4, "/bin") && strcasecmp(p-4, "/lib"))) {
p -= 4;
*p = 0;
@@ -277,4 +318,5 @@ ruby_init_loadpath()
}
+ init:
rest = FILENAME_MAX - (p - libpath);