Commit 5b7b932c authored by Stephen Morris's avatar Stephen Morris
Browse files

[2980] Changes in preparation for merge

Absence of "libdl" on BSD systems required an addition to configure.ac
to check its presence.  Problems with converting "pointer to object"
to "pointer to void*" via reinterpret_cast on Solaris required an
extension to the Pointer_converter class.
parent 43ea555f
......@@ -430,6 +430,7 @@ AC_SUBST(B10_CXXFLAGS)
AC_SEARCH_LIBS(inet_pton, [nsl])
AC_SEARCH_LIBS(recvfrom, [socket])
AC_SEARCH_LIBS(nanosleep, [rt])
AC_SEARCH_LIBS(dlsym, [dl])
# Checks for header files.
......
......@@ -35,13 +35,14 @@ libb10_hooks_la_SOURCES += hooks_manager.cc hooks_manager.h
libb10_hooks_la_SOURCES += library_handle.cc library_handle.h
libb10_hooks_la_SOURCES += library_manager.cc library_manager.h
libb10_hooks_la_SOURCES += library_manager_collection.cc library_manager_collection.h
libb10_hooks_la_SOURCES += pointer_converter.h
libb10_hooks_la_SOURCES += server_hooks.cc server_hooks.h
nodist_libb10_hooks_la_SOURCES = hooks_messages.cc hooks_messages.h
libb10_hooks_la_CXXFLAGS = $(AM_CXXFLAGS)
libb10_hooks_la_CPPFLAGS = $(AM_CPPFLAGS) $(LOG4CPLUS_INCLUDES)
libb10_hooks_la_LDFLAGS = $(AM_LDFLAGS) -ldl
libb10_hooks_la_LDFLAGS = $(AM_LDFLAGS)
libb10_hooks_la_LIBADD =
libb10_hooks_la_LIBADD += $(top_builddir)/src/lib/log/libb10-log.la
libb10_hooks_la_LIBADD += $(top_builddir)/src/lib/util/libb10-util.la
......
......@@ -15,6 +15,7 @@
#include <hooks/callout_handle.h>
#include <hooks/callout_manager.h>
#include <hooks/hooks_log.h>
#include <hooks/pointer_converter.h>
#include <boost/static_assert.hpp>
......@@ -145,20 +146,20 @@ CalloutManager::callCallouts(int hook_index, CalloutHandle& callout_handle) {
HOOKS_CALLOUT_CALLED).arg(current_library_)
.arg(ServerHooks::getServerHooks()
.getName(current_hook_))
.arg(reinterpret_cast<void*>(i->second));
.arg(PointerConverter(i->second).dlsymPtr());
} else {
LOG_ERROR(hooks_logger, HOOKS_CALLOUT_ERROR)
.arg(current_library_)
.arg(ServerHooks::getServerHooks()
.getName(current_hook_))
.arg(reinterpret_cast<void*>(i->second));
.arg(PointerConverter(i->second).dlsymPtr());
}
} catch (...) {
// Any exception, not just ones based on isc::Exception
LOG_ERROR(hooks_logger, HOOKS_CALLOUT_EXCEPTION)
.arg(current_library_)
.arg(ServerHooks::getServerHooks().getName(current_hook_))
.arg(reinterpret_cast<void*>(i->second));
.arg(PointerConverter(i->second).dlsymPtr());
}
}
......
......@@ -24,9 +24,9 @@ namespace {
const int BIND10_HOOKS_VERSION = 1;
// Names of the framework functions.
const char* LOAD_FUNCTION_NAME = "load";
const char* UNLOAD_FUNCTION_NAME = "unload";
const char* VERSION_FUNCTION_NAME = "version";
const char* const LOAD_FUNCTION_NAME = "load";
const char* const UNLOAD_FUNCTION_NAME = "unload";
const char* const VERSION_FUNCTION_NAME = "version";
// Typedefs for pointers to the framework functions.
typedef int (*version_function_ptr)();
......
......@@ -17,6 +17,7 @@
#include <hooks/callout_manager.h>
#include <hooks/library_handle.h>
#include <hooks/library_manager.h>
#include <hooks/pointer_converter.h>
#include <hooks/server_hooks.h>
#include <string>
......@@ -29,78 +30,6 @@ using namespace std;
namespace isc {
namespace hooks {
/// @brief Local class for conversion of void pointers to function pointers
///
/// Converting between void* and function pointers in C++ is fraught with
/// difficulty and pitfalls, e.g. see
/// https://groups.google.com/forum/?hl=en&fromgroups#!topic/comp.lang.c++/37o0l8rtEE0
///
/// The method given in that article - convert using a union is used here. A
/// union is declared (and zeroed) and the appropriate member extracted when
/// needed.
class PointerConverter {
public:
/// @brief Constructor
///
/// Zeroes the union and stores the void* pointer we wish to convert (the
/// one returned by dlsym).
///
/// @param dlsym_ptr void* pointer returned by call to dlsym()
PointerConverter(void* dlsym_ptr) {
memset(&pointers_, 0, sizeof(pointers_));
pointers_.dlsym_ptr = dlsym_ptr;
}
/// @name Pointer accessor functions
///
/// It is up to the caller to ensure that the correct member is called so
/// that the correct trype of pointer is returned.
///
///@{
/// @brief Return pointer to callout function
///
/// @return Pointer to the callout function
CalloutPtr calloutPtr() const {
return (pointers_.callout_ptr);
}
/// @brief Return pointer to load function
///
/// @return Pointer to the load function
load_function_ptr loadPtr() const {
return (pointers_.load_ptr);
}
/// @brief Return pointer to unload function
///
/// @return Pointer to the unload function
unload_function_ptr unloadPtr() const {
return (pointers_.unload_ptr);
}
/// @brief Return pointer to version function
///
/// @return Pointer to the version function
version_function_ptr versionPtr() const {
return (pointers_.version_ptr);
}
///@}
private:
/// @brief Union linking void* and pointers to functions.
union {
void* dlsym_ptr; // void* returned by dlsym
CalloutPtr callout_ptr; // Pointer to callout
load_function_ptr load_ptr; // Pointer to load function
unload_function_ptr unload_ptr; // Pointer to unload function
version_function_ptr version_ptr; // Pointer to version function
} pointers_;
};
// Open the library
......
// Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef POINTER_CONVERTER_H
#define POINTER_CONVERTER_H
#include <hooks/hooks.h>
namespace isc {
namespace hooks {
/// @brief Local class for conversion of void pointers to function pointers
///
/// Converting between void* and function pointers in C++ is fraught with
/// difficulty and pitfalls, e.g. see
/// https://groups.google.com/forum/?hl=en&fromgroups#!topic/comp.lang.c++/37o0l8rtEE0
///
/// The method given in that article - convert using a union is used here. A
/// union is declared (and zeroed) and the appropriate member extracted when
/// needed.
class PointerConverter {
public:
/// @brief Constructor
///
/// Zeroes the union and stores the void* pointer we wish to convert (the
/// one returned by dlsym).
///
/// @param dlsym_ptr void* pointer returned by call to dlsym()
PointerConverter(void* dlsym_ptr) {
memset(&pointers_, 0, sizeof(pointers_));
pointers_.dlsym_ptr = dlsym_ptr;
}
/// @brief Constructor
///
/// Zeroes the union and stores the CalloutPtr pointer we wish to convert.
/// This constructor is used in debug messages; output of a pointer to
/// an object (including to a function) is, on some compilers, printed as
/// "1".
///
/// @param callout_ptr Pointer to callout function
PointerConverter(CalloutPtr callout_ptr) {
memset(&pointers_, 0, sizeof(pointers_));
pointers_.callout_ptr = callout_ptr;
}
/// @name Pointer accessor functions
///
/// It is up to the caller to ensure that the correct member is called so
/// that the correct type of pointer is returned.
///
///@{
/// @brief Return pointer returned by dlsym call
///
/// @return void* pointer returned by the call to dlsym(). This can be
/// used in statements that print the hexadecimal value of the
/// symbol.
void* dlsymPtr() const {
return (pointers_.dlsym_ptr);
}
/// @brief Return pointer to callout function
///
/// @return Pointer to the callout function
CalloutPtr calloutPtr() const {
return (pointers_.callout_ptr);
}
/// @brief Return pointer to load function
///
/// @return Pointer to the load function
load_function_ptr loadPtr() const {
return (pointers_.load_ptr);
}
/// @brief Return pointer to unload function
///
/// @return Pointer to the unload function
unload_function_ptr unloadPtr() const {
return (pointers_.unload_ptr);
}
/// @brief Return pointer to version function
///
/// @return Pointer to the version function
version_function_ptr versionPtr() const {
return (pointers_.version_ptr);
}
///@}
private:
/// @brief Union linking void* and pointers to functions.
union {
void* dlsym_ptr; // void* returned by dlsym
CalloutPtr callout_ptr; // Pointer to callout
load_function_ptr load_ptr; // Pointer to load function
unload_function_ptr unload_ptr; // Pointer to unload function
version_function_ptr version_ptr; // Pointer to version function
} pointers_;
};
} // namespace hooks
} // namespace isc
#endif // POINTER_CONVERTER_H
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment