@@ -34,4 +34,5 @@ indent:
$(MAKE) -C include $@
test: all
+ $(MAKE) -C src test
$(MAKE) -C tests test
@@ -160,7 +160,10 @@ clean:
distclean: clean
rm -f $(GENERATED) $(SWIGFILES)
+test:
+ bash -e exception.sh test
+
indent:
../../scripts/Lindent $(filter-out $(GENERATED),$(wildcard *.[ch]))
-.PHONY: all clean pywrap rubywrap swigify install install-pywrap install-rubywrap distclean
+.PHONY: all clean pywrap rubywrap swigify install install-pywrap install-rubywrap distclean test indent
@@ -1,3 +1,4 @@
+#!/bin/bash -e
function except() {
echo "
%exception $1 {
@@ -9,10 +10,35 @@ echo "
}
"
}
-if ! ${CC:-gcc} -x c -c -I../include - -aux-info temp.aux < ../include/semanage/semanage.h
+
+if [ $# -eq 1 ] && [ "$1" = "test" ]
then
- # clang does not support -aux-info so fall back to gcc
- gcc -x c -c -I../include - -aux-info temp.aux < ../include/semanage/semanage.h
+ # Ensure that "gcc -aux-info" produces the same list of functions as the sed command.
+ # The main difference between these way of producing the list of exported
+ # functions is that "gcc -aux-info" automatically inserts "extern" to all
+ # declarations and writes each one on a single line.
+ # clang does not support -aux-info, so skip the test if generating the aux file failed.
+ if ${CC:-gcc} -x c -c -I../include - -aux-info temp.aux < ../include/semanage/semanage.h
+ then
+ FCT_FROM_AUX="$(awk '/include\/semanage\/.*extern int/ { print $6 }' temp.aux | sort -u)"
+ FCT_FROM_SED="$(cat ../include/semanage/*.h | sed -n 's/^extern \+int \+\([0-9A-Za-z_]\+\) *(.*$/\1/p' | sort -u)"
+ if [ "$FCT_FROM_AUX" != "$FCT_FROM_SED" ]
+ then
+ echo >&2 'Error ensuring that all exported functions that return an int are handled by exception.sh.'
+ echo >&2 'Here are functions that were not found in "gcc -aux-info" but that were collected by "sed":'
+ comm -13 <(echo "$FCT_FROM_AUX") <(echo "$FCT_FROM_SED")
+ echo >&2 'Here are functions in "gcc -aux-info" that may be missing "extern" in header file:'
+ comm -23 <(echo "$FCT_FROM_AUX") <(echo "$FCT_FROM_SED")
+ exit 1
+ fi
+ fi
+ rm -f -- temp.aux -.o
+ exit
fi
-for i in `awk '/extern int/ { print $6 }' temp.aux`; do except $i ; done
+
+# shellcheck disable=SC2013
+for i in $(cat ../include/semanage/*.h | sed -n 's/^extern \+int \+\([0-9A-Za-z_]\+\) *(.*$/\1/p')
+do
+ except "$i"
+done
rm -f -- temp.aux -.o
libsemanage currently uses "gcc -aux-info" in order to generate glue code for its Python bindings that throws an exception when a function returns a negative integer value. This causes issues when another compiler than gcc is used (such as clang or icc), as option -aux-info is specific to gcc. Replace "gcc -aux-info" with a command that parses the content of header files using "sed". As this is more fragile (because the declaration of functions is not normalized), add a new target to the Makefile in order to test that the new method does not produce different results with "make CC=gcc test". When reverting commit b915c7a9d330 ("libsemanage: mark all exported function "extern""), "make test" now fails as expected: bash -e exception.sh test Error ensuring that all exported functions that return an int are handled by exception.sh. Here are functions that were not found in "gcc -aux-info" but that were collected by "sed": Here are functions in "gcc -aux-info" that may be missing "extern" in header file: semanage_access_check semanage_begin_transaction semanage_commit semanage_connect semanage_disconnect semanage_get_disable_dontaudit semanage_get_hll_compiler_path ... make: *** [Makefile:202: test] Error 1 Original thread: https://lore.kernel.org/selinux/20191012172357.GB19655@imap.altlinux.org/T/#ma78bd7fe71fb5784387a8c0cebd867d6c02ee6e4 Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org> Cc: Michael Shigorin <mike@altlinux.org> --- libsemanage/Makefile | 1 + libsemanage/src/Makefile | 5 ++++- libsemanage/src/exception.sh | 34 ++++++++++++++++++++++++++++++---- 3 files changed, 35 insertions(+), 5 deletions(-)