Dynamic library loading functions were added to ddsrt
ddsrt_dlopen ddsrt_dlclose ddsrt_dlsym and ddsrt_dlerror functions can be used in posix and windows platforms that support dynamic loading Signed-off-by: Kurtulus Oksuztepe <kurtulus.oksuztepe@adlinktech.com>
This commit is contained in:
		
							parent
							
								
									98cf8e2ae5
								
							
						
					
					
						commit
						a65d3db7c8
					
				
					 9 changed files with 633 additions and 3 deletions
				
			
		| 
						 | 
				
			
			@ -66,6 +66,7 @@ list(APPEND headers
 | 
			
		|||
  "${include_path}/dds/ddsrt/misc.h"
 | 
			
		||||
  "${include_path}/dds/ddsrt/io.h"
 | 
			
		||||
  "${include_path}/dds/ddsrt/process.h"
 | 
			
		||||
  "${include_path}/dds/ddsrt/dynlib.h"
 | 
			
		||||
  "${include_path}/dds/ddsrt/strtod.h"
 | 
			
		||||
  "${include_path}/dds/ddsrt/strtol.h"
 | 
			
		||||
  "${include_path}/dds/ddsrt/types.h")
 | 
			
		||||
| 
						 | 
				
			
			@ -102,7 +103,7 @@ list(APPEND sources
 | 
			
		|||
# network stack. In order to mix-and-match various compilers, architectures,
 | 
			
		||||
# operating systems, etc input from the build system is required.
 | 
			
		||||
foreach(feature atomics cdtors environ heap ifaddrs random rusage
 | 
			
		||||
                sockets string sync threads time md5 process)
 | 
			
		||||
                sockets string sync threads time md5 process dynlib)
 | 
			
		||||
  if(EXISTS "${include_path}/dds/ddsrt/${feature}.h")
 | 
			
		||||
    list(APPEND headers "${include_path}/dds/ddsrt/${feature}.h")
 | 
			
		||||
    file(GLOB
 | 
			
		||||
| 
						 | 
				
			
			@ -176,6 +177,7 @@ target_sources(ddsrt INTERFACE ${sources})
 | 
			
		|||
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
 | 
			
		||||
find_package(Threads REQUIRED)
 | 
			
		||||
target_link_libraries(ddsrt INTERFACE Threads::Threads)
 | 
			
		||||
target_link_libraries(ddsrt INTERFACE ${CMAKE_DL_LIBS})
 | 
			
		||||
 | 
			
		||||
if(WIN32)
 | 
			
		||||
  target_link_libraries(ddsrt INTERFACE wsock32 ws2_32 iphlpapi bcrypt)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										143
									
								
								src/ddsrt/include/dds/ddsrt/dynlib.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								src/ddsrt/include/dds/ddsrt/dynlib.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,143 @@
 | 
			
		|||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
 | 
			
		||||
 *
 | 
			
		||||
 * This program and the accompanying materials are made available under the
 | 
			
		||||
 * terms of the Eclipse Public License v. 2.0 which is available at
 | 
			
		||||
 * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
 | 
			
		||||
 * v. 1.0 which is available at
 | 
			
		||||
 * http://www.eclipse.org/org/documents/edl-v10.php.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 | 
			
		||||
 */
 | 
			
		||||
#ifndef DDSRT_LIBRARY_H
 | 
			
		||||
#define DDSRT_LIBRARY_H
 | 
			
		||||
 | 
			
		||||
#include "dds/export.h"
 | 
			
		||||
#include "dds/ddsrt/types.h"
 | 
			
		||||
#include "dds/ddsrt/retcode.h"
 | 
			
		||||
#include "dds/ddsrt/attributes.h"
 | 
			
		||||
 | 
			
		||||
#if defined (__cplusplus)
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//typedef void *ddsrt_dynlib_t;
 | 
			
		||||
typedef struct ddsrt_dynlib *ddsrt_dynlib_t;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Load a dynamic shared library.
 | 
			
		||||
 *
 | 
			
		||||
 * The function ddsrt_dlopen() loads the dynamic shared object (shared library)
 | 
			
		||||
 * file, identified by 'name', sets the handle parameter for the loaded library and
 | 
			
		||||
 * returns the result with dds return code.
 | 
			
		||||
 *
 | 
			
		||||
 * If the 'translate' boolean is true, this function will first try to open the
 | 
			
		||||
 * library with a translated 'name'. Translated in this context means that if
 | 
			
		||||
 * "mylibrary" is provided, it will be translated into libmylibrary.so,
 | 
			
		||||
 * libmylibrary.dylib or mylibrary.dll depending on the platform.
 | 
			
		||||
 * This translation only happens when the given name does not contain
 | 
			
		||||
 * a directory.
 | 
			
		||||
 * If the function isn't able to load the library with the translated name, it
 | 
			
		||||
 * will still try the given name.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   name        Library file name.
 | 
			
		||||
 * @param[in]   translate   Automatic name translation on/off.
 | 
			
		||||
 * @param[out]  handle      Library handle that will be assigned after successfull operation. It is assigned to NULL if loading fails.
 | 
			
		||||
 *
 | 
			
		||||
 * @returns A dds_retcode_t indicating success or failure.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval DDS_RETCODE_OK
 | 
			
		||||
 *             Library handle was successfully loaded.
 | 
			
		||||
 * @retval DDS_RETCODE_BAD_PARAM
 | 
			
		||||
 *             There is an invalid input in the parameter list
 | 
			
		||||
 * @retval DDS_RETCODE_ERROR
 | 
			
		||||
 *             Loading failed.
 | 
			
		||||
 *             Use ddsrt_dlerror() to diagnose the failure.
 | 
			
		||||
 */
 | 
			
		||||
DDS_EXPORT dds_retcode_t
 | 
			
		||||
ddsrt_dlopen(
 | 
			
		||||
    const char *name,
 | 
			
		||||
    bool translate,
 | 
			
		||||
    ddsrt_dynlib_t *handle) ddsrt_nonnull_all;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Close the library.
 | 
			
		||||
 *
 | 
			
		||||
 * The function ddsrt_dlclose() informs the system that the
 | 
			
		||||
 * library, identified by 'handle', is no longer needed.
 | 
			
		||||
 * will get the memory address of a symbol,
 | 
			
		||||
 * identified by 'symbol', from a loaded library 'handle'.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   handle      Library handle.
 | 
			
		||||
 *
 | 
			
		||||
 * @returns A dds_retcode_t indicating success or failure.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval DDS_RETCODE_OK
 | 
			
		||||
 *             Library handle was successfully closed.
 | 
			
		||||
 * @retval DDS_RETCODE_ERROR
 | 
			
		||||
 *             Library closing failed.
 | 
			
		||||
 *             Use ddsrt_dlerror() to diagnose the failure.
 | 
			
		||||
 */
 | 
			
		||||
DDS_EXPORT dds_retcode_t
 | 
			
		||||
ddsrt_dlclose(
 | 
			
		||||
    ddsrt_dynlib_t handle);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Get the memory address of a symbol.
 | 
			
		||||
 *
 | 
			
		||||
 * The function ddsrt_dlsym() will get the memory address of a symbol,
 | 
			
		||||
 * identified by 'symbol', from a loaded library 'handle'.
 | 
			
		||||
 *
 | 
			
		||||
 * @param[in]   handle      Library handle.
 | 
			
		||||
 * @param[in]   symbol      Symbol name.
 | 
			
		||||
 * @param[out]  address     The memory address of the loaded symbol (void*).
 | 
			
		||||
 *
 | 
			
		||||
 * @returns  A dds_retcode_t indicating success or failure.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval DDS_RETCODE_OK
 | 
			
		||||
 *             Symbol was found in the loaded library.
 | 
			
		||||
 *             Address parameter is ready to use.
 | 
			
		||||
 * @retval DDS_RETCODE_ERROR
 | 
			
		||||
 *             Symbol was not found.
 | 
			
		||||
 *             Use ddsrt_dlerror() to diagnose the failure.
 | 
			
		||||
 */
 | 
			
		||||
DDS_EXPORT dds_retcode_t
 | 
			
		||||
ddsrt_dlsym(
 | 
			
		||||
    ddsrt_dynlib_t handle,
 | 
			
		||||
    const char *symbol,
 | 
			
		||||
    void **address);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Get the most recent library related error.
 | 
			
		||||
 *
 | 
			
		||||
 * The function ddsrt_dlerror() will return the most recent error of the operating system
 | 
			
		||||
 * in human readable form.
 | 
			
		||||
 *
 | 
			
		||||
 * If no error was found, it's either due to the fact that there
 | 
			
		||||
 * actually was no error since init or last ddsrt_dlerror() call,
 | 
			
		||||
 * or due to an unknown unrelated error.
 | 
			
		||||
 *
 | 
			
		||||
 * As error reporting function can be used for different purposes, dssrt_dlerror
 | 
			
		||||
 * function should be called immediately after calling ddsrt_dlopen or ddsrt_dlsym
 | 
			
		||||
 * function.
 | 
			
		||||
 *
 | 
			
		||||
 * @returns A dds_retcode_t indicating success or failure.
 | 
			
		||||
 *
 | 
			
		||||
 * @retval DDS_RETCODE_OK
 | 
			
		||||
 *             Most recent library related error returned.
 | 
			
		||||
 * @retval DDS_RETCODE_NOT_FOUND
 | 
			
		||||
 *             No library related error found.
 | 
			
		||||
 */
 | 
			
		||||
DDS_EXPORT dds_retcode_t
 | 
			
		||||
ddsrt_dlerror(
 | 
			
		||||
    char *buf,
 | 
			
		||||
    size_t buflen);
 | 
			
		||||
 | 
			
		||||
#if defined (__cplusplus)
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* DDSRT_LIBRARY_H */
 | 
			
		||||
							
								
								
									
										95
									
								
								src/ddsrt/src/dynlib/posix/dynlib.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								src/ddsrt/src/dynlib/posix/dynlib.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,95 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
 | 
			
		||||
 *
 | 
			
		||||
 * This program and the accompanying materials are made available under the
 | 
			
		||||
 * terms of the Eclipse Public License v. 2.0 which is available at
 | 
			
		||||
 * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
 | 
			
		||||
 * v. 1.0 which is available at
 | 
			
		||||
 * http://www.eclipse.org/org/documents/edl-v10.php.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 | 
			
		||||
 */
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <dlfcn.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <dds/ddsrt/dynlib.h>
 | 
			
		||||
#include "dds/ddsrt/heap.h"
 | 
			
		||||
#include "dds/ddsrt/io.h"
 | 
			
		||||
 | 
			
		||||
dds_retcode_t ddsrt_dlopen(const char *name, bool translate,
 | 
			
		||||
		ddsrt_dynlib_t *handle) {
 | 
			
		||||
	dds_retcode_t retcode = DDS_RETCODE_OK;
 | 
			
		||||
 | 
			
		||||
	assert( handle );
 | 
			
		||||
	*handle = NULL;
 | 
			
		||||
 | 
			
		||||
	if ((translate) && (strrchr(name, '/') == NULL )) {
 | 
			
		||||
		/* Add lib and suffix to the name and try to open. */
 | 
			
		||||
#if __APPLE__
 | 
			
		||||
		static const char suffix[] = ".dylib";
 | 
			
		||||
#else
 | 
			
		||||
		static const char suffix[] = ".so";
 | 
			
		||||
#endif
 | 
			
		||||
		char* libName;
 | 
			
		||||
		ddsrt_asprintf( &libName, "lib%s%s", name, suffix);
 | 
			
		||||
		*handle = dlopen(libName, RTLD_GLOBAL | RTLD_NOW);
 | 
			
		||||
		ddsrt_free(libName);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (*handle == NULL ) {
 | 
			
		||||
		/* name contains a path,
 | 
			
		||||
		 * (auto)translate is disabled or
 | 
			
		||||
		 * dlopen on translated name failed. */
 | 
			
		||||
		*handle = dlopen(name, RTLD_GLOBAL | RTLD_NOW);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (*handle != NULL) {
 | 
			
		||||
		retcode = DDS_RETCODE_OK;
 | 
			
		||||
	} else {
 | 
			
		||||
		retcode = DDS_RETCODE_ERROR;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return retcode;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dds_retcode_t ddsrt_dlclose(ddsrt_dynlib_t handle) {
 | 
			
		||||
 | 
			
		||||
	assert ( handle );
 | 
			
		||||
	return (dlclose(handle) == 0) ? DDS_RETCODE_OK : DDS_RETCODE_ERROR;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dds_retcode_t ddsrt_dlsym(ddsrt_dynlib_t handle, const char *symbol,
 | 
			
		||||
		void **address) {
 | 
			
		||||
	dds_retcode_t retcode = DDS_RETCODE_OK;
 | 
			
		||||
 | 
			
		||||
	assert( handle );
 | 
			
		||||
	assert( address );
 | 
			
		||||
	assert( symbol );
 | 
			
		||||
 | 
			
		||||
	*address = dlsym(handle, symbol);
 | 
			
		||||
	if (*address == NULL) {
 | 
			
		||||
		retcode = DDS_RETCODE_ERROR;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return retcode;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dds_retcode_t ddsrt_dlerror(char *buf, size_t buflen) {
 | 
			
		||||
 | 
			
		||||
	const char *err;
 | 
			
		||||
	dds_retcode_t retcode = DDS_RETCODE_OK;
 | 
			
		||||
 | 
			
		||||
	assert (buf );
 | 
			
		||||
 | 
			
		||||
	err = dlerror();
 | 
			
		||||
	if (err == NULL) {
 | 
			
		||||
		retcode = DDS_RETCODE_NOT_FOUND;
 | 
			
		||||
	} else {
 | 
			
		||||
		snprintf(buf, buflen, "%s", err);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return retcode;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										95
									
								
								src/ddsrt/src/dynlib/windows/dynlib.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								src/ddsrt/src/dynlib/windows/dynlib.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,95 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
 | 
			
		||||
 *
 | 
			
		||||
 * This program and the accompanying materials are made available under the
 | 
			
		||||
 * terms of the Eclipse Public License v. 2.0 which is available at
 | 
			
		||||
 * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
 | 
			
		||||
 * v. 1.0 which is available at
 | 
			
		||||
 * http://www.eclipse.org/org/documents/edl-v10.php.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 | 
			
		||||
 */
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <dds/ddsrt/dynlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "dds/ddsrt/heap.h"
 | 
			
		||||
#include "dds/ddsrt/types.h"
 | 
			
		||||
#include "dds/ddsrt/string.h"
 | 
			
		||||
 | 
			
		||||
dds_retcode_t ddsrt_dlopen(const char *name, bool translate,
 | 
			
		||||
		ddsrt_dynlib_t *handle) {
 | 
			
		||||
	dds_retcode_t retcode = DDS_RETCODE_OK;
 | 
			
		||||
 | 
			
		||||
	assert( handle );
 | 
			
		||||
	*handle = NULL;
 | 
			
		||||
 | 
			
		||||
	if ((translate) && (strrchr(name, '/') == NULL )
 | 
			
		||||
			&& (strrchr(name, '\\') == NULL )) {
 | 
			
		||||
		/* Add suffix to the name and try to open. */
 | 
			
		||||
		static const char suffix[] = ".dll";
 | 
			
		||||
		size_t len = strlen(name) + sizeof(suffix);
 | 
			
		||||
		char* libName = ddsrt_malloc(len);
 | 
			
		||||
		sprintf_s(libName, len, "%s%s", name, suffix);
 | 
			
		||||
		*handle = LoadLibrary(libName);
 | 
			
		||||
		ddsrt_free(libName);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (*handle == NULL) {
 | 
			
		||||
		/* Name contains a path,
 | 
			
		||||
		 * (auto)translate is disabled or
 | 
			
		||||
		 * LoadLibrary on translated name failed. */
 | 
			
		||||
		*handle = LoadLibrary(name);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (*handle != NULL) {
 | 
			
		||||
		retcode = DDS_RETCODE_OK;
 | 
			
		||||
	} else {
 | 
			
		||||
		retcode = DDS_RETCODE_ERROR;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return retcode;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dds_retcode_t ddsrt_dlclose(ddsrt_dynlib_t handle) {
 | 
			
		||||
 | 
			
		||||
	assert ( handle );
 | 
			
		||||
	return (FreeLibrary(handle) == 0) ? DDS_RETCODE_ERROR : DDS_RETCODE_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dds_retcode_t ddsrt_dlsym(ddsrt_dynlib_t handle, const char *symbol,
 | 
			
		||||
		void **address) {
 | 
			
		||||
	dds_retcode_t retcode = DDS_RETCODE_OK;
 | 
			
		||||
 | 
			
		||||
	assert( handle );
 | 
			
		||||
	assert( address );
 | 
			
		||||
	assert( symbol );
 | 
			
		||||
 | 
			
		||||
	*address = GetProcAddress(handle, symbol);
 | 
			
		||||
	if ( *address == NULL ) {
 | 
			
		||||
		retcode = DDS_RETCODE_ERROR;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return retcode;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dds_retcode_t ddsrt_dlerror(char *buf, size_t buflen) {
 | 
			
		||||
 | 
			
		||||
	/* Hopefully (and likely), the last error is
 | 
			
		||||
	 * related to a Library action attempt. */
 | 
			
		||||
	DWORD err;
 | 
			
		||||
	assert ( buf );
 | 
			
		||||
 | 
			
		||||
	dds_retcode_t retcode = DDS_RETCODE_OK;
 | 
			
		||||
 | 
			
		||||
	err = GetLastError();
 | 
			
		||||
	if ( err == 0 ) {
 | 
			
		||||
		retcode = DDS_RETCODE_NOT_FOUND;
 | 
			
		||||
	} else {
 | 
			
		||||
		retcode = ddsrt_strerror_r(err, buf, buflen);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return retcode;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -10,9 +10,11 @@
 | 
			
		|||
# SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 | 
			
		||||
#
 | 
			
		||||
include(CUnit)
 | 
			
		||||
include(GenerateExportHeader)
 | 
			
		||||
 | 
			
		||||
set(sources
 | 
			
		||||
    "atomics.c"
 | 
			
		||||
    "dynlib.c"
 | 
			
		||||
    "environ.c"
 | 
			
		||||
    "heap.c"
 | 
			
		||||
    "ifaddrs.c"
 | 
			
		||||
| 
						 | 
				
			
			@ -66,3 +68,47 @@ set(process_app_name "${CMAKE_CURRENT_BINARY_DIR}/process_app${CMAKE_EXECUTABLE_
 | 
			
		|||
configure_file(
 | 
			
		||||
        "process_test.h.in" "${CMAKE_CURRENT_BINARY_DIR}/include/process_test.h" @ONLY)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Create a separate shared library that will be used to
 | 
			
		||||
# test dynamic library loading.
 | 
			
		||||
set(test_lib_name "dltestlib")
 | 
			
		||||
add_library(${test_lib_name} SHARED dllib.c)
 | 
			
		||||
# Force the lib to be at the same location, no matter what platform or build type.
 | 
			
		||||
set_target_properties(
 | 
			
		||||
        ${test_lib_name}
 | 
			
		||||
        PROPERTIES
 | 
			
		||||
        RUNTIME_OUTPUT_DIRECTORY                ${CMAKE_CURRENT_BINARY_DIR}
 | 
			
		||||
        RUNTIME_OUTPUT_DIRECTORY_DEBUG          ${CMAKE_CURRENT_BINARY_DIR}
 | 
			
		||||
        RUNTIME_OUTPUT_DIRECTORY_RELEASE        ${CMAKE_CURRENT_BINARY_DIR}
 | 
			
		||||
        RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_CURRENT_BINARY_DIR}
 | 
			
		||||
        RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL     ${CMAKE_CURRENT_BINARY_DIR}
 | 
			
		||||
        LIBRARY_OUTPUT_DIRECTORY                ${CMAKE_CURRENT_BINARY_DIR}
 | 
			
		||||
        LIBRARY_OUTPUT_DIRECTORY_DEBUG          ${CMAKE_CURRENT_BINARY_DIR}
 | 
			
		||||
        LIBRARY_OUTPUT_DIRECTORY_RELEASE        ${CMAKE_CURRENT_BINARY_DIR}
 | 
			
		||||
        LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_CURRENT_BINARY_DIR}
 | 
			
		||||
        LIBRARY_OUTPUT_DIRECTORY_MINSIZEREL     ${CMAKE_CURRENT_BINARY_DIR} )
 | 
			
		||||
# Use proper export for this test lib.
 | 
			
		||||
generate_export_header(${test_lib_name} BASE_NAME LIB_TEST)
 | 
			
		||||
target_include_directories(${test_lib_name} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
 | 
			
		||||
# Let the cunit application know the location and name of the library.
 | 
			
		||||
file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}" test_lib_native_dir)
 | 
			
		||||
file(TO_NATIVE_PATH "/" test_lib_sep)
 | 
			
		||||
string(REPLACE "\\" "\\\\" test_lib_dir ${test_lib_native_dir})
 | 
			
		||||
string(REPLACE "\\" "\\\\" test_lib_sep ${test_lib_sep})
 | 
			
		||||
configure_file("dl_test.h.in" "${CMAKE_CURRENT_BINARY_DIR}/include/dl_test.h" @ONLY)
 | 
			
		||||
# Let ctest set the proper library path when executing library tests.
 | 
			
		||||
unset(test_lib_tests)
 | 
			
		||||
process_cunit_source_file("dynlib.c" test_lib_header test_lib_suites test_lib_tests)
 | 
			
		||||
foreach(libtest ${test_lib_tests})
 | 
			
		||||
  string(REPLACE ":" ";" libtest ${libtest})
 | 
			
		||||
  list(GET libtest 0 suite)
 | 
			
		||||
  list(GET libtest 1 test)
 | 
			
		||||
  set(libtestname "CUnit_${suite}_${test}")
 | 
			
		||||
  if("${CMAKE_HOST_SYSTEM}" MATCHES ".*Windows.*")
 | 
			
		||||
    set_property(TEST ${libtestname} APPEND PROPERTY ENVIRONMENT "${test_lib_native_dir}")
 | 
			
		||||
  else()
 | 
			
		||||
    set_property(TEST ${libtestname} APPEND PROPERTY ENVIRONMENT "LD_LIBRARY_PATH=${test_lib_native_dir};$ENV{LD_LIBRARY_PATH}")
 | 
			
		||||
  endif()
 | 
			
		||||
endforeach()
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										22
									
								
								src/ddsrt/tests/dl_test.h.in
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/ddsrt/tests/dl_test.h.in
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,22 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
 | 
			
		||||
 *
 | 
			
		||||
 * This program and the accompanying materials are made available under the
 | 
			
		||||
 * terms of the Eclipse Public License v. 2.0 which is available at
 | 
			
		||||
 * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
 | 
			
		||||
 * v. 1.0 which is available at
 | 
			
		||||
 * http://www.eclipse.org/org/documents/edl-v10.php.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 | 
			
		||||
 */
 | 
			
		||||
#ifndef DDSRT_TEST_DL_TEST_H
 | 
			
		||||
#define DDSRT_TEST_DL_TEST_H
 | 
			
		||||
 | 
			
		||||
/* Get the library name information from cmake. */
 | 
			
		||||
#define TEST_LIB_NAME   "@test_lib_name@"
 | 
			
		||||
#define TEST_LIB_DIR    "@test_lib_dir@"
 | 
			
		||||
#define TEST_LIB_SEP    "@test_lib_sep@"
 | 
			
		||||
#define TEST_LIB_SUFFIX "@CMAKE_SHARED_LIBRARY_SUFFIX@"
 | 
			
		||||
#define TEST_LIB_PREFIX "@CMAKE_SHARED_LIBRARY_PREFIX@"
 | 
			
		||||
 | 
			
		||||
#endif /* DDSRT_TEST_DL_TEST_H */
 | 
			
		||||
							
								
								
									
										25
									
								
								src/ddsrt/tests/dllib.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/ddsrt/tests/dllib.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,25 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright(c) 2019 ADLINK Technology Limited and others
 | 
			
		||||
 *
 | 
			
		||||
 * This program and the accompanying materials are made available under the
 | 
			
		||||
 * terms of the Eclipse Public License v. 2.0 which is available at
 | 
			
		||||
 * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
 | 
			
		||||
 * v. 1.0 which is available at
 | 
			
		||||
 * http://www.eclipse.org/org/documents/edl-v10.php.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 | 
			
		||||
 */
 | 
			
		||||
#include "lib_test_export.h"
 | 
			
		||||
 | 
			
		||||
static int g_val = -1;
 | 
			
		||||
 | 
			
		||||
LIB_TEST_EXPORT void set_int(int val)
 | 
			
		||||
{
 | 
			
		||||
  g_val = val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LIB_TEST_EXPORT int get_int(void)
 | 
			
		||||
{
 | 
			
		||||
  return g_val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										197
									
								
								src/ddsrt/tests/dynlib.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										197
									
								
								src/ddsrt/tests/dynlib.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,197 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright(c) 2019 ADLINK Technology Limited and others
 | 
			
		||||
 *
 | 
			
		||||
 * This program and the accompanying materials are made available under the
 | 
			
		||||
 * terms of the Eclipse Public License v. 2.0 which is available at
 | 
			
		||||
 * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
 | 
			
		||||
 * v. 1.0 which is available at
 | 
			
		||||
 * http://www.eclipse.org/org/documents/edl-v10.php.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 | 
			
		||||
 */
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <dds/ddsrt/dynlib.h>
 | 
			
		||||
#include "CUnit/Test.h"
 | 
			
		||||
#include "dds/ddsrt/heap.h"
 | 
			
		||||
#include "dds/ddsrt/string.h"
 | 
			
		||||
#include "dds/ddsrt/environ.h"
 | 
			
		||||
#include "dl_test.h"
 | 
			
		||||
 | 
			
		||||
#define TEST_LIB_FILE     ""TEST_LIB_PREFIX""TEST_LIB_NAME""TEST_LIB_SUFFIX""
 | 
			
		||||
#define TEST_LIB_ABSOLUTE ""TEST_LIB_DIR""TEST_LIB_SEP""TEST_LIB_FILE""
 | 
			
		||||
 | 
			
		||||
#define TEST_ABORT_IF_NULL(var, msg) \
 | 
			
		||||
do { \
 | 
			
		||||
  if (var == NULL) { \
 | 
			
		||||
    char buffer[256]; \
 | 
			
		||||
    r = ddsrt_dlerror(buffer, sizeof(buffer)); \
 | 
			
		||||
    CU_ASSERT_EQUAL_FATAL(r, DDS_RETCODE_OK); \
 | 
			
		||||
    printf("\n%s", buffer); \
 | 
			
		||||
    CU_FAIL_FATAL(msg); \
 | 
			
		||||
  } \
 | 
			
		||||
} while(0)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Load a library.
 | 
			
		||||
 */
 | 
			
		||||
CU_Test(ddsrt_library, dlopen_path)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t r;
 | 
			
		||||
  ddsrt_dynlib_t  l;
 | 
			
		||||
 | 
			
		||||
  printf("Absolute lib: %s\n", TEST_LIB_ABSOLUTE);
 | 
			
		||||
  r = ddsrt_dlopen(TEST_LIB_ABSOLUTE, false, &l);
 | 
			
		||||
  CU_ASSERT_EQUAL(r, DDS_RETCODE_OK);
 | 
			
		||||
  CU_ASSERT_PTR_NOT_NULL(l);
 | 
			
		||||
  TEST_ABORT_IF_NULL(l, "ddsrt_dlopen() failed. Is the proper library path set?");
 | 
			
		||||
 | 
			
		||||
  r = ddsrt_dlclose(l);
 | 
			
		||||
  CU_ASSERT_EQUAL(r, DDS_RETCODE_OK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CU_Test(ddsrt_library, dlopen_file)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t r;
 | 
			
		||||
  ddsrt_dynlib_t l;
 | 
			
		||||
 | 
			
		||||
  r = ddsrt_dlopen(TEST_LIB_FILE, false, &l);
 | 
			
		||||
  CU_ASSERT_EQUAL(r, DDS_RETCODE_OK);
 | 
			
		||||
  CU_ASSERT_PTR_NOT_NULL(l);
 | 
			
		||||
  TEST_ABORT_IF_NULL(l, "ddsrt_dlopen() failed. Is the proper library path set?");
 | 
			
		||||
 | 
			
		||||
  r = ddsrt_dlclose(l);
 | 
			
		||||
  CU_ASSERT_EQUAL(r, DDS_RETCODE_OK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CU_Test(ddsrt_library, dlopen_name)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t r;
 | 
			
		||||
  ddsrt_dynlib_t l;
 | 
			
		||||
 | 
			
		||||
  r = ddsrt_dlopen(TEST_LIB_NAME, true, &l);
 | 
			
		||||
  CU_ASSERT_EQUAL(r, DDS_RETCODE_OK);
 | 
			
		||||
  CU_ASSERT_PTR_NOT_NULL(l);
 | 
			
		||||
  TEST_ABORT_IF_NULL(l, "ddsrt_dlopen() failed. Is the proper library path set?");
 | 
			
		||||
 | 
			
		||||
  r = ddsrt_dlclose(l);
 | 
			
		||||
  CU_ASSERT_EQUAL(r, DDS_RETCODE_OK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CU_Test(ddsrt_library, dlopen_unknown)
 | 
			
		||||
{
 | 
			
		||||
  char buffer[256];
 | 
			
		||||
  dds_retcode_t r;
 | 
			
		||||
  ddsrt_dynlib_t l;
 | 
			
		||||
 | 
			
		||||
  r = ddsrt_dlopen("UnknownLib", false, &l);
 | 
			
		||||
 | 
			
		||||
  CU_ASSERT_PTR_NULL_FATAL(l);
 | 
			
		||||
 | 
			
		||||
  r = ddsrt_dlerror(buffer, sizeof(buffer));
 | 
			
		||||
  CU_ASSERT_EQUAL_FATAL(r, DDS_RETCODE_OK);
 | 
			
		||||
  printf("\n%s", buffer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CU_Test(ddsrt_library, dlsym)
 | 
			
		||||
{
 | 
			
		||||
  dds_retcode_t r;
 | 
			
		||||
  ddsrt_dynlib_t l;
 | 
			
		||||
  void* f;
 | 
			
		||||
 | 
			
		||||
  r = ddsrt_dlopen(TEST_LIB_NAME, true, &l);
 | 
			
		||||
  CU_ASSERT_PTR_NOT_NULL(l);
 | 
			
		||||
  CU_ASSERT_EQUAL(r, DDS_RETCODE_OK);
 | 
			
		||||
  TEST_ABORT_IF_NULL(l, "ddsrt_dlopen() failed. Is the proper library path set?");
 | 
			
		||||
 | 
			
		||||
  r = ddsrt_dlsym(l, "get_int", &f);
 | 
			
		||||
  CU_ASSERT_EQUAL(r, DDS_RETCODE_OK);
 | 
			
		||||
  CU_ASSERT_PTR_NOT_NULL(f);
 | 
			
		||||
  TEST_ABORT_IF_NULL(f, "ddsrt_dlsym(l, \"get_int\") failed.");
 | 
			
		||||
 | 
			
		||||
  r = ddsrt_dlclose(l);
 | 
			
		||||
  CU_ASSERT_EQUAL(r, DDS_RETCODE_OK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CU_Test(ddsrt_library, dlsym_unknown)
 | 
			
		||||
{
 | 
			
		||||
  char buffer[256];
 | 
			
		||||
  dds_retcode_t r;
 | 
			
		||||
  ddsrt_dynlib_t l;
 | 
			
		||||
  void* f;
 | 
			
		||||
 | 
			
		||||
  r = ddsrt_dlopen(TEST_LIB_NAME, true, &l);
 | 
			
		||||
  CU_ASSERT_PTR_NOT_NULL(l);
 | 
			
		||||
  TEST_ABORT_IF_NULL(l,"ddsrt_dlopen() failed. Is the proper library path set?");
 | 
			
		||||
 | 
			
		||||
  r = ddsrt_dlsym(l, "UnknownSym", &f);
 | 
			
		||||
  CU_ASSERT_EQUAL(r, DDS_RETCODE_ERROR);
 | 
			
		||||
  CU_ASSERT_PTR_NULL_FATAL(f);
 | 
			
		||||
 | 
			
		||||
  r = ddsrt_dlerror(buffer, sizeof(buffer));
 | 
			
		||||
  CU_ASSERT_EQUAL_FATAL(r, DDS_RETCODE_OK);
 | 
			
		||||
  printf("\n%s", buffer);
 | 
			
		||||
 | 
			
		||||
  r = ddsrt_dlclose(l);
 | 
			
		||||
  CU_ASSERT_EQUAL(r, DDS_RETCODE_OK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef void (*func_set_int)(int val);
 | 
			
		||||
typedef int  (*func_get_int)(void);
 | 
			
		||||
CU_Test(ddsrt_library, call)
 | 
			
		||||
{
 | 
			
		||||
  int get_int = 0;
 | 
			
		||||
  int set_int = 1234;
 | 
			
		||||
  func_get_int f_get;
 | 
			
		||||
  func_set_int f_set;
 | 
			
		||||
  dds_retcode_t r;
 | 
			
		||||
  ddsrt_dynlib_t l;
 | 
			
		||||
 | 
			
		||||
  r = ddsrt_dlopen(TEST_LIB_NAME, true, &l);
 | 
			
		||||
  CU_ASSERT_PTR_NOT_NULL(l);
 | 
			
		||||
  TEST_ABORT_IF_NULL(l, "ddsrt_dlopen() failed. Is the proper library path set?");
 | 
			
		||||
 | 
			
		||||
  r = ddsrt_dlsym(l, "get_int", (void **)&f_get);
 | 
			
		||||
  CU_ASSERT_PTR_NOT_NULL(f_get);
 | 
			
		||||
  TEST_ABORT_IF_NULL(f_get, "ddsrt_dlsym(l, \"get_int\") failed.");
 | 
			
		||||
 | 
			
		||||
  r = ddsrt_dlsym(l, "set_int", (void **)&f_set);
 | 
			
		||||
  CU_ASSERT_PTR_NOT_NULL(f_set);
 | 
			
		||||
  TEST_ABORT_IF_NULL(f_set, "ddsrt_dlsym(l, \"set_int\") failed.");
 | 
			
		||||
 | 
			
		||||
  f_set(set_int);
 | 
			
		||||
  get_int = f_get();
 | 
			
		||||
  CU_ASSERT_EQUAL(set_int, get_int);
 | 
			
		||||
 | 
			
		||||
  r = ddsrt_dlclose(l);
 | 
			
		||||
  CU_ASSERT_EQUAL(r, DDS_RETCODE_OK);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CU_Test(ddsrt_library, dlclose_error)
 | 
			
		||||
{
 | 
			
		||||
    dds_retcode_t r;
 | 
			
		||||
    ddsrt_dynlib_t l;
 | 
			
		||||
 | 
			
		||||
    r = ddsrt_dlopen(TEST_LIB_NAME, true, &l);
 | 
			
		||||
    CU_ASSERT_PTR_NOT_NULL(l);
 | 
			
		||||
    TEST_ABORT_IF_NULL(l, "ddsrt_dlopen() failed. Is the proper library path set?");
 | 
			
		||||
 | 
			
		||||
    r = ddsrt_dlclose(l);
 | 
			
		||||
    CU_ASSERT_EQUAL(r, DDS_RETCODE_OK);
 | 
			
		||||
 | 
			
		||||
    r = ddsrt_dlclose( l ); /*already closed handle */
 | 
			
		||||
    CU_ASSERT_EQUAL(r, DDS_RETCODE_ERROR);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CU_Test(ddsrt_library, dlerror_notfound)
 | 
			
		||||
{
 | 
			
		||||
    char buffer[256];
 | 
			
		||||
    dds_retcode_t r;
 | 
			
		||||
    ddsrt_dlerror(buffer, sizeof(buffer));
 | 
			
		||||
    r = ddsrt_dlerror(buffer, sizeof(buffer));
 | 
			
		||||
    CU_ASSERT_EQUAL(r, DDS_RETCODE_NOT_FOUND);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue