diff --git a/Makefile b/Makefile index 7c5043867..fbe092472 100644 --- a/Makefile +++ b/Makefile @@ -79,7 +79,8 @@ TEST_PREREQ += lib/libtestutil-closedir$(SHLIB_SUFFIX) \ lib/libtestutil-0getgroups$(SHLIB_SUFFIX) \ lib/libtestutil-dupgetgroups$(SHLIB_SUFFIX) \ lib/libtestutil-time$(SHLIB_SUFFIX) \ - lib/libtestutil-mktime$(SHLIB_SUFFIX) + lib/libtestutil-mktime$(SHLIB_SUFFIX) \ + lib/libtestutil-tcl_loadfile$(SHLIB_SUFFIX) endif endif @@ -660,6 +661,9 @@ lib/libtestutil-time$(SHLIB_SUFFIX): lib/libtestutil-mktime$(SHLIB_SUFFIX): $(MAKE) --no-print-directory -C lib $(@F) +lib/libtestutil-tcl_loadfile$(SHLIB_SUFFIX): + $(MAKE) --no-print-directory -C lib $(@F) + # example configs for test rules testsuite/example/.modulespath: testsuite/example/.modulespath.in $(translate-in-script) @@ -1172,6 +1176,7 @@ $(V).SILENT: initdir pkgdoc doc version.inc share/rpm/environment-modules.spec \ lib/libtestutil-getpwuid$(SHLIB_SUFFIX) lib/libtestutil-getgroups$(SHLIB_SUFFIX) \ lib/libtestutil-0getgroups$(SHLIB_SUFFIX) lib/libtestutil-mktime$(SHLIB_SUFFIX) \ lib/libtestutil-dupgetgroups$(SHLIB_SUFFIX) lib/libtestutil-time$(SHLIB_SUFFIX) \ + lib/libtestutil-tcl_loadfile$(SHLIB_SUFFIX) \ testsuite/example/.modulespath testsuite/example/modulespath-wild \ testsuite/example/modulerc testsuite/example/initrc-1 testsuite/example/initrc \ dist-tar dist-gzip dist-bzip2 dist-win $(MODULECMDTEST) $(MODULECMDTEST)_i diff --git a/NEWS.rst b/NEWS.rst index f81d73123..06ab3049d 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -130,6 +130,8 @@ Modules 5.7.0 (not yet released) or :subcmd:`sh-to-mod` sub-command, does not get access to shell aliases, functions or completions settings only available in interactive sessions or defined in profile files. (fix issue #646) +* Report a global known error when Modules Tcl extension library cannot be + loaded. (fix issue #644) .. _5.6 release notes: diff --git a/lib/.gitignore b/lib/.gitignore index b52804364..f968b7127 100644 --- a/lib/.gitignore +++ b/lib/.gitignore @@ -16,6 +16,7 @@ /libtestutil-dupgetgroups.so /libtestutil-time.so /libtestutil-mktime.so +/libtestutil-tcl_loadfile.so /envmodules.c.gcov /envmodules.gcda /envmodules.gcno diff --git a/lib/Makefile.in b/lib/Makefile.in index 68aefbf43..4393d61d8 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -60,6 +60,10 @@ libtestutil-mktime@SHLIB_SUFFIX@: testutil-mktime.c $(ECHO_CC) $(LDCC) $< -o $@ +libtestutil-tcl_loadfile@SHLIB_SUFFIX@: testutil-tcl_loadfile.c + $(ECHO_CC) + $(LDCC) $< -o $@ + clean: rm -f envmodules.o rm -f libtclenvmodules@TCL_SHLIB_SUFFIX@ @@ -70,6 +74,7 @@ clean: rm -f libtestutil-dupgetgroups@SHLIB_SUFFIX@ rm -f libtestutil-time@SHLIB_SUFFIX@ rm -f libtestutil-mktime@SHLIB_SUFFIX@ + rm -f libtestutil-tcl_loadfile@SHLIB_SUFFIX@ rm -f envmodules.c.gcov envmodules.gcda envmodules.gcno distclean: clean @@ -95,4 +100,4 @@ $(V).SILENT: envmodules.o libtclenvmodules@TCL_SHLIB_SUFFIX@ \ libtestutil-closedir@SHLIB_SUFFIX@ libtestutil-getpwuid@SHLIB_SUFFIX@ \ libtestutil-getgroups@SHLIB_SUFFIX@ libtestutil-0getgroups@SHLIB_SUFFIX@ \ libtestutil-dupgetgroups@SHLIB_SUFFIX@ libtestutil-time@SHLIB_SUFFIX@ \ - libtestutil-mktime@SHLIB_SUFFIX@ + libtestutil-mktime@SHLIB_SUFFIX@ libtestutil-tcl_loadfile@SHLIB_SUFFIX@ diff --git a/lib/testutil-tcl_loadfile.c b/lib/testutil-tcl_loadfile.c new file mode 100644 index 000000000..57527eb04 --- /dev/null +++ b/lib/testutil-tcl_loadfile.c @@ -0,0 +1,35 @@ +/************************************************************************* + * + * TESTUTIL-TCL_LOADFILE.C, Superseded Tcl_LoadFile function for test purpose + * Copyright (C) 2026 Xavier Delaruelle + * + * 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 2 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 . + * + ************************************************************************/ + +#include + +#if !defined (__APPLE__) + +int Tcl_LoadFile(Tcl_Interp *interp, Tcl_Obj *pathPtr, + const char *const symbols[], int flags, void *procVPtrs, + Tcl_LoadHandle *handlePtr) +{ + Tcl_SetObjResult(interp, Tcl_ObjPrintf("error message")); + return TCL_ERROR; +} + +#endif + +/* vim:set tabstop=3 shiftwidth=3 expandtab autoindent: */ diff --git a/tcl/main.tcl.in b/tcl/main.tcl.in index 59ad2de6d..e16452542 100644 --- a/tcl/main.tcl.in +++ b/tcl/main.tcl.in @@ -625,7 +625,11 @@ if {[catch { ##nagelfar ignore +2 Too long line @libtclenvmodules@if {[file readable [getConf tcl_ext_lib]]} { @libtclenvmodules@ reportDebug "Load Tcl extension library ([getConf tcl_ext_lib])" - @libtclenvmodules@ load [file normalize [getConf tcl_ext_lib]] Envmodules + @libtclenvmodules@ if {[catch { + @libtclenvmodules@ load [file normalize [getConf tcl_ext_lib]] Envmodules + @libtclenvmodules@ } errMsg]} { + @libtclenvmodules@ reportErrorAndExit $errMsg + @libtclenvmodules@ } @libtclenvmodules@ setState tcl_ext_lib_loaded 1 @libtclenvmodules@} # use fallback procs if extension library is not loaded diff --git a/testsuite/modules.00-init/005-init_ts.exp b/testsuite/modules.00-init/005-init_ts.exp index 705d2e601..7ac00fb45 100644 --- a/testsuite/modules.00-init/005-init_ts.exp +++ b/testsuite/modules.00-init/005-init_ts.exp @@ -168,6 +168,7 @@ if {$install_libtclenvmodules eq {y}} { set dupgetgroupslib_file lib/libtestutil-dupgetgroups$install_shlib_suffix set timelib_file lib/libtestutil-time$install_shlib_suffix set mktimelib_file lib/libtestutil-mktime$install_shlib_suffix + set tcl_loadfilelib_file lib/libtestutil-tcl_loadfile$install_shlib_suffix } # check file permission capabilities diff --git a/testsuite/modules.00-init/150-access-init.exp b/testsuite/modules.00-init/150-access-init.exp index 09297561d..3ae31096d 100644 --- a/testsuite/modules.00-init/150-access-init.exp +++ b/testsuite/modules.00-init/150-access-init.exp @@ -75,7 +75,7 @@ if {[info exists tclextlib_file]} { } else { set tserr "$error_msgs: couldn't load file \"$tclextlib_file_abs_re\":.*" } - testouterr_cmd_re sh {-V} {} $tserr + testouterr_cmd_re sh {-V} ERR $tserr file delete $tclextlib_file file rename $tclextlib_file.orig $tclextlib_file } diff --git a/testsuite/modules.00-init/190-tcl_ext_lib.exp b/testsuite/modules.00-init/190-tcl_ext_lib.exp new file mode 100644 index 000000000..56a097e63 --- /dev/null +++ b/testsuite/modules.00-init/190-tcl_ext_lib.exp @@ -0,0 +1,44 @@ +############################################################################## +# Modules Revision 3.0 +# Providing a flexible user environment +# +# File: modules.00-init/%M% +# Revision: %I% +# First Edition: 2026/07/17 +# Last Mod.: %U%, %G% +# +# Authors: Xavier Delaruelle, xavier.delaruelle@cea.fr +# +# Description: Testuite testsequence +# Command: load +# Modulefiles: bar, foo +# Sub-Command: +# +# Comment: %C{ +# Test Modules Tcl extended library +# }C% +# +############################################################################## + +skip_if_quick_mode + +# test error report when loading library +# ensure we are in a specific test mode so we can play with installed files +# no need to specifically test on Darwin system and on Tcl < 9 +if {[siteconfig_isStderrTty] && $tcl_platform(os) ne "Darwin" &&\ + [info exists tclextlib_file] && [info exists tcl_loadfilelib_file] &&\ + [file exists $tcl_loadfilelib_file] && [cmpversion $tclsh_version 9.0] > -1} { + setenv_var LD_PRELOAD $tcl_loadfilelib_file + + set tserr "$error_msgs: error message" + testouterr_cmd sh {-V} ERR $tserr + + unsetenv_var LD_PRELOAD +} + + +# +# Cleanup +# + +reset_test_env