From bfd747340aa6fda550af21ba26bf1966e0269daf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=A4ckerlin?= Date: Tue, 22 Sep 2015 07:42:24 +0000 Subject: [PATCH] don't throw exception in destructur when card has been removed --- ax_check_qt.m4 | 121 ++++++++++++++++++++---------------- ax_init_standard_project.m4 | 103 +++++++++++++++++++++++------- configure.ac | 4 +- src/cryptoki.cxx | 6 +- src/cryptoki.hxx | 11 ++-- src/pcsc.hxx | 7 ++- 6 files changed, 165 insertions(+), 87 deletions(-) diff --git a/ax_check_qt.m4 b/ax_check_qt.m4 index 1a5dafb..479f65c 100644 --- a/ax_check_qt.m4 +++ b/ax_check_qt.m4 @@ -1,10 +1,10 @@ # SYNOPSIS # # Check if a module exists: -# AX_CHECK_QT([qt_prefix], [list-of-qt-modules], [optional-modules]) +# AX_CHECK_QT([qt_prefix], [list-of-qt-modules], [optional-modules] [flags]) # # Abort if a module does not exist: -# AX_REQUIRE_QT([qt_prefix], [list-of-qt-modules], [optional-modules]) +# AX_REQUIRE_QT([qt_prefix], [list-of-qt-modules], [optional-modules] [flags]) # # DESCRIPTIONS # @@ -35,6 +35,18 @@ # Optional list of more, optional modules, e.g. modules that # exist only in Qt5, but not in Qt4, such as QtWidgets or # QtWebKitWidgets +# +# flags +# +# Optional flages, space separated from this list: +# +# manualflags +# +# CXXFLAGS, CPPFLAGS and LIBS variables are not +# automatically expanded, but you need to add the +# qt_prefix_CXXFLAGS, qt_prefix_CPPFLAGS and qt_prefix_LIBS +# variables manually where you need them. This is useful, +# if some build targets need a feature and some don't. AC_DEFUN([AX_CXX_QT_TOOL], [ @@ -83,6 +95,7 @@ AC_DEFUN([AX_CXX_QT_TOOLS], [ AC_DEFUN([AX_CHECK_QT], [ qt_modules="$2" qt_modules_optional="$3" + qt_flags="$4" AX_CXX_QT_TOOLS HAVE_$1=0 PKG_PROG_PKG_CONFIG @@ -91,17 +104,37 @@ AC_DEFUN([AX_CHECK_QT], [ AC_DEFINE([HAVE_$1]) QTDIR=$(${PKG_CONFIG} --variable=prefix Qt5Core) QT_PLUGIN_PATH=${QTDIR}/share/qt5/plugins - CPPFLAGS+=" ${[$1]5_CFLAGS}" MOC_FLAGS+=" -DHAVE_$1=1 ${[$1]5_CFLAGS}" - CXXFLAGS+=" ${[$1]5_CFLAGS}" - LIBS+=" ${[$1]5_LIBS}" + [$1]_CPPFLAGS="${[$1]5_CFLAGS}" + [$1]_CXXFLAGS="${[$1]5_CFLAGS}" + [$1]_LIBS="${[$1]5_LIBS}" + AC_SUBST([$1]_CPPFLAGS) + AC_SUBST([$1]_CXXFLAGS) + if test "${qt_flags/manualflags/}" = "${qt_flags}"; then + CPPFLAGS+=" ${[$1]_CPPFLAGS}" + CXXFLAGS+=" ${[$1]_CXXFLAGS}" + LIBS+=" ${[$1]_LIBS}" + AC_MSG_NOTICE([Adding flags for $1]) + else + AC_MSG_NOTICE([To enable $1, add $1_CPPFLAGS, $1_CXXFLAGS and $1_LIBS]) + fi PKG_REQUIREMENTS+=" ${qt_modules//Qt/Qt5}" if test -n "${qt_modules_optional}"; then PKG_CHECK_MODULES([$1]5_OPTIONAL, [${qt_modules_optional//Qt/Qt5}], [ - CPPFLAGS+=" ${[$1]5_OPTIONAL_CFLAGS}" MOC_FLAGS+=" ${[$1]5_OPTIONAL_CFLAGS}" - CXXFLAGS+=" ${[$1]5_OPTIONAL_CFLAGS}" - LIBS+=" ${[$1]5_OPTIONAL_LIBS}" + [$1]_CPPFLAGS+=" ${[$1]5_OPTIONAL_CFLAGS}" + [$1]_CXXFLAGS+=" ${[$1]5_OPTIONAL_CFLAGS}" + [$1]_LIBS+=" ${[$1]5_OPTIONAL_LIBS}" + AC_SUBST([$1]_CPPFLAGS) + AC_SUBST([$1]_CXXFLAGS) + if test "${qt_flags/manualflags/}" = "${qt_flags}"; then + CPPFLAGS+=" ${[$1]5_OPTIONAL_CFLAGS}" + CXXFLAGS+=" ${[$1]5_OPTIONAL_CFLAGS}" + LIBS+=" ${[$1]5_OPTIONAL_LIBS}" + AC_MSG_NOTICE([Adding flags for $1]) + else + AC_MSG_NOTICE([To enable $1, add $1_CPPFLAGS, $1_CXXFLAGS and $1_LIBS]) + fi PKG_REQUIREMENTS+=" ${qt_modules_optional//Qt/Qt5}" ], [ AC_MSG_NOTICE([Not found: ${qt_modules_optional//Qt/Qt5}]) @@ -113,17 +146,36 @@ AC_DEFUN([AX_CHECK_QT], [ AC_DEFINE([HAVE_$1]) QTDIR=$(${PKG_CONFIG} --variable=prefix QtCore) QT_PLUGIN_PATH=${QTDIR}/share/qt/plugins - CPPFLAGS+=" ${$1_CFLAGS}" MOC_FLAGS+=" -DHAVE_$1=1 ${$1_CFLAGS}" - CXXFLAGS+=" ${$1_CFLAGS}" - LIBS+=" ${$1_LIBS}" + [$1]_CPPFLAGS="${[$1]_CFLAGS}" + [$1]_CXXFLAGS="${[$1]_CFLAGS}" + AC_SUBST([$1]_CPPFLAGS) + AC_SUBST([$1]_CXXFLAGS) + if test "${qt_flags/manualflags/}" = "${qt_flags}"; then + CPPFLAGS+=" ${[$1]_CPPFLAGS}" + CXXFLAGS+=" ${[$1]_CXXFLAGS}" + LIBS+=" ${[$1]_LIBS}" + AC_MSG_NOTICE([Adding flags for $1]) + else + AC_MSG_NOTICE([To enable $1, add $1_CPPFLAGS, $1_CXXFLAGS and $1_LIBS]) + fi PKG_REQUIREMENTS+=" ${qt_modules}" if test -n "$3"; then PKG_CHECK_MODULES($1_OPTIONAL, [${qt_modules_optional}], [ - CPPFLAGS+=" ${$1_OPTIONAL_CFLAGS}" - MOC_FLAGS+=" ${$1_OPTIONAL_CFLAGS}" - CXXFLAGS+=" ${$1_OPTIONAL_CFLAGS}" - LIBS+=" ${$1_OPTIONAL_LIBS}" + MOC_FLAGS+="${$1_OPTIONAL_CFLAGS}" + [$1]_CPPFLAGS+=" ${$1_OPTIONAL_CFLAGS}" + [$1]_CXXFLAGS+=" ${$1_OPTIONAL_CFLAGS}" + [$1]_LIBS+=" ${$1_OPTIONAL_LIBS}" + AC_SUBST([$1]_CPPFLAGS) + AC_SUBST([$1]_CXXFLAGS) + if test "${qt_flags/manualflags/}" = "${qt_flags}"; then + CPPFLAGS+=" ${$1_OPTIONAL_CFLAGS}" + CXXFLAGS+=" ${$1_OPTIONAL_CFLAGS}" + LIBS+=" ${$1_OPTIONAL_LIBS}" + AC_MSG_NOTICE([Adding flags for $1]) + else + AC_MSG_NOTICE([To enable $1, add $1_CPPFLAGS, $1_CXXFLAGS and $1_LIBS]) + fi PKG_REQUIREMENTS+=" ${qt_modules_optional}" ], [ AC_MSG_NOTICE([Not found: ${qt_modules_optional}]) @@ -133,7 +185,7 @@ AC_DEFUN([AX_CHECK_QT], [ ]) AM_CONDITIONAL(HAVE_$1, test $HAVE_[$1] -eq 1) AX_CHECK_VALID_CXX_FLAG([-fPIC -fPIE], [position independent code flag]) - if test "${MINGW}" != "no"; then + if test -n "${MINGW}"; then AX_CHECK_VALID_CXX_FLAG([-Wl,-subsystem,windows], [windows console flag]) fi AC_SUBST(QTDIR) @@ -169,42 +221,8 @@ qrc_%.cxx: %.qrc ']) -# SYNOPSIS -# -# AX_CHECK_QT([qt_prefix], [list-of-qt-modules], [optional-modules]) -# -# DESCRIPTIONS -# -# qt_prefix -# -# Each call to AX_CHECK_QT should have a different prefix -# value (with a few exceptions discussed later on). This value, -# usually provided in uppercase, is used as prefix to the -# variables holding the compiler flags and libraries reported by -# pkg-config. -# -# For instance, if your prefix was to be FOO you'll be provided -# two variables FOO_CFLAGS and FOO_LIBS. -# -# This will also be used as message during the configure checks: -# checking for FOO.... -# -# list-of-modules -# -# A single call to the macro can check for the presence of one or -# more qt modules; you'll see later how to make good use of this -# feature. Each entry in the list can have a version comparison -# specifier, with the same syntax as the Requires keyword in the -# data files themselves. -# -# optional-modules -# -# Optional list of more, optional modules, e.g. modules that -# exist only in Qt5, but not in Qt4, such as QtWidgets or -# QtWebKitWidgets - AC_DEFUN([AX_REQUIRE_QT], [ - AX_CHECK_QT([$1], [$2], [$3]) + AX_CHECK_QT([$1], [$2], [$3], [$4]) if ! test "$HAVE_$1" -eq 1; then AC_MSG_ERROR([Required Qt modules not found: $2]) fi @@ -213,7 +231,6 @@ AC_DEFUN([AX_REQUIRE_QT], [ # Omit Qt Keywords # AX_QT_NO_KEYWORDS - AC_DEFUN([AX_QT_NO_KEYWORDS], [ CPPFLAGS+=" -DQT_NO_KEYWORDS" ]) diff --git a/ax_init_standard_project.m4 b/ax_init_standard_project.m4 index eb2753d..d4126d1 100644 --- a/ax_init_standard_project.m4 +++ b/ax_init_standard_project.m4 @@ -8,17 +8,26 @@ m4_define([mrw_esyscmd_s], [m4_normalize(m4_esyscmd([$1]))]) # define least version number from subversion's revision number: # it is taken modulo 256 due to a bug on Apple's MacOSX -m4_define(x_least, mrw_esyscmd_s([ +m4_define(x_least, m4_ifdef([x_least_diff], mrw_esyscmd_s([ SVN_REVISION="ERROR-UNDEFINED-REVISION-to-be-built-in-subdirectory-of-svn-checkout" for path in . .. ../..; do if svn info $path 2>&1 > /dev/null; then - SVN_REVISION=$(LANG= svn info $path | sed -n 's/Last Changed Rev: //p') + SVN_REVISION=$(LANG= svn info $path | sed -n 's/^Revision: //p') + break; + fi + done + echo $ECHO_N $(($SVN_REVISION)) +]), mrw_esyscmd_s([ + SVN_REVISION="ERROR-UNDEFINED-REVISION-to-be-built-in-subdirectory-of-svn-checkout" + for path in . .. ../..; do + if svn info $path 2>&1 > /dev/null; then + SVN_REVISION=$(LANG= svn info $path | sed -n 's/^Revision: //p') break; fi done # Mac does not support LEAST > 255 echo $ECHO_N $(($SVN_REVISION%256)) -])) +]))) # define version number from subversion's revision number: # it is taken modulo 256 due to a bug on Apple's MacOSX # add to x_minor if revision number is > 256 @@ -26,15 +35,15 @@ m4_define(x_minor_diff, mrw_esyscmd_s([ SVN_REVISION="ERROR-UNDEFINED-REVISION-to-be-built-in-subdirectory-of-svn-checkout" for path in . .. ../..; do if svn info $path 2>&1 > /dev/null; then - SVN_REVISION=$(LANG= svn info $path | sed -n 's/Last Changed Rev: //p') + SVN_REVISION=$(LANG= svn info $path | sed -n 's/^Revision: //p') break; fi; done # Mac does not support LEAST > 255 echo $ECHO_N $(($SVN_REVISION/256)) -])) +]))) # setup version number -m4_define(x_version, [x_major.m4_eval(x_minor+x_minor_diff).x_least]) +m4_define(x_version, [x_major.m4_ifdef([x_least_diff], x_minor, m4_eval(x_minor+x_minor_diff)).m4_eval(m4_ifdef([x_least_diff], [x_least-x_least_diff], [x_least]))]) ## bugreport mail address is taken from in first line of AUTHORS m4_define(x_bugreport, mrw_esyscmd_s([ @@ -107,14 +116,27 @@ AC_DEFUN([AX_SUBST], [ # # configures the basic environment AC_DEFUN([AX_INIT_STANDARD_PROJECT], [ - MINGW=no - MAC=no - case $host in - *mingw*) MINGW=yes;; - *darwin* | *rhapsody* | *macosx*) MAC=yes;; - esac - AM_CONDITIONAL(MINGW, test "$MINGW" = "yes") - AM_CONDITIONAL(MAC, test "$MAC" = "yes") + AC_MSG_CHECKING([target platfrom]) + UNIX=1 + MINGW= + MACOSX= + for h in ${target} ${target_os} ${host} ${host_os} \ + ${build} ${build_os} $(uname -s 2> /dev/null); do + p="$h is generic Unix" + case "$h" in + (*mingw*) + UNIX=; MINGW=1; p="MinGW"; break;; + (*Darwin*|*darwin*|*rhapsody*|*macosx*) + UNIX=; MACOSX=1; p="MacOSX"; break;; + esac + done + AC_MSG_RESULT($p) + AM_CONDITIONAL(UNIX, test "$UNIX" = "1") + AM_CONDITIONAL(MINGW, test "$MINGW" = "1") + AM_CONDITIONAL(MACOSX, test "$MACOSX" = "1") + AX_SUBST(UNIX) + AX_SUBST(MINGW) + AX_SUBST(MACOSX) AM_CPPFLAGS+=" '-DMAKE_STRING(X)=\#X' '-DNAMESPACE=${PACKAGE_TARNAME//[^a-zA-Z0-9]/_}'" AX_SUBST(NUMBERS) AX_SUBST(HOME) @@ -127,7 +149,7 @@ AC_DEFUN([AX_INIT_STANDARD_PROJECT], [ AUTHOR=$(head -1 AUTHORS) AX_SUBST(AUTHOR) _AM_SUBST_NOTMAKE([AUTHOR]) - DISTRO=$(lsb_release -sc) + DISTRO=$(lsb_release -sc 2>/dev/null || uname -s 2>/dev/null) AX_SUBST(DISTRO) BUILD_NUMBER=${BUILD_NUMBER:-1} AX_SUBST(BUILD_NUMBER) @@ -156,11 +178,24 @@ AC_DEFUN([AX_INIT_STANDARD_PROJECT], [ - all warnings result in an error - doxygen warnings are treated as error too]); fi + AC_ARG_ENABLE(debug, + [AS_HELP_STRING([--enable-debug], + [compile for debugger])], + [have_debug="$enableval"; test "$enableval" = "yes" && \ + AM_CPPFLAGS="${AM_CPPFLAGS} -DDEBUG" && \ + AM_CXXFLAGS="${AM_CXXFLAGS:-} -ggdb3 -O0" && \ + AM_LDFLAGS="${AM_LDFLAGS} -ggdb3 -O0"]) + AM_CONDITIONAL(DEBUG, test "$enableval" = "yes") + if test "$have_debug" == "yes"; then + AC_MSG_NOTICE([Debug compile mode enabled]); + fi + AC_CONFIG_FILES([makefile]) AX_ADD_MAKEFILE_TARGET_DEP([clean-am], [clean-standard-project-targets], [makefile.in]) AX_ADD_MAKEFILE_TARGET_DEP([distclean-am], [distclean-standard-project-targets], [makefile.in]) AX_ADD_MAKEFILE_TARGET_DEP([maintainer-clean-am], [maintainer-clean-standard-project-targets], [makefile.in]) - test -f makefile.in && sed -i '1iEXTRA_DIST = ' makefile.in + test -f makefile.in && TMP_MAKEFILE="$( makefile.in test -f makefile.in && cat >> makefile.in <&1 | html2 | sed -n 's,.*/a/@href=\(.*\.h\)$,\1,gp'); do wget --unlink $f done - AM_CPPFLAGS+="-I$(pwd)" + AM_CPPFLAGS+=" -I$(pwd)" cd - fi ]) @@ -39,7 +39,7 @@ AX_CHECK_QT([QTNETWORK], [Qt5Network >= 5.2]) CPPFLAGS="${CPPFLAGS} -DQT_NO_KEYWORDS" # libraries used -if test "$MINGW" = "no"; then +if test -z "$MINGW"; then AX_PKG_REQUIRE([pcsc], [libpcsclite], [pcsclite.h]) AX_PKG_REQUIRE([pkcs11], [p11-kit-1], [pkcs11.h], [p11-kit libpkcs11-helper-1]) AX_PKG_REQUIRE([ssl], [libssl], [openssl/crypto.h], [openssl]) diff --git a/src/cryptoki.cxx b/src/cryptoki.cxx index acfe17b..2bdfacf 100644 --- a/src/cryptoki.cxx +++ b/src/cryptoki.cxx @@ -193,6 +193,8 @@ namespace cryptoki { Library::Init::~Init() { CRYPTOLOG("log"); + /// ignore failure in disconnect, possibly smartcard has + /// been removed try { //! calls @c C_Finalize check(_fn->C_Finalize(0), CRYPTOKI_FN_LOG("C_Finalize")); @@ -204,8 +206,10 @@ namespace cryptoki { _lib = 0; #endif _fn = 0; + } catch (std::exception& e) { + CRYPTOLOG("unloading cryptoki library failed, reason: "+e.what()); } catch (...) { - if (!std::uncaught_exception()) throw; + CRYPTOLOG("unloading cryptoki library failed"); } } diff --git a/src/cryptoki.hxx b/src/cryptoki.hxx index 5c5ef58..48ca777 100644 --- a/src/cryptoki.hxx +++ b/src/cryptoki.hxx @@ -1559,25 +1559,22 @@ namespace cryptoki { } ~Session() try { - CRYPTOLOG("log "<<(std::uncaught_exception()?"IN EXCEPTION":"")); + /// ignore failure in disconnect, possibly smartcard has + /// been removed try { logout(); } catch (const std::exception& x) { CRYPTOLOG("caught: "<C_Logout (_session._session), CRYPTOKI_FN_LOG("C_Logout")); } catch (const std::exception& x) { - if (!std::uncaught_exception()) throw; CRYPTOLOG("ERROR during error cleanup: "<check(_state, "disconnect smartcard"); + /// ignore failure in disconnect, possibly smartcard has + /// been removed } //! Get reader status. @@ -495,7 +495,8 @@ namespace pcsc { ~Connection() { CRYPTOLOG("Close Connection id="<<_id); _state = SCardReleaseContext(_id); - if (!std::uncaught_exception()) check("smartcard release context"); + /// ignore failure in disconnect, possibly smartcard has + /// been removed } //! Scans for available readers from a specified list of groups.