POW_LIB
PBX_WORKING_FORK
LIBOBJS
+PERMANENT_DLOPEN
DISABLE_XMLDOC
CONFIG_LIBXML2
JANSSON_LIBS
docdir
oldincludedir
includedir
-runstatedir
localstatedir
sharedstatedir
sysconfdir
with_x11
with_z
enable_xmldoc
+enable_permanent_dlopen
enable_largefile
enable_internal_poll
enable_asteriskssl
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
-runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
- -runstatedir | --runstatedir | --runstatedi | --runstated \
- | --runstate | --runstat | --runsta | --runst | --runs \
- | --run | --ru | --r)
- ac_prev=runstatedir ;;
- -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
- | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
- | --run=* | --ru=* | --r=*)
- runstatedir=$ac_optarg ;;
-
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
- libdir localedir mandir runstatedir
+ libdir localedir mandir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
- --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
--enable-dev-mode Turn on developer mode
--enable-coverage Turn on code coverage tracking (for gcov)
--disable-xmldoc Explicitly disable XML documentation
+ --enable-permanent-dlopen
+ Enable when your libc has a permanent dlopen like
+ musl
--disable-largefile omit support for large files
--enable-internal-poll Use Asterisk's poll implementation
--disable-asteriskssl Disable Asterisk's SSL wrapper library
+fi
+
+# Check whether --enable-permanent-dlopen was given.
+if test "${enable_permanent_dlopen+set}" = set; then :
+ enableval=$enable_permanent_dlopen; case "${enableval}" in
+ y|ye|yes) PERMANENT_DLOPEN=yes ;;
+ n|no) PERMANENT_DLOPEN=no ;;
+ *) as_fn_error $? "bad value ${enableval} for --enable-permanent-dlopen" "$LINENO" 5 ;;
+ esac
+else
+ PERMANENT_DLOPEN=no
+fi
+
+
+
+if test "${PERMANENT_DLOPEN}" == "yes"; then
+
+$as_echo "#define HAVE_PERMANENT_DLOPEN 1" >>confdefs.h
+
fi
# some embedded systems omit internationalization (locale) support
We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
We can't simply define LARGE_OFF_T to be 9223372036854775807,
since some C++ compilers masquerading as C compilers
incorrectly reject 9223372036854775807. */
-#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
+#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
&& LARGE_OFF_T % 2147483647 == 1)
? 1 : -1];
if (*(data + i) != *(data3 + i))
return 14;
close (fd);
- free (data);
- free (data3);
return 0;
}
_ACEOF
fi
+AC_ARG_ENABLE([permanent-dlopen],
+ [AS_HELP_STRING([--enable-permanent-dlopen],
+ [Enable when your libc has a permanent dlopen like musl])],
+ [case "${enableval}" in
+ y|ye|yes) PERMANENT_DLOPEN=yes ;;
+ n|no) PERMANENT_DLOPEN=no ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for --enable-permanent-dlopen) ;;
+ esac], [PERMANENT_DLOPEN=no])
+
+AC_SUBST([PERMANENT_DLOPEN])
+if test "${PERMANENT_DLOPEN}" == "yes"; then
+ AC_DEFINE([HAVE_PERMANENT_DLOPEN], 1, [Define to support libc with permanent dlopen.])
+fi
+
# some embedded systems omit internationalization (locale) support
AC_CHECK_HEADERS([xlocale.h])
/* Define to 1 if your system defines the file flag O_SYMLINK in fcntl.h */
#undef HAVE_O_SYMLINK
+/* Define to support libc with permanent dlopen. */
+#undef HAVE_PERMANENT_DLOPEN
+
/* Define to indicate the PostgreSQL library */
#undef HAVE_PGSQL
static struct ast_vector_string startup_errors;
static struct ast_str *startup_error_builder;
+#if defined(HAVE_PERMANENT_DLOPEN)
+#define FIRST_DLOPEN 999
+
+struct ao2_container *info_list = NULL;
+
+struct info_list_obj {
+ const struct ast_module_info *info;
+ int dlopened;
+ char name[0];
+};
+
+static struct info_list_obj *info_list_obj_alloc(const char *name,
+ const struct ast_module_info *info)
+{
+ struct info_list_obj *new_entry;
+
+ new_entry = ao2_alloc(sizeof(*new_entry) + strlen(name) + 1, NULL);
+
+ if (!new_entry) {
+ return NULL;
+ }
+
+ strcpy(new_entry->name, name); /* SAFE */
+ new_entry->info = info;
+ new_entry->dlopened = FIRST_DLOPEN;
+
+ return new_entry;
+}
+
+AO2_STRING_FIELD_CMP_FN(info_list_obj, name)
+
+static char *get_name_from_resource(const char *resource)
+{
+ int len;
+ const char *last_three;
+ char *mod_name;
+
+ if (!resource) {
+ return NULL;
+ }
+
+ len = strlen(resource);
+ if (len > 3) {
+ last_three = &resource[len-3];
+ if (!strcasecmp(last_three, ".so")) {
+ mod_name = ast_calloc(1, len - 2);
+ if (mod_name) {
+ ast_copy_string(mod_name, resource, len - 2);
+ return mod_name;
+ } else {
+ /* Unable to allocate memory. */
+ return NULL;
+ }
+ }
+ }
+
+ /* Resource is the name - happens when manually unloading a module. */
+ mod_name = ast_calloc(1, len + 1);
+ if (mod_name) {
+ ast_copy_string(mod_name, resource, len + 1);
+ return mod_name;
+ }
+
+ /* Unable to allocate memory. */
+ return NULL;
+}
+
+static void manual_mod_reg(const void *lib, const char *resource)
+{
+ struct info_list_obj *obj_tmp;
+ char *mod_name;
+
+ if (lib) {
+ mod_name = get_name_from_resource(resource);
+ if (mod_name) {
+ obj_tmp = ao2_find(info_list, mod_name, OBJ_SEARCH_KEY);
+ if (obj_tmp) {
+ if (obj_tmp->dlopened == FIRST_DLOPEN) {
+ obj_tmp->dlopened = 1;
+ } else {
+ ast_module_register(obj_tmp->info);
+ }
+ ao2_ref(obj_tmp, -1);
+ }
+ ast_free(mod_name);
+ }
+ }
+}
+
+static void manual_mod_unreg(const char *resource)
+{
+ struct info_list_obj *obj_tmp;
+ char *mod_name;
+
+ /* When Asterisk shuts down the destructor is called automatically. */
+ if (ast_shutdown_final()) {
+ return;
+ }
+
+ mod_name = get_name_from_resource(resource);
+ if (mod_name) {
+ obj_tmp = ao2_find(info_list, mod_name, OBJ_SEARCH_KEY);
+ if (obj_tmp) {
+ ast_module_unregister(obj_tmp->info);
+ ao2_ref(obj_tmp, -1);
+ }
+ ast_free(mod_name);
+ }
+}
+#endif
+
static __attribute__((format(printf, 1, 2))) void module_load_error(const char *fmt, ...)
{
char *copy = NULL;
/* give the module a copy of its own handle, for later use in registrations and the like */
*((struct ast_module **) &(info->self)) = mod;
+
+#if defined(HAVE_PERMANENT_DLOPEN)
+ if (mod->flags.builtin != 1) {
+ struct info_list_obj *obj_tmp = ao2_find(info_list, info->name,
+ OBJ_SEARCH_KEY);
+
+ if (!obj_tmp) {
+ obj_tmp = info_list_obj_alloc(info->name, info);
+ if (obj_tmp) {
+ ao2_link(info_list, obj_tmp);
+ ao2_ref(obj_tmp, -1);
+ }
+ } else {
+ ao2_ref(obj_tmp, -1);
+ }
+ }
+#endif
}
static int module_post_register(struct ast_module *mod)
error = dlerror();
ast_log(AST_LOG_ERROR, "Failure in dlclose for module '%s': %s\n",
S_OR(name, "unknown"), S_OR(error, "Unknown error"));
+#if defined(HAVE_PERMANENT_DLOPEN)
+ } else {
+ manual_mod_unreg(name);
+#endif
}
}
resource_being_loaded = mod;
mod->lib = dlopen(filename, flags);
+#if defined(HAVE_PERMANENT_DLOPEN)
+ manual_mod_reg(mod->lib, mod->resource);
+#endif
if (resource_being_loaded) {
struct ast_str *list;
int c = 0;
resource_being_loaded = mod;
mod->lib = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
+#if defined(HAVE_PERMANENT_DLOPEN)
+ manual_mod_reg(mod->lib, mod->resource);
+#endif
if (resource_being_loaded) {
resource_being_loaded = NULL;
ast_verb(1, "Asterisk Dynamic Loader Starting:\n");
+#if defined(HAVE_PERMANENT_DLOPEN)
+ info_list = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_NOLOCK, 0, NULL,
+ info_list_obj_cmp_fn); /* must not be cleaned at shutdown */
+ if (!info_list) {
+ fprintf(stderr, "Module info list allocation failure.\n");
+ return 1;
+ }
+#endif
+
AST_LIST_HEAD_INIT_NOLOCK(&load_order);
AST_DLLIST_LOCK(&module_list);