r26576: Allow the static module loading code to be used for the Python modules.
authorJelmer Vernooij <jelmer@samba.org>
Mon, 24 Dec 2007 05:54:30 +0000 (23:54 -0600)
committerStefan Metzmacher <metze@samba.org>
Mon, 24 Dec 2007 07:51:06 +0000 (01:51 -0600)
Simplify the way module initialization functions are handled.

28 files changed:
source/auth/auth.c
source/auth/config.mk
source/auth/credentials/config.mk
source/auth/gensec/gensec.c
source/build/smb_build/dot.pl
source/build/smb_build/header.pm
source/build/smb_build/input.pm
source/lib/events/events.c
source/lib/ldb/common/ldb_modules.c
source/lib/ldb/python.mk
source/lib/registry/config.mk
source/ntptr/ntptr_base.c
source/ntvfs/ntvfs_base.c
source/ntvfs/sysdep/sys_notify.c
source/param/param.i
source/param/param_wrap.c
source/param/share.c
source/rpc_server/service_rpc.c
source/scripting/ejs/smbcalls.c
source/scripting/python/config.m4
source/scripting/python/config.mk
source/scripting/python/modules.c [new file with mode: 0644]
source/scripting/python/smbpython.c
source/scripting/python/uuidmodule.c
source/selftest/env/Samba4.pm
source/smbd/process_model.c
source/smbd/server.c
source/torture/torture.c

index 918890b3f621d3e372f3fdb8e85ebeea8f1a649f..4bfc92e8f9de350a39e325762035440b8dcba8dd 100644 (file)
@@ -516,7 +516,7 @@ NTSTATUS auth_init(void)
 {
        static bool initialized = false;
 
-       init_module_fn static_init[] = STATIC_auth_MODULES;
+       init_module_fn static_init[] = { STATIC_auth_MODULES, NULL };
        
        if (initialized) return NT_STATUS_OK;
        initialized = true;
index 3514059cf00c42a9910e9fc1c24262cc0ab3c8e4..4d111107a971f7dffa489b6f95ffddbfd968775e 100644 (file)
@@ -92,6 +92,6 @@ PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL
 #######################
 
 [PYTHON::swig_auth]
-PUBLIC_DEPENDENCIES = auth_system_session LIBPYTHON
+PUBLIC_DEPENDENCIES = auth_system_session
 PRIVATE_DEPENDENCIES = SAMDB 
 SWIG_FILE = auth.i
index 4c8308d01f4ae5dc4796adf4f61f66c47fca22ad..8d33bdbd554fa35cfdc2e51234f683d301b1d3b7 100644 (file)
@@ -14,5 +14,5 @@ PRIVATE_DEPENDENCIES = \
                SECRETS
 
 [PYTHON::swig_credentials]
-PUBLIC_DEPENDENCIES = CREDENTIALS LIBPYTHON
+PUBLIC_DEPENDENCIES = CREDENTIALS
 SWIG_FILE = credentials.i
index f055b1a995c99ae5ea197019e68b86aa45111cd3..6f7ff91db6c6636fe5ecebfb1fc65493e80b1d37 100644 (file)
@@ -1268,7 +1268,7 @@ NTSTATUS gensec_init(struct loadparm_context *lp_ctx)
 {
        static bool initialized = false;
 
-       init_module_fn static_init[] = STATIC_gensec_MODULES;
+       init_module_fn static_init[] = { STATIC_gensec_MODULES, NULL };
        init_module_fn *shared_init;
 
        if (initialized) return NT_STATUS_OK;
index c8203d4cdd11f9ac81cce928101ef52a11dd5bcd..82f89c081a8b527889279fda25e963a462f33bd3 100755 (executable)
@@ -25,9 +25,11 @@ sub generate($$$)
 
        foreach my $part (values %{$depend}) {
                next if (defined($only) and not contains($only,$part->{NAME}));
-               foreach my $elem (@{$part->{PUBLIC_DEPENDENCIES}},
-                                 @{$part->{PRIVATE_DEPENDENCIES}}) {
-                       $res .= "\t\"$part->{NAME}\" -> \"$elem\";\n";
+               foreach my $elem (@{$part->{PUBLIC_DEPENDENCIES}}) {
+                       $res .= "\t\"$part->{NAME}\" -> \"$elem\"; /* public */\n";
+               }
+               foreach my $elem (@{$part->{PRIVATE_DEPENDENCIES}}) {
+                       $res .= "\t\"$part->{NAME}\" -> \"$elem\"; /* private */\n";
                }
        }
 
index 34e81a3a24ddeac89c69e23dadbe2de7e8d36829..b0dced48975d38e3179495530c1131d79d63db77 100644 (file)
@@ -39,16 +39,18 @@ sub _prepare_build_h($)
                $name =~ s/-/_/g;
                $DEFINE->{COMMENT} = "$key->{TYPE} $key->{NAME} INIT";
                $DEFINE->{KEY} = "STATIC_$name\_MODULES";
-               $DEFINE->{VAL} = "\\\n";
+               $DEFINE->{VAL} = "\\\n";
                foreach (@{$key->{INIT_FUNCTIONS}}) {
                        $DEFINE->{VAL} .= "\t$_, \\\n";
-                       my $fn = $key->{INIT_FUNCTION_TYPE};
-                       unless(defined($fn)) { $fn = "NTSTATUS (*) (void)"; }
-                       $fn =~ s/\(\*\)/$_/;
-                       $output .= "$fn;\n";
+                       unless (/{/) {
+                               my $fn = $key->{INIT_FUNCTION_TYPE};
+                               unless(defined($fn)) { $fn = "NTSTATUS (*) (void)"; }
+                               $fn =~ s/\(\*\)/$_/;
+                               $output .= "$fn;\n";
+                       }
                }
 
-               $DEFINE->{VAL} .= "\tNULL \\\n }";
+               $DEFINE->{VAL} =~ s/, \\\n$//g; # Remove the last comma
 
                push(@defines,$DEFINE);
        }
index 431fd3cb8359839a340617771f3d6a3866fe23c1..ae37a7602bcc54227247afb74687c8d072ca66d6 100644 (file)
@@ -108,7 +108,7 @@ sub check_module($$$)
                my $sane_subsystem = lc($mod->{SUBSYSTEM});
                $sane_subsystem =~ s/^lib//;
                $mod->{INSTALLDIR} = "MODULESDIR/$sane_subsystem";
-               push (@{$mod->{PRIVATE_DEPENDENCIES}}, $mod->{SUBSYSTEM});
+               push (@{$mod->{PUBLIC_DEPENDENCIES}}, $mod->{SUBSYSTEM});
        } 
        if (grep(/INTEGRATED/, @{$mod->{OUTPUT_TYPE}})) {
                push (@{$INPUT->{$mod->{SUBSYSTEM}}{INIT_FUNCTIONS}}, $mod->{INIT_FUNCTION}) if defined($mod->{INIT_FUNCTION});
@@ -147,14 +147,14 @@ sub check_library($$$)
        add_libreplace($lib);
 }
 
-sub check_python($$)
+sub check_python($$$)
 {
-       my ($INPUT, $python) = @_;
+       my ($INPUT, $python, $default_ot) = @_;
 
        return if ($INPUT->{LIBPYTHON}{ENABLE} ne "YES");
 
        $python->{INSTALLDIR} = "PYTHONDIR";
-       push (@{$python->{PUBLIC_DEPENDENCIES}}, "LIBPYTHON");
+       unless (defined($python->{CFLAGS})) { $python->{CFLAGS} = []; }
        if (defined($python->{SWIG_FILE})) {
                my $dirname = dirname($python->{SWIG_FILE});
                my $basename = basename($python->{SWIG_FILE}, ".i");
@@ -165,18 +165,20 @@ sub check_python($$)
                $python->{OBJ_FILES} = ["$dirname$basename\_wrap.o"];
                $python->{LIBRARY_REALNAME} = "_$basename.\$(SHLIBEXT)";
                $python->{PYTHON_FILES} = ["$dirname$basename.py"];
-               unless (defined($python->{CFLAGS})) { $python->{CFLAGS} = []; }
                push (@{$python->{CFLAGS}}, $config::config{CFLAG_NO_UNUSED_MACROS});
                push (@{$python->{CFLAGS}}, $config::config{CFLAG_NO_CAST_QUAL});
+               $python->{INIT_FUNCTION} = "{ (char *)\"_$basename\", init_$basename }";
        } else {
                my $basename = $python->{NAME};
                $basename =~ s/^python_//g;
                $python->{LIBRARY_REALNAME} = "$basename.\$(SHLIBEXT)";
+               $python->{INIT_FUNCTION} = "{ (char *)\"$basename\", init$basename }";
        }
+       push (@{$python->{CFLAGS}}, @{$INPUT->{EXT_LIB_PYTHON}->{CFLAGS}});
 
        $python->{SUBSYSTEM} = "LIBPYTHON";
 
-       check_module($INPUT, $python, ["SHARED_LIBRARY"]);
+       check_module($INPUT, $python, $default_ot);
 }
 
 sub check_binary($$)
@@ -204,7 +206,8 @@ sub import_integrated($$)
 
                push (@{$lib->{FULL_OBJ_LIST}}, "\$($mod->{TYPE}_$mod->{NAME}_FULL_OBJ_LIST)");
                push (@{$lib->{LINK_FLAGS}}, "\$($mod->{TYPE}_$mod->{NAME}_LINK_FLAGS)");
-               push (@{$lib->{PRIVATE_DEPENDENCIES}}, @{$mod->{PUBLIC_DEPENDENCIES}}) if defined($mod->{PUBLIC_DEPENDENCIES});
+               push (@{$lib->{CFLAGS}}, @{$mod->{CFLAGS}}) if defined($mod->{CFLAGS});
+               push (@{$lib->{PUBLIC_DEPENDENCIES}}, @{$mod->{PUBLIC_DEPENDENCIES}}) if defined($mod->{PUBLIC_DEPENDENCIES});
                push (@{$lib->{PRIVATE_DEPENDENCIES}}, @{$mod->{PRIVATE_DEPENDENCIES}}) if defined($mod->{PRIVATE_DEPENDENCIES});
 
                $mod->{ENABLE} = "NO";
@@ -288,7 +291,7 @@ sub check($$$$$)
                } elsif ($part->{TYPE} eq "BINARY") {
                        check_binary($INPUT, $part);
                } elsif ($part->{TYPE} eq "PYTHON") {
-                       check_python($INPUT, $part);
+                       check_python($INPUT, $part, $module_ot);
                } elsif ($part->{TYPE} eq "EXT_LIB") {
                } else {
                        die("Unknown type $part->{TYPE}");
index fd736e46d8d900ee212d346ed765362ee1dd74f1..db7c3a5066a3a1e4ef80da7dbc1389eb48b85ecc 100644 (file)
@@ -102,7 +102,7 @@ void event_set_default_backend(const char *backend)
 static void event_backend_init(void)
 {
 #if _SAMBA_BUILD_
-       init_module_fn static_init[] = STATIC_LIBEVENTS_MODULES;
+       init_module_fn static_init[] = { STATIC_LIBEVENTS_MODULES, NULL };
        init_module_fn *shared_init;
        if (event_backends) return;
        shared_init = load_samba_modules(NULL, global_loadparm, "events");
index 72ed9692980064d909dbe77c3b7a3100bee2b856..f30206dc5bc1cfc56bb00ee1e61142e723b7760e 100644 (file)
@@ -168,7 +168,7 @@ static const struct ldb_module_ops *ldb_find_module_ops(const char *name)
 
 int ldb_global_init(void)
 {
-       int (*static_init_fns[])(void) = STATIC_LIBLDB_MODULES;
+       int (*static_init_fns[])(void) = { STATIC_LIBLDB_MODULES, NULL };
 
        static int initialized = 0;
        int ret = 0, i;
index 12badf04f6e5b6c09c7ab362c65c524aa8e832d0..f81c2e3e16a7ff53839a589841158c0b6699004d 100644 (file)
@@ -1,7 +1,7 @@
 #######################
 # Start LIBRARY swig_ldb
 [PYTHON::swig_ldb]
-PUBLIC_DEPENDENCIES = LIBLDB LIBPYTHON
+PUBLIC_DEPENDENCIES = LIBLDB
 SWIG_FILE = ldb.i
 # End LIBRARY swig_ldb
 #######################
index b289ff9afdb17761c71b580ce69d53cfdb4ba7ac..f1f50479cbce66e5070bb5adaf55e6e876ba234a 100644 (file)
@@ -102,6 +102,6 @@ OBJ_FILES = \
                tests/registry.o
 
 [PYTHON::swig_registry]
-PUBLIC_DEPENDENCIES = registry LIBPYTHON
+PUBLIC_DEPENDENCIES = registry
 SWIG_FILE = registry.i
 
index e184afcfd5f2e83181257e488aa9288cc2b4fba4..275f2045248c95b960353255d49bb3994db440bc 100644 (file)
@@ -71,7 +71,7 @@ NTSTATUS ntptr_register(const void *_ops)
 
 NTSTATUS ntptr_init(struct loadparm_context *lp_ctx)
 {
-       init_module_fn static_init[] = STATIC_ntptr_MODULES;
+       init_module_fn static_init[] = { STATIC_ntptr_MODULES, NULL };
        init_module_fn *shared_init = load_samba_modules(NULL, lp_ctx, "ntptr");
 
        run_init_functions(static_init);
index 28f43eabe8a7d57d0a36e5608de622367b483c74..d4ae6c8b4fcfbf706f48532cfb6cad7c0b45010c 100644 (file)
@@ -202,7 +202,7 @@ NTSTATUS ntvfs_init_connection(TALLOC_CTX *mem_ctx, struct share_config *scfg, e
 NTSTATUS ntvfs_init(struct loadparm_context *lp_ctx)
 {
        static bool initialized = false;
-       init_module_fn static_init[] = STATIC_ntvfs_MODULES;
+       init_module_fn static_init[] = { STATIC_ntvfs_MODULES, NULL };
        init_module_fn *shared_init;
 
        if (initialized) return NT_STATUS_OK;
index 1664461d3324713d02f8c170b08dbcf3b092126c..a6d0a698bcb7094a58c806095b434f238f7e71f1 100644 (file)
@@ -125,7 +125,7 @@ _PUBLIC_ NTSTATUS sys_notify_init(void)
 {
        static bool initialized = false;
 
-       init_module_fn static_init[] = STATIC_sys_notify_MODULES;
+       init_module_fn static_init[] = { STATIC_sys_notify_MODULES, NULL };
        init_module_fn *shared_init;
 
        if (initialized) return NT_STATUS_OK;
index 55c7b3fe0cd0b578c737ecbef5efd7268fb25b2d..11cda9910a144765c0119249b4730eb08306cff7 100644 (file)
@@ -186,7 +186,7 @@ typedef struct param_context {
             struct param_opt *opt = param_get_add($self, parameter, section_name);
 
             talloc_free(opt->value);
-            opt->value = talloc_strdup(opt, PyObject_Str(ob));
+            opt->value = talloc_strdup(opt, PyString_AsString(PyObject_Str(ob)));
 
             return 0;
         }
index d594955f38040b20c7d84d1d1c9025c35c9b73ab..49c986aeb71bf471070751e66e21e12e73b68b81 100644 (file)
@@ -2747,7 +2747,7 @@ SWIGINTERN int param_set(param *self,char const *parameter,PyObject *ob,char con
             struct param_opt *opt = param_get_add(self, parameter, section_name);
 
             talloc_free(opt->value);
-            opt->value = talloc_strdup(opt, PyObject_Str(ob));
+            opt->value = talloc_strdup(opt, PyString_AsString(PyObject_Str(ob)));
 
             return 0;
         }
index 2ada9999ea834ef0c67f8ba486af597f332cfdfb..edbb68b5f01a54966db599e348e4f88ceb3a8516 100644 (file)
@@ -146,7 +146,7 @@ NTSTATUS share_get_context_by_name(TALLOC_CTX *mem_ctx, const char *backend_name
 */
 NTSTATUS share_init(void)
 {
-       init_module_fn static_init[] = STATIC_share_MODULES;
+       init_module_fn static_init[] = { STATIC_share_MODULES, NULL };
 
        run_init_functions(static_init);
 
index 33a86851a86805056d4aefd1e3227ccae5cad800..0483736912f81937449a01b0868158289db83442 100644 (file)
@@ -467,7 +467,7 @@ static NTSTATUS dcesrv_init(struct event_context *event_context,
 
 NTSTATUS server_service_rpc_init(void)
 {
-       init_module_fn static_init[] = STATIC_dcerpc_server_MODULES;
+       init_module_fn static_init[] = { STATIC_dcerpc_server_MODULES, NULL };
        init_module_fn *shared_init = load_samba_modules(NULL, global_loadparm, "dcerpc_server");
 
        run_init_functions(static_init);
index 8a3ce245d2ad1f36208f92864554593696341955..da13f1f6ef60d208d928f3adf22f50a95f432879 100644 (file)
@@ -173,7 +173,7 @@ _PUBLIC_ void ejs_exception(const char *reason)
 */
 void smb_setup_ejs_functions(void (*exception_handler)(const char *))
 {
-       init_module_fn static_init[] = STATIC_smbcalls_MODULES;
+       init_module_fn static_init[] = { STATIC_smbcalls_MODULES, NULL };
        init_module_fn *shared_init;
 
        ejs_exception_handler = exception_handler;
index 49ad7273a4445a2957f93e90c02e2d4086cdb1a1..b6ca7966df242261dd9c5a238b39438b3dc0a198 100644 (file)
@@ -24,7 +24,7 @@ fi
 PYTHON_LDFLAGS=`$PYTHON_CONFIG --ldflags`
 PYTHON_CFLAGS=`$PYTHON_CONFIG --cflags`
 
-SMB_EXT_LIB(LIBPYTHON, [$PYTHON_LDFLAGS], [$PYTHON_CFLAGS])
+SMB_EXT_LIB(EXT_LIB_PYTHON, [$PYTHON_LDFLAGS], [$PYTHON_CFLAGS])
 
 AC_MSG_CHECKING(working python module support)
 if test x$working_python = xyes
@@ -40,10 +40,12 @@ then
                ],[
                        Py_InitModule(NULL, NULL);
                ],[
-                       SMB_ENABLE(LIBPYTHON,YES)
+                       SMB_ENABLE(EXT_LIB_PYTHON,YES)
                        SMB_ENABLE(smbpython,YES)
+                       SMB_ENABLE(LIBPYTHON,YES)
                        AC_MSG_RESULT([yes])
                ],[
+                       SMB_ENABLE(EXT_LIB_PYTHON,NO)
                        SMB_ENABLE(LIBPYTHON,NO)
                        SMB_ENABLE(smbpython,NO)
                        AC_MSG_RESULT([no])
@@ -52,7 +54,8 @@ then
        LIBS="$ac_save_LIBS"
        CFLAGS="$ac_save_CFLAGS"
 else
-       SMB_ENABLE(LIBPYTHON,NO)
+       SMB_ENABLE(EXT_LIB_PYTHON,NO)
+       SMB_ENABLE(LIBPYTHONyy,NO)
        SMB_ENABLE(smbpython,NO)
        AC_MSG_RESULT([no])
 fi
index ac923cb8d135d2ae11b27e08c45b8c34cb3d1838..601e43290639a21e710af7f70acf6fa416c1f817 100644 (file)
@@ -1,7 +1,10 @@
 [BINARY::smbpython]
 PRIVATE_DEPENDENCIES = LIBPYTHON
-OBJ_FILES = \
-                       smbpython.o
+OBJ_FILES = smbpython.o
+
+[SUBSYSTEM::LIBPYTHON]
+PUBLIC_DEPENDENCIES = EXT_LIB_PYTHON
+OBJ_FILES = modules.o
 
 [PYTHON::python_uuid]
 PRIVATE_DEPENDENCIES = LIBNDR 
diff --git a/source/scripting/python/modules.c b/source/scripting/python/modules.c
new file mode 100644 (file)
index 0000000..6a766f3
--- /dev/null
@@ -0,0 +1,45 @@
+/* 
+   Unix SMB/CIFS implementation.
+   Samba utility functions
+   Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include <Python.h>
+#include "build.h"
+
+extern void init_ldb(void);
+extern void init_security(void);
+extern void init_registry(void);
+extern void init_param(void);
+extern void init_misc(void);
+extern void init_ldb(void);
+extern void init_auth(void);
+extern void init_credentials(void);
+extern void init_tdb(void);
+extern void init_dcerpc(void);
+extern void init_events(void);
+extern void inituuid(void);
+
+static struct _inittab py_modules[] = { STATIC_LIBPYTHON_MODULES };
+
+void py_load_samba_modules(void)
+{
+       int i;
+       for (i = 0; i < ARRAY_SIZE(py_modules); i++) {
+               PyImport_ExtendInittab(&py_modules[i]);
+       }
+}
index 43785765c122ba0255890de1eecf890e0030091e..19c458e7acbb37be67954918afe71cf38d89ad35 100644 (file)
 #include "includes.h"
 #include <Python.h>
 
-int main(int argc, char **argv) {
+void py_load_samba_modules(void);
+
+int main(int argc, char **argv) 
+{
+       py_load_samba_modules();
        return Py_Main(argc,argv);
 }
index 9ae432dfa5b82c6be97ebf3b874a5899ce759c3f..02c929d4a54b261d7c1d61400a04dae9f465a9c5 100644 (file)
@@ -26,7 +26,7 @@ static PyObject *uuid_random(PyObject *self, PyObject *args)
        struct GUID guid;
        char *str;
 
-       if (!PyArg_ParseTuple(args, ""))
+       if (!PyArg_ParseTuple(args, (char *)""))
                return NULL;
 
        guid = GUID_random();
@@ -51,7 +51,7 @@ PyDoc_STRVAR(param_doc, "UUID helper routines");
 
 PyMODINIT_FUNC inituuid(void)
 {
-       PyObject *mod = Py_InitModule3("uuid", methods, param_doc);
+       PyObject *mod = Py_InitModule3((char *)"uuid", methods, param_doc);
        if (mod == NULL)
                return;
 }
index 4f8b96d3320d1ce219452b7fe164dcb18f9b22ad..ae7302fc4a4bb9bac659c02a3841485a21af4dab 100644 (file)
@@ -640,6 +640,7 @@ nogroup:x:65534:nobody
        push (@provision_options, "NSS_WRAPPER_PASSWD=\"$nsswrap_passwd\"");
        push (@provision_options, "NSS_WRAPPER_GROUP=\"$nsswrap_group\"");
        if (defined($ENV{PROVISION_PYTHON})) {
+               push (@provision_options, "$self->{bindir}/smbpython");
                push (@provision_options, "$self->{setupdir}/provision.py");
        } else {
                push (@provision_options, "$self->{bindir}/smbscript");
index e240ae2c6093f38661685e880aecc8738c6be29e..dc3ede613c22f93250895a69cc28c6717cd06640 100644 (file)
@@ -82,7 +82,7 @@ _PUBLIC_ NTSTATUS register_process_model(const void *_ops)
 
 NTSTATUS process_model_init(struct loadparm_context *lp_ctx)
 {
-       init_module_fn static_init[] = STATIC_process_model_MODULES;
+       init_module_fn static_init[] = { STATIC_process_model_MODULES, NULL };
        init_module_fn *shared_init = load_samba_modules(NULL, lp_ctx, "process_model");
 
        run_init_functions(static_init);
index 3f1d3c35d8b3817d68d5d3a1ad84cb600cc287c8..78892b6760bca2067da843881713362ece402f6f 100644 (file)
@@ -187,7 +187,7 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[
        bool opt_interactive = false;
        int opt;
        poptContext pc;
-       init_module_fn static_init[] = STATIC_service_MODULES;
+       init_module_fn static_init[] = { STATIC_service_MODULES, NULL };
        init_module_fn *shared_init;
        struct event_context *event_ctx;
        NTSTATUS status;
index f0538c03623687cbb5667dfb18e5bd95b3c27f8b..6bce38363e7a34c35e8be0d4d0fc6c2f36c16f1c 100644 (file)
@@ -64,7 +64,7 @@ struct torture_context *torture_context_init(TALLOC_CTX *mem_ctx,
 
 int torture_init(void)
 {
-       init_module_fn static_init[] = STATIC_torture_MODULES;
+       init_module_fn static_init[] = { STATIC_torture_MODULES, NULL };
        init_module_fn *shared_init = load_samba_modules(NULL, cmdline_lp_ctx, "torture");
 
        run_init_functions(static_init);