components/lua/patches/solaris-64-bit.patch
author James Chang <james.c.chang@Oracle.COM>
Fri, 02 Oct 2015 10:50:45 -0700
changeset 4915 48f204cc245c
parent 2104 72ce614559ff
permissions -rw-r--r--
PSARC/2015/333 EOL of grails 21494758 Removal of GRAILS from Solaris 21494777 Removal of GRAILS man page from Solaris

When looking for lua shared objects, dynamically adjust the pathnames to
include "64/", when running a 64-bit lua executable.

For example:
  /usr/lib/lua/5.2/gv.so
becomes:
  /usr/lib/lua/5.2/64/gv.so

The lua maintainers are not interested in this patch.

--- src/loadlib.c.orig	2014-09-19 06:57:40.032464104 -0700
+++ src/loadlib.c	2014-09-19 16:39:01.502592411 -0700
@@ -346,29 +346,94 @@
 }
 
 
+/*
+** Return 1 if template is a shared object (has an extension of ".so"),
+** otherwise 0.
+*/
+static int
+issharedobj(const char *template) {
+  const char *ext;
+  if (strlen(template) < 3)
+    return 0;
+  ext = template + strlen(template) - 3;
+  return strcmp(ext, ".so") == 0;
+}
+
+/*
+** Return 1 if this is a 64-bit executable, otherwise 0.
+*/
+static int is64bit() {
+  return sizeof(void *) == 8;
+}
+
 static const char *searchpath (lua_State *L, const char *name,
                                              const char *path,
                                              const char *sep,
                                              const char *dirsep) {
   luaL_Buffer msg;  /* to build error message */
+  char *name64;
   luaL_buffinit(L, &msg);
   if (*sep != '\0')  /* non-empty separator? */
     name = luaL_gsub(L, name, sep, dirsep);  /* replace it by 'dirsep' */
+  if (is64bit()) {
+    name64 = calloc(strlen(name) + 4, 1);
+    strcpy(name64, "64/");
+    strcat(name64, name);
+  } else
+    name64 = strdup(name);
   while ((path = pushnexttemplate(L, path)) != NULL) {
-    const char *filename = luaL_gsub(L, lua_tostring(L, -1),
-                                     LUA_PATH_MARK, name);
+    char *filename;
+    const char *item = lua_tostring(L, -1);
+
+    if (is64bit() && issharedobj(item)) {
+      name = name64;
+      if (strstr(item, LUA_PATH_MARK))
+        filename = (char *)luaL_gsub(L, item, LUA_PATH_MARK, name);
+      else {
+        /*
+         * There's nothing to substitute, so we have to go digging through the
+         * path to find where to put the 64-bit directory.  Search for "/" in
+         * the template element until we can't find any more, replace that with
+         * "?", and replace that with "/64/".
+         */
+        char *p1, *p2;
+        char *s = strdup(item);
+        for (p1 = s; p1; p1 = strstr(p1 + 1, "/"))
+          p2 = p1;
+        if (p2 != s)
+          *p2 = '?';
+        else {
+          /*
+           * We didn't find any slashes; that either means there aren't any, or
+           * item is in the root directory.
+           */
+          free(s);
+          s = calloc(strlen(item) + 3, 1);
+          if (item[0] == '/')
+            strcpy(s, "/64");
+          else
+            strcpy(s, "64/");
+          strcat(s, item);
+        }
+        filename = (char *)luaL_gsub(L, s, LUA_PATH_MARK, "/64/");
+        free(s);
+      }
+    } else
+      filename = (char *)luaL_gsub(L, item, LUA_PATH_MARK, name);
     lua_remove(L, -2);  /* remove path template */
-    if (readable(filename))  /* does file exist and is readable? */
+    if (readable(filename)) {  /* does file exist and is readable? */
+      free(name64);
       return filename;  /* return that file name */
+    }
     lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
     lua_remove(L, -2);  /* remove file name */
     luaL_addvalue(&msg);  /* concatenate error msg. entry */
   }
   luaL_pushresult(&msg);  /* create error message */
+  free(name64);
   return NULL;  /* not found */
 }
 
-
 static int ll_searchpath (lua_State *L) {
   const char *f = searchpath(L, luaL_checkstring(L, 1),
                                 luaL_checkstring(L, 2),