lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Am 19.09.2013 18:19 schröbte Philipp Janda:
Am 19.09.2013 17:10 schröbte Francesco Santini:

I guess linking lua with the module would help, but I would like to
avoid that if possible.

There is a glibc-specific dlopen-flag (man 3 dlopen):

This is not only for glibc. FreeBSD has it too.

RTLD_NOLOAD (since glibc 2.2)
     Don't load the library. This can be used to test if the library is
already resident (dlopen() returns NULL if it is not, or the library's
handle if it is resident). This flag can also be used to promote the
flags on a library that is already loaded. For example, a library that
was previously loaded with RTLD_LOCAL can be reopened with RTLD_NOLOAD |
RTLD_GLOBAL. This flag is not specified in POSIX.1-2001.

I don't know if this also works from within the dynamically loaded
library, but you can try (and tell us how it went) ...

I got curious ...
So for the record, this actually seems to work! I've attached the code I used (which I hereby place in the public domain), maybe it is useful for someone else ...

Tested on:
- Ubuntu 12.04.3, x86, Lua 5.1
- Ubuntu 13.04, amd64, Lua 5.1 + Lua 5.2
- FreeBSD 9.1, amd64, Lua 5.1

Philipp

#ifndef FIXLUASO_H_
#define FIXLUASO_H_

/* Provides a C function macro that tries to reopen the Lua library
 * in global mode, so that C extension modules do not have to be
 * relinked for Lua VMs in shared libraries.
 */

/* detect some form of UNIX, so that unistd.h can be included to
 * use other feature macros */
#if defined( unix ) || defined( __unix ) || defined( __unix__ ) || \
    defined( __TOS_AIX__ ) || defined( _SYSTYPE_BSD ) || \
    defined( HAVE_UNISTD_H )

#include <unistd.h>
/* check for minimum POSIX version that specifies dlopen etc. */
#if (defined( _POSIX_VERSION ) && _POSIX_VERSION >= 200112L) || \
    defined( HAVE_DLFCN_H )

#include <dlfcn.h>
/* check for the existence of the RTLD_NOLOAD flag
 * - GLIBC has it (since 2.2)
 * - FreeBSD has it
 */
#ifdef RTLD_NOLOAD

/* Lua VM library names to try
 * Most of them require the dev-package to be installed,
 * but guessing the real library names for multiple distros
 * is pretty difficult ...
 * If the library is not in the default search path you can
 * set LD_LIBRARY_PATH, or use FIXLUASO_LIBNAME to specify
 * an absolute path to the library.
 */
static char const* fixluaso_lib_names[] = {
/* you can define your own custom name via compiler define: */
#ifdef FIXLUASO_LIBNAME
  FIXLUASO_LIBNAME,
#endif /* custom Lua library name */
  "liblua5.2.so",       /* Lua 5.2, Debian/Ubuntu naming */
  "liblua52.so",
  "liblua.so",          /* default name from Lua's makefile */
  "liblua5.1.so",       /* Lua 5.1, Debian/Ubuntu naming */
  "liblua51.so",
  "libluajit-5.1.so",   /* LuaJIT default name */
};

#define FIX_LUA_SO() \
  do { \
    unsigned i = 0; \
    for( ; i < sizeof( fixluaso_lib_names )/sizeof( *fixluaso_lib_names ); ++i ) { \
      if( dlopen( fixluaso_lib_names[ i ], RTLD_LAZY|RTLD_GLOBAL|RTLD_NOLOAD ) ) \
        break; \
    } \
  } while( 0 )

#endif /* has RTLD_NOLOAD */
#endif /* has dlfcn.h */
#endif /* has unistd.h */

/* define fallback */
#ifndef FIX_LUA_SO
#define FIX_LUA_SO()
#endif

#endif /* FIXLUASO_H_ */