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),