runs-on: <?=DEF[DEF["os"]]?> #
env:
ENABLE_SANITIZERS: "thread"
- ENABLE_MEMASLAP: "OFF"
steps:
- uses: actions/checkout@v2
<?php steps(); ?>
runs-on: ubuntu-20.04 #
env:
ENABLE_SANITIZERS: "thread"
- ENABLE_MEMASLAP: "OFF"
steps:
- uses: actions/checkout@v2
- name: Prepare environment (for cur gnu on ubuntu-20.04)
-include(CheckCSourceRuns)
-include(CheckCXXSourceRuns)
-
# sets HAVE_ATOMICS, checks for :
# - C++11 std::atomic: HAVE_CXX_STDATOMIC
# - C11 stdatomic: HAVE_C_STDATOMIC
# - builtin __atomic: HAVE_BUILTIN_ATOMIC
# - builtin __sync: HAVE_BUILTIN_SYNC
# - atomic_add_nv: HAVE_ATOMIC_ADD_NV
-function(check_atomics)
- check_cxx_source_runs("
- #include <atomic>
- int main() {
- std::atomic<int> i(0);
- return atomic_load(&i);
- }"
- HAVE_CXX_STDATOMIC)
- check_c_source_runs("
- #include <stdatomic.h>
- int main() {
- atomic_int i;
- atomic_init(&i, 0);
- return atomic_load(&i);
- }"
- HAVE_C_STDATOMIC)
- foreach(BUILTIN_ATOMIC_PREFIX IN ITEMS _ __c11)
- check_c_source_runs("
- int main() {
- long l = -1;
- return ${BUILTIN_ATOMIC_PREFIX}_atomic_add_fetch(&l,1,__ATOMIC_RELAXED);
- }"
- HAVE_BUILTIN_ATOMIC${BUILTIN_ATOMIC_PREFIX})
- if (HAVE_BUILTIN_ATOMIC${BUILTIN_ATOMIC_PREFIX})
- set(HAVE_BUILTIN_ATOMIC 1)
- break()
- endif()
- endforeach()
- check_c_source_runs("
+
+configure_define(HAVE_ATOMICS)
+
+check_cxx_source("
+ #include <atomic>
+ int main() {
+ std::atomic<int> i(0);
+ return atomic_load(&i);
+ }"
+ HAVE_CXX_STDATOMIC)
+
+check_c_source("
+ #include <stdatomic.h>
+ int main() {
+ atomic_int i;
+ atomic_init(&i, 0);
+ return atomic_load(&i);
+ }"
+ HAVE_C_STDATOMIC)
+
+
+configure_define(HAVE_BUILTIN_ATOMIC)
+configure_define_literal(BUILTIN_ATOMIC_PREFIX)
+foreach(BUILTIN_ATOMIC_PREFIX IN ITEMS __c11 _ "")
+ check_c_source("
int main() {
long l = -1;
- return __sync_add_and_fetch(&l,1);
- }"
- HAVE_BUILTIN_SYNC)
- check_c_source_runs("
- #include <atomic.h>
- int main() {
- volatile uint_t i = 0;
- return atomic_add_int_nv(&i, 1) == 1 ? 0 : -1;
+ return ${BUILTIN_ATOMIC_PREFIX}_atomic_add_fetch(&l,1,__ATOMIC_RELAXED);
}"
- HAVE_ATOMIC_ADD_NV)
- if ( HAVE_CXX_STDATOMIC
- OR HAVE_C_STDATOMIC
- OR HAVE_BUILTIN_ATOMIC
- OR HAVE_BUILTIN_SYNC
- OR HAVE_ATOMIC_ADD_NV)
- set(HAVE_ATOMICS 1 PARENT_SCOPE)
+ HAVE_BUILTIN_ATOMIC${BUILTIN_ATOMIC_PREFIX})
+ if (HAVE_BUILTIN_ATOMIC${BUILTIN_ATOMIC_PREFIX})
+ set(HAVE_BUILTIN_ATOMIC 1)
+ break()
endif()
-endfunction()
+endforeach()
+
+check_c_source("
+ int main() {
+ long l = -1;
+ return __sync_add_and_fetch(&l,1);
+ }"
+ HAVE_BUILTIN_SYNC)
+
+check_c_source("
+ #include <atomic.h>
+ int main() {
+ volatile uint_t i = 0;
+ return atomic_add_int_nv(&i, 1) == 1 ? 0 : -1;
+ }"
+ HAVE_ATOMIC_ADD_NV)
+
+
+if ( (HAVE_CXX_STDATOMIC)
+ OR (HAVE_C_STDATOMIC)
+ OR (HAVE_BUILTIN_ATOMIC)
+ OR (HAVE_BUILTIN_SYNC)
+ OR (HAVE_ATOMIC_ADD_NV))
+ set(HAVE_ATOMICS 1 CACHE INTERNAL "HAVE_ATOMICS")
+endif()
--- /dev/null
+find_package(Backtrace)
+if(Backtrace_FOUND)
+ configure_set(HAVE_BACKTRACE 1)
+ configure_define_header(Backtrace_HEADER)
+ set(BACKTRACE BACKTRACE)
+ add_library(BACKTRACE INTERFACE IMPORTED)
+ set_target_properties(BACKTRACE PROPERTIES
+ INTERFACE_LINK_LIBRARIES "${Backtrace_LIBRARIES}"
+ INTERFACE_INCLUDE_DIRECTORIES "${Backtrace_INCLUDE_DIR}")
+endif()
-include(CheckHeader)
-include(CheckDecl)
-include(CheckCompiles)
-
# defines HAVE_BYTESWAP
# optionally defines BYTESWAP_HEADER
# optionally defines BYTESWAP_32
# sys/endian.h: defines HAVE_SYS_ENDIAN_H
# bswap32() in sys/endian.h: defines HAVE_BSWAP32
#
-function(check_byteswap)
- check_compiles(HAVE_BUILTIN_BSWAP32 "uint32_t a, b = __builtin_bswap32(a);" stdint.h)
+include(TestBigEndian)
+test_big_endian(WORDS_BIGENDIAN)
+configure_define(WORDS_BIGENDIAN)
- if(HAVE_BUILTIN_BSWAP32)
- unset(BYTESWAP_HEADER PARENT_SCOPE)
- set(BYTESWAP_32 __builtin_bswap32 PARENT_SCOPE)
- set(HAVE_BYTESWAP 1 PARENT_SCOPE)
- return()
- endif()
+configure_define(HAVE_BYTESWAP)
+configure_define_header(BYTESWAP_HEADER)
+configure_define_literal(BYTESWAP_32)
+
+check_c_source("
+ #include <stdint.h>
+ int main() {
+ uint32_t a = 1, b = __builtin_bswap32(a);
+ return b;
+ }"
+ HAVE_BUILTIN_BSWAP32
+)
+
+if(HAVE_BUILTIN_BSWAP32)
+ configure_undef(BYTESWAP_HEADER)
+ set(BYTESWAP_32 __builtin_bswap32 CACHE INTERNAL "BYTESWAP_32")
+ set(HAVE_BYTESWAP 1 CACHE INTERNAL "HAVE_BYTESWAP")
+ return()
+endif()
- check_header(byteswap.h)
- check_decl(bswap_32 byteswap.h)
+check_include(byteswap.h)
+check_symbol(bswap_32 byteswap.h)
- if(HAVE_BSWAP_32)
- if(HAVE_BYTESWAP_H)
- set(BYTESWAP_HEADER byteswap.h PARENT_SCOPE)
- endif()
- set(BYTESWAP_32 bswap_32 PARENT_SCOPE)
- set(HAVE_BYTESWAP 1 PARENT_SCOPE)
- return()
+if(HAVE_BSWAP_32)
+ if(HAVE_BYTESWAP_H)
+ set(BYTESWAP_HEADER byteswap.h CACHE INTERNAL "BYTESWAP_HEADER")
endif()
+ set(BYTESWAP_32 bswap_32 CACHE INTERNAL "BYTESWAP_32")
+ set(HAVE_BYTESWAP 1 CACHE INSTERNAL "HAVE_BYTESWAP")
+ return()
+endif()
- check_header(sys/endian.h)
- check_decl(bswap32 sys/endian.h)
+check_include(sys/endian.h)
+check_symbol(bswap32 sys/endian.h)
- if(HAVE_BSWAP32)
- if(HAVE_SYS_ENDIAN_H)
- set(BYTESWAP_HEADER sys/endian.h PARENT_SCOPE)
- endif()
- set(BYTESWAP_32 bswap32 PARENT_SCOPE)
- set(HAVE_BYTESWAP 1 PARENT_SCOPT)
- return()
+if(HAVE_BSWAP32)
+ if(HAVE_SYS_ENDIAN_H)
+ set(BYTESWAP_HEADER sys/endian.h CACHE INTERNAL "BYTESWAP_HEADER")
endif()
+ set(BYTESWAP_32 bswap32 CACHE INTERNAL "BYTESWAP_32")
+ set(HAVE_BYTESWAP 1 CACHE INTERNAL "HAVE_BYTESWAP")
+ return()
+endif()
- unset(BYTESWAP_HEADER PARENT_SCOPE)
- unset(BYTESWAP_32 PARENT_SCOPE)
- set(HAVE_BYTESWAP 0 PARENT_SCOPE)
-endfunction()
+configure_undef(BYTESWAP_HEADER)
+configure_undef(BYTESWAP_32)
+set(HAVE_BYTESWAP 0)
+++ /dev/null
-include(CheckCXXSourceCompiles)
-
-function(check_compiles RESULT_VAR TEST)
-
- unset(SOURCE)
- foreach(HEADER IN LISTS ARGN)
- string(APPEND SOURCE "#include <${HEADER}>\n")
- endforeach()
- string(APPEND SOURCE "
- int main() {
- ${TEST}
- return 0;
- }
- ")
- check_cxx_source_compiles("${SOURCE}" ${RESULT_VAR})
-endfunction()
-include(CMakePushCheckState)
-include(CheckCXXCompilerFlag)
-function(check_flag FLAG DEFAULT)
+function(set_flag FLAG DEFAULT)
unset(FLAG_CONSTANT)
string(MAKE_C_IDENTIFIER CXX${FLAG} FLAG_CONSTANT)
check_cxx_compiler_flag(${FLAG} ${FLAG_CONSTANT})
macro(check_sanitizer VAR NAME LIB)
message(STATUS "Checking for sanitizer: ${NAME} (-l${LIB})")
if(${NAME} IN_LIST ${VAR} OR ${LIB} IN_LIST ${VAR})
- safe_string(${LIB} ID)
+ make_have_identifier(${LIB} HAVE)
cmake_push_check_state(RESET)
set(CMAKE_REQUIRED_LIBRARIES ${LIB})
- check_cxx_compiler_flag(-fsanitize=${NAME} HAVE_${ID})
+ check_cxx_compiler_flag(-fsanitize=${NAME} ${HAVE})
cmake_pop_check_state()
- if(HAVE_${ID})
- add_compile_definitions(HAVE_${ID})
+ if(${HAVE})
+ add_compile_definitions(${HAVE})
add_compile_options(-fsanitize=${NAME})
link_libraries(-fsanitize=${NAME})
- check_flag(-fsanitize-recover=${NAME} IGNORE)
+ set_flag(-fsanitize-recover=${NAME} IGNORE)
message(STATUS " OK: sanitizer ${NAME}")
else()
message(STATUS " NO: not supported")
endif()
endmacro()
-function(check_debug)
- if(CMAKE_BUILD_TYPE STREQUAL "Debug")
- add_definitions(-DDEBUG=1)
- if(CMAKE_CXX_FLAGS MATCHES --coverage)
- message("-- Coverage build detected!")
- message("-- Skipping debug and sanitizer flag checks.")
- else()
- check_flag(-Og -O0)
- check_flag(-ggdb -g)
- foreach(FLAG IN ITEMS
- -fno-inline
- -fno-omit-frame-pointer
- -fno-eliminate-unused-debug-types
- -funsafe-loop-optimizations
+if(CMAKE_BUILD_TYPE STREQUAL "Debug")
+ add_definitions(-DDEBUG=1)
+ if(CMAKE_CXX_FLAGS MATCHES --coverage)
+ message("-- Coverage build detected!")
+ message("-- Skipping debug and sanitizer flag checks.")
+ else()
+ set_flag(-Og -O0)
+ set_flag(-ggdb -g)
+ foreach(FLAG IN ITEMS
+ -fno-inline
+ -fno-omit-frame-pointer
+ -fno-eliminate-unused-debug-types
+ -funsafe-loop-optimizations
- -Wall
- -Wextra
+ -Wall
+ -Wextra
- -Wdouble-promotion
- -Wduplicated-cond
- -Wduplicated-branches
- -Wformat=2
- -Wlogical-op
- -Wnull-dereference
- -Wrestrict
- -Wshadow
- -Wunknown-pragmas
- -Wunsafe-loop-optimizations
- )
- check_flag(${FLAG} IGNORE)
- endforeach()
+ -Wdouble-promotion
+ -Wduplicated-cond
+ -Wduplicated-branches
+ -Wformat=2
+ -Wlogical-op
+ -Wnull-dereference
+ -Wrestrict
+ -Wshadow
+ -Wunknown-pragmas
+ -Wunsafe-loop-optimizations
+ )
+ set_flag(${FLAG} IGNORE)
+ endforeach()
- if(ENABLE_SANITIZERS)
- check_sanitizer(ENABLE_SANITIZERS address asan)
- check_sanitizer(ENABLE_SANITIZERS undefined ubsan)
- check_sanitizer(ENABLE_SANITIZERS thread tsan)
- check_sanitizer(ENABLE_SANITIZERS leak lsan)
- endif()
+ if(ENABLE_SANITIZERS)
+ check_sanitizer(ENABLE_SANITIZERS address asan)
+ check_sanitizer(ENABLE_SANITIZERS undefined ubsan)
+ check_sanitizer(ENABLE_SANITIZERS thread tsan)
+ check_sanitizer(ENABLE_SANITIZERS leak lsan)
endif()
- else()
- add_definitions(-DDEBUG=0)
endif()
-endfunction()
+else()
+ add_definitions(-DDEBUG=0)
+endif()
+++ /dev/null
-include(CheckCXXSymbolExists)
-
-# check for symbol and set HAVE_SYMBOL
-function(check_decl DECL HEADER)
- safe_string(${DECL} DECL_CONST)
- check_cxx_symbol_exists(${DECL} ${HEADER} HAVE_${DECL_CONST})
-endfunction(check_decl)
find_package(PkgConfig)
-include(SafeString)
-include(CheckHeader)
+function(check_dependency NAME LIB)
+ make_have_identifier(${NAME} HAVE)
+ configure_define(${HAVE})
-function(check_dependency NAME LIB HEADER)
if(PKG_CONFIG_FOUND)
pkg_check_modules(${NAME} lib${LIB}${ARGN} IMPORTED_TARGET)
if(NOT ${NAME}_FOUND)
pkg_check_modules(${NAME} ${LIB}${ARGN} IMPORTED_TARGET)
endif()
if(${NAME}_FOUND)
- set(${NAME} PkgConfig::${NAME} PARENT_SCOPE)
+ set(${NAME} PkgConfig::${NAME} CACHE INTERNAL "${NAME} import target")
+ set(${HAVE} 1 CACHE INTERNAL "${HAVE}")
+ return()
endif()
endif()
- if(NOT ${NAME}_FOUND)
- set(FOUND 1)
- message(STATUS "Checking for library '${LIB}' with header '${HEADER}' ...")
- find_library(LIB${LIB} NAMES ${LIB})
- if(NOT LIB${LIB})
- set(FOUND 0)
- endif()
- if(HEADER)
- safe_string(${HEADER} HEADER_CONST)
- check_header(${HEADER})
- if(NOT HAVE_${HEADER_CONST})
- set(FOUND 0)
- else()
- find_path(${HEADER_CONST}_ROOT ${HEADER})
- if(NOT ${HEADER_CONST}_ROOT)
- set(FOUND 0)
- endif()
- endif()
- endif()
- if(FOUND)
- message(STATUS " Found library '${LIB${LIB}}'")
- message(STATUS " Found include '${${HEADER_CONST}_ROOT}'")
- set(${NAME} Imported::${NAME} PARENT_SCOPE)
- add_library(Imported::${NAME} INTERFACE IMPORTED)
- set_target_properties(Imported::${NAME} PROPERTIES
- INTERFACE_INCLUDE_DIRECTORIES ${${HEADER_CONST}_ROOT}
- INTERFACE_LINK_LIBRARIES ${LIB${LIB}})
- else()
- message("-- No library '${LIB}' found")
- endif()
- set(${NAME}_FOUND ${FOUND})
- endif()
- set(HAVE_${NAME} ${${NAME}_FOUND} PARENT_SCOPE)
+ message(STATUS "Checking for library '${LIB}' ...")
+ find_library(${NAME}_FOUND NAMES ${LIB} ${ARGN})
if(${NAME}_FOUND)
- safe_string(${HEADER} HEADER_CONST)
- find_path(HAVE_${HEADER_CONST} ${HEADER} PATHS ${${NAME}_INCLUDEDIR})
+ mark_as_advanced(${NAME}_FOUND)
+ message(STATUS " Found '${${NAME}_FOUND}'")
+
+ set(${NAME}_INCLUDES "")
+ foreach(PATH IN_LIST CMAKE_PREFIX_PATHS)
+ if(LIB${LIB} MATCHES "^${PATH}")
+ set(${NAME}_INCLUDES "${PATH}/include")
+ break()
+ endif()
+ endforeach()
+
+ add_library(Imported::${NAME} INTERFACE IMPORTED)
+ set_target_properties(Imported::${NAME} PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${${NAME}_INCLUDES}"
+ INTERFACE_LINK_LIBRARIES ${${NAME}_FOUND})
+
+ set(${NAME} Imported::${NAME} CACHE INTERNAL "${NAME} import target")
+ set(${HAVE} 1 CACHE INTERNAL "${HAVE}")
+ return()
endif()
+
+ message(STATUS " Not found")
endfunction()
--- /dev/null
+include(EnableDtrace)
+if(ENABLE_DTRACE)
+ find_package(DTrace)
+ if(DTRACE_EXECUTABLE)
+ configure_set(HAVE_DTRACE 1)
+ else()
+ message(WARNING "The dtrace command is required to enable dtrace/systemtap support.")
+ endif()
+endif()
+++ /dev/null
-include(CheckIncludeFileCXX)
-
-include(SafeString)
-
-# check for header.h and set HAVE_HEADER_H
-function(check_header HEADER_PATH)
- safe_string(${HEADER_PATH} HEADER_CONST)
- check_include_file_cxx(${HEADER_PATH} HAVE_${HEADER_CONST})
-endfunction(check_header)
-
--- /dev/null
+if(CMAKE_HOST_SYSTEM_NAME MATCHES "BSD")
+ find_program(PKGCONF pkgconf)
+ if(PKGCONF)
+ set(PKG_CONFIG_EXECUTABLE ${PKGCONF})
+ endif()
+endif()
+
+find_package(PkgConfig)
-macro(CHECK_TBB)
- check_header(execution)
- # TBBConfig only sets TBB_FOUND to FALSE
+
+configure_define(HAVE_TBB)
+
+# TBBConfig only sets TBB_FOUND to FALSE
+check_dependency(LIBTBB tbb)
+
+if(HAVE_LIBTBB)
+
+ cmake_push_check_state()
+ get_property(LIBTBB_INCLUDEDIR TARGET ${LIBTBB} PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
+ get_property(LIBTBB_LIBRARIES TARGET ${LIBTBB} PROPERTY INTERFACE_LINK_LIBRARIES)
+ set(CMAKE_REQUIRED_INCLUDES "${LIBTBB_INCLUDEDIR}")
+ set(CMAKE_REQUIRED_LIBRARIES "${LIBTBB_LIBRARIES}")
+ set(CMAKE_REQUIRED_FLAGS -std=c++17)
+
+ check_cxx_include(execution -std=c++17)
if(HAVE_EXECUTION)
- check_dependency(LIBTBB tbb tbb/task.h)
- if(HAVE_LIBTBB)
- cmake_push_check_state(RESET)
- get_property(LIBTBB_INCLUDEDIR TARGET ${LIBTBB} PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
- get_property(LIBTBB_LIBRARIES TARGET ${LIBTBB} PROPERTY INTERFACE_LINK_LIBRARIES)
- set(CMAKE_REQUIRED_INCLUDES "${LIBTBB_INCLUDEDIR}")
- set(CMAKE_REQUIRED_LIBRARIES "${LIBTBB_LIBRARIES}")
- set(CMAKE_REQUIRED_FLAGS -std=c++17)
- check_compiles(HAVE_TBB "std::vector<char> a={1,2,3}; std::all_of(std::execution::par,a.begin(),a.end(),[](char i){return i>0;});" vector algorithm execution)
- cmake_pop_check_state(RESET)
- endif()
+ check_cxx_source_compiles("
+ #include <vector>
+ #include <algorithm>
+ #include <execution>
+ int main() {
+ std::vector<char> a = {1,2,3};
+ std::all_of(std::execution::par, a.begin(), a.end(), [](char i) {
+ return i>0;
+ });
+ }
+ "
+ HAVE_TBB
+ )
endif()
-endmacro()
+ cmake_pop_check_state()
+endif()
--- /dev/null
+set(THREADS_PREFER_PTHREAD_FLAG ON)
+set(CMAKE_THREAD_PREFER_PTHREAD ON)
+find_package(Threads REQUIRED)
+++ /dev/null
-include(CheckTypeSize)
-
-include(SafeString)
-
-# check for type (possibly in header.h) and set HAVE_TYPE
-function(check_type TYPE HEADER)
- safe_string(${TYPE} TYPE_CONST)
- SET(CMAKE_EXTRA_INCLUDE_FILES ${HEADER})
- check_type_size(${TYPE} ${TYPE_CONST} LANGUAGE CXX)
- SET(CMAKE_EXTRA_INCLUDE_FILES)
-endfunction(check_type)
--- /dev/null
+configure_define(HAVE_VISIBILITY)
+
+check_flag(-fvisibility=hidden HAVE_VISIBILITY_FLAG)
+if(NOT HAVE_VISIBILITY_FLAG)
+ check_flag(-Wl,-fvisibility=hidden HAVE_VISIBILITY_LINKER_FLAG)
+endif()
+check_c_source("
+ __attribute__ ((visibility (\"default\")))
+ int main(int argc, char **argv) {
+ return *argv[argc-1];
+ }"
+ HAVE_VISIBILITY_ATTR
+)
+
+if(HAVE_VISIBILITY_ATTR AND (HAVE_VISIBILITY_FLAG OR HAVE_VISIBILITY_LINKER_FLAG))
+ if(HAVE_VISIBILITY_LINKER_FLAG)
+ string(APPEND CMAKE_SHARED_LINKER_FLAGS " -Wl,-fvisibility=hidden")
+ else()
+ add_compile_options("-fvisibility=hidden")
+ endif()
+ set(HAVE_VISIBILITY 1 CACHE INTERNAL "-fvisibility and __attribute__((visibility(...)))")
+endif()
if(HEADER MATCHES "^@")
string(SUBSTRING ${HEADER} 1 -1 HEADER)
configure_file(${HEADER}.in ${HEADER})
- string(PREPEND HEADER ${CMAKE_CURRENT_BINARY_DIR}/)
+ set(HEADER "${CMAKE_CURRENT_BINARY_DIR}/${HEADER}")
endif()
install(FILES ${HEADER}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${DIRECTORY}
+++ /dev/null
-
-# replace any non-alnum characters with underscore and uppercase the result
-function(safe_string STRING OUTPUT)
- string(REGEX REPLACE "[^0-9a-zA-Z_]" "_" HEADER_SAFE ${STRING})
- string(TOUPPER "${HEADER_SAFE}" HEADER_DEFN)
- set(${OUTPUT} ${HEADER_DEFN} PARENT_SCOPE)
-endfunction(safe_string)
-
--- /dev/null
+
+macro(configure_init CONFIG_HEADER_FILE)
+ set(CONFIGURE_FILE_IN ${CONFIG_HEADER_FILE}.in)
+ file(WRITE ${CONFIGURE_FILE_IN} "#pragma once\n")
+ set(CONFIGURE_FILE_OUT ${CONFIG_HEADER_FILE})
+endmacro()
+
+macro(configure_append)
+ file(APPEND ${CONFIGURE_FILE_IN} ${ARGN})
+endmacro()
+
+macro(configure_set VAR VAL)
+ set(${VAR} ${VAL})
+ configure_append("#cmakedefine ${VAR} 1\n")
+endmacro()
+
+macro(configure_define VAR)
+ configure_append("#cmakedefine ${VAR} 1\n")
+endmacro()
+macro(configure_undef VAR)
+ configure_append("#undef ${VAR}\n")
+endmacro()
+
+macro(configure_define_01 VAR)
+ configure_append("#cmakedefine01 ${VAR}\n")
+endmacro()
+
+macro(configure_define_literal VAR)
+ string(TOUPPER ${VAR} UPPER)
+ configure_append("#define ${UPPER} @${VAR}@\n")
+endmacro()
+macro(configure_define_header VAR)
+ string(TOUPPER ${VAR} UPPER)
+ configure_append("#define ${UPPER} <@${VAR}@>\n")
+endmacro()
+macro(configure_define_string VAR)
+ string(TOUPPER ${VAR} UPPER)
+ configure_append("#define ${UPPER} \"@${VAR}@\"\n")
+endmacro()
+include(_Configure)
+configure_init(${CMAKE_BINARY_DIR}/mem_config.h)
-# globals
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
include(CTest)
endif()
+
+include(CMakePushCheckState)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
-if(CMAKE_HOST_SYSTEM_NAME MATCHES "BSD")
- find_program(PKGCONF pkgconf)
- if(PKGCONF)
- set(PKG_CONFIG_EXECUTABLE ${PKGCONF})
+macro(make_have_identifier NAME ID)
+ string(MAKE_C_IDENTIFIER ${NAME} _make_have_identifier)
+ string(TOUPPER ${_make_have_identifier} _make_have_identifier)
+ set(${ID} HAVE_${_make_have_identifier})
+endmacro()
+
+include(CheckCCompilerFlag)
+macro(check_flag FLAG HAVE)
+ configure_define(${HAVE})
+ check_c_compiler_flag("${FLAG}" ${HAVE})
+endmacro()
+include(CheckCXXCompilerFlag)
+macro(check_cxx_flag FLAG HAVE)
+ configure_define(${HAVE})
+ check_cxx_compiler_flag("${FLAG}" ${HAVE})
+endmacro()
+include(CheckSymbolExists)
+macro(check_symbol NAME HEADER)
+ make_have_identifier(${NAME} HAVE)
+ configure_define(${HAVE})
+ cmake_push_check_state()
+ if(${ARGC} GREATER 1)
+ string(APPEND CMAKE_REQUIRED_FLAGS " ${ARGV2}")
endif()
-endif()
-find_package(PkgConfig)
-set(THREADS_PREFER_PTHREAD_FLAG ON)
-find_package(Threads REQUIRED)
-
-# locals
-include(InstallPublicHeaders)
-include(SafeString)
-include(CheckDebug)
-include(CheckDecl)
-include(CheckDependency)
-include(CheckHeader)
-include(CheckCompiles)
-include(CheckType)
-include(TestBigEndian)
-include(CheckByteswap)
-
-# configuration
-
-## debug
-check_debug()
-
-## dtrace
-include(EnableDtrace)
-if(ENABLE_DTRACE)
- find_package(DTrace)
- if(DTRACE_EXECUTABLE)
- set(HAVE_DTRACE 1)
- else()
- message(WARNING "The dtrace command is required to enable dtrace/systemtap support.")
+ check_symbol_exists(${NAME} ${HEADER} ${HAVE})
+ cmake_pop_check_state()
+endmacro()
+include(CheckCXXSymbolExists)
+macro(check_cxx_symbol NAME HEADER)
+ make_have_identifier(${NAME} HAVE)
+ configure_define(${HAVE})
+ cmake_push_check_state()
+ if(${ARGC} GREATER 1)
+ string(APPEND CMAKE_REQUIRED_FLAGS " ${ARGN}")
endif()
-endif()
+ check_cxx_symbol_exists(${NAME} ${HEADER} ${HAVE})
+ cmake_pop_check_state()
+endmacro()
+include(CheckIncludeFile)
+macro(check_include HEADER)
+ make_have_identifier(${HEADER} HAVE)
+ configure_define(${HAVE})
+ cmake_push_check_state()
+ if(${ARGC} GREATER 1)
+ string(APPEND CMAKE_REQUIRED_FLAGS " ${ARGN}")
+ endif()
+ check_include_file(${HEADER} ${HAVE})
+ cmake_pop_check_state()
+endmacro()
+include(CheckIncludeFileCXX)
+macro(check_cxx_include HEADER)
+ make_have_identifier(${HEADER} HAVE)
+ configure_define(${HAVE})
+ cmake_push_check_state()
+ if(${ARGC} GREATER 1)
+ string(APPEND CMAKE_REQUIRED_FLAGS " ${ARGN}")
+ endif()
+ check_include_file_cxx(${HEADER} ${HAVE})
+ cmake_pop_check_state()
+endmacro()
+include(CheckTypeSize)
+macro(check_type TYPE)
+ make_have_identifier(${TYPE} HAVE)
+ configure_define(${HAVE})
+ cmake_push_check_state()
+ if(${ARGC} GREATER 1)
+ list(APPEND CMAKE_EXTRA_INCLUDE_FILES ${ARGN})
+ endif()
+ check_type_size(${TYPE} ${HAVE})
+ cmake_pop_check_state()
+endmacro()
+include(CheckCSourceCompiles)
+macro(check_c_source SOURCE HAVE)
+ configure_define(${HAVE})
+ check_c_source_compiles("${SOURCE}" ${HAVE})
+endmacro()
+include(CheckCXXSourceCompiles)
+macro(check_cxx_source SOURCE HAVE)
+ configure_define(${HAVE})
+ check_cxx_source_compiles("${SOURCE}" ${HAVE})
+endmacro()
+
+include(CheckBacktrace)
+include(CheckByteswap)
+include(CheckDependency)
+include(CheckDtrace)
+include(CheckPkgconf)
+include(CheckDebug)
+include(CheckThreads)
+include(CheckVisibility)
+include(InstallPublicHeaders)
## sasl
+configure_define_01(LIBMEMCACHED_WITH_SASL_SUPPORT)
if(ENABLE_SASL)
- check_dependency(LIBSASL sasl2 sasl/sasl.h)
+ check_dependency(LIBSASL sasl2)
if(HAVE_LIBSASL)
set(LIBMEMCACHED_WITH_SASL_SUPPORT 1)
endif()
endif()
## hashes
-if(ENABLE_HASH_FNV64)
- set(HAVE_FNV64_HASH 1)
-endif()
-if(ENABLE_HASH_MURMUR)
- set(HAVE_MURMUR_HASH 1)
-endif()
-if(ENABLE_HASH_HSIEH)
- set(HAVE_HSIEH_HASH 1)
-endif()
-
-# system checks
-
-test_big_endian(WORDS_BIGENDIAN)
-check_byteswap()
+configure_set(HAVE_FNV64_HASH ${ENABLE_HASH_FNV64})
+configure_set(HAVE_MURMUR_HASH ${ENABLE_HASH_MURMUR})
+configure_set(HAVE_HSIEH_HASH ${ENABLE_HASH_HSIEH})
# most of the following checks are due to mingw or msvc; see gnulib
-check_header(arpa/inet.h)
-check_header(dlfcn.h)
-check_header(netdb.h)
-check_header(poll.h)
-check_header(strings.h)
-check_header(sys/socket.h)
-check_header(sys/time.h)
-check_header(sys/un.h)
-check_header(time.h)
-check_header(unistd.h)
+check_include(arpa/inet.h)
+check_include(dlfcn.h)
+check_include(netdb.h)
+check_include(poll.h)
+check_include(strings.h)
+check_include(sys/socket.h)
+check_include(sys/time.h)
+check_include(sys/un.h)
+check_include(unistd.h)
if(WIN32)
- check_header(io.h)
- check_header(winsock2.h)
- check_header(ws2tcpip.h)
+ check_include(io.h)
+ check_include(winsock2.h)
+ check_include(ws2tcpip.h)
endif()
-check_decl(abi::__cxa_demangle cxxabi.h)
-check_decl(fcntl fcntl.h)
-check_decl(htonll arpa/inet.h)
-check_decl(MSG_DONTWAIT sys/socket.h)
-check_decl(MSG_MORE sys/socket.h)
-check_decl(MSG_NOSIGNAL sys/socket.h)
-check_decl(SO_RCVTIMEO sys/socket.h)
-check_decl(SO_SNDTIMEO sys/socket.h)
-check_decl(setenv stdlib.h)
-check_decl(strerror string.h)
-check_decl(strerror_r string.h)
-
check_type(in_port_t netinet/in.h)
-check_compiles(HAVE_STRERROR_R_CHAR_P "
- char x, y = *strerror_r(0,&x,1);"
- string.h)
-
-
-find_package(Backtrace)
-if(Backtrace_FOUND)
- set(HAVE_BACKTRACE 1)
- set(BACKTRACE BACKTRACE)
- add_library(BACKTRACE INTERFACE IMPORTED)
- set_target_properties(BACKTRACE PROPERTIES
- INTERFACE_LINK_LIBRARIES "${Backtrace_LIBRARIES}"
- INTERFACE_INCLUDE_DIRECTORIES "${Backtrace_INCLUDE_DIR}")
-endif()
-
+check_cxx_symbol(abi::__cxa_demangle cxxabi.h)
+check_symbol(fcntl fcntl.h)
+check_symbol(htonll arpa/inet.h)
+check_symbol(MSG_DONTWAIT sys/socket.h)
+check_symbol(MSG_MORE sys/socket.h)
+check_symbol(MSG_NOSIGNAL sys/socket.h)
+check_symbol(SO_RCVTIMEO sys/socket.h)
+check_symbol(SO_SNDTIMEO sys/socket.h)
+check_symbol(setenv stdlib.h)
+check_symbol(strerror_r string.h)
+check_c_source("
+ #include <string.h>
+ int main() {
+ char x;
+ return *strerror_r(0, &x, 1);
+ }"
+ HAVE_STRERROR_R_CHAR_P
+)
-
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
if(NOT DEFINED ENV{CMAKE_BUILD_TYPE})
set(ENV{CMAKE_BUILD_TYPE} Release)
# legacy
set(HAVE_VISIBILITY 1)
-set(HAVE_SHARED_ENABLED 1)
# modules
if(NOT BUILD_DOCSONLY)
- set(AUTOHEADER_FILE mem_config.h)
-
set(CLIENTS
memcapable
memcat
add_subdirectory(contrib)
add_subdirectory(include)
add_subdirectory(support)
+
+ # tests need c++17 support
add_subdirectory(test)
# keep last
- configure_file(src/mem_config.h.in ${AUTOHEADER_FILE} @ONLY)
+ configure_file(${CONFIGURE_FILE_IN} ${CONFIGURE_FILE_OUT} @ONLY)
endif()
if(BUILD_DOCS OR BUILD_DOCSONLY)
if(ENABLE_MEMASLAP)
- include(CheckAtomics)
add_definitions(-D_GNU_SOURCE)
- check_atomics()
- check_dependency(LIBEVENT event event.h)
- check_decl(getline stdio.h)
- check_decl(_SC_NPROCESSORS_ONLN unistd.h)
+
+ include(CheckAtomics)
+
check_type(cpu_set_t sched.h)
+ check_symbol(getline stdio.h)
+ check_symbol(_SC_NPROCESSORS_ONLN unistd.h)
+
+ check_dependency(LIBEVENT event)
if(HAVE_LIBEVENT AND HAVE_ATOMICS)
add_executable(memaslap
${CMAKE_SOURCE_DIR}/src
${CMAKE_BINARY_DIR}/src
${CMAKE_BINARY_DIR})
- target_link_libraries(memaslap PUBLIC libmemcached Threads::Threads ${LIBEVENT} m)
+ target_link_libraries(memaslap PRIVATE libmemcached Threads::Threads ${LIBEVENT} m)
set_property(TARGET memaslap PROPERTY C_STANDARD 11)
if(CMAKE_INSTALL_RPATH)
set_target_properties(${CLIENT} PROPERTIES
return -1;
}
if (res == -1) {
- if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
+ if ((errno == EAGAIN) || (EAGAIN != EWOULDBLOCK && errno == EWOULDBLOCK))
break;
/* Should close on unhandled errors. */
ms_conn_set_state(c, conn_closing);
}
return TRANSMIT_INCOMPLETE;
}
- if ((res == -1) && ((errno == EAGAIN) || (errno == EWOULDBLOCK))) {
+ if ((res == -1) && ((errno == EAGAIN) || (EAGAIN != EWOULDBLOCK && errno == EWOULDBLOCK))) {
if (!ms_update_event(c, EV_WRITE | EV_PERSIST)) {
fprintf(stderr, "Couldn't update event.\n");
ms_conn_set_state(c, conn_closing);
pthread_mutex_t seq_mutex;
/* global synchronous flags for slap mode */
- bool finish_warmup;
- bool time_out;
+ ATOMIC bool finish_warmup;
+ ATOMIC bool time_out;
} ms_global_t;
/* global structure */
/**
* used to get the CPU count of the current system
*
- * @return return the cpu count if get, else return EXIT_FAILURE
+ * @return return the cpu count if possible, else return 1
*/
static uint32_t ms_get_cpu_count() {
-#ifdef HAVE__SC_NPROCESSORS_ONLN
- return sysconf(_SC_NPROCESSORS_CONF);
-
-#else
-# ifdef HAVE_CPU_SET_T
- int cpu_count = 0;
+#ifdef HAVE_CPU_SET_T
+ unsigned cpu_count = 0;
cpu_set_t cpu_set;
sched_getaffinity(0, sizeof(cpu_set_t), &cpu_set);
- for (int i = 0; i < (sizeof(cpu_set_t) * 8); i++) {
+ for (unsigned i = 0; i < (sizeof(cpu_set_t) * 8); i++) {
if (CPU_ISSET(i, &cpu_set)) {
cpu_count++;
}
}
return cpu_count;
-
-# endif
+#elif defined HAVE__SC_NPROCESSORS_ONLN
+ return sysconf(_SC_NPROCESSORS_CONF);
#endif
/* the system with one cpu at least */
- return EXIT_FAILURE;
+ return 1;
} /* ms_get_cpu_count */
/**
*
* @return total events recorded
*/
+#if HAVE_TSAN
+__attribute__ (( no_sanitize_thread, no_sanitize("thread")))
+#endif
static uint64_t ms_get_events(ms_stat_t *stat) {
uint64_t events = 0;
* @param freq, statistic frequency
* @param obj_size, average object size
*/
+#if HAVE_TSAN
+__attribute__ (( no_sanitize_thread, no_sanitize("thread")))
+#endif
void ms_dump_format_stats(ms_stat_t *stat, int run_time, int freq, int obj_size) {
uint64_t events = 0;
double global_average = 0;
def("username", 'u', required_argument, "SASL username.")
.apply = [](const client_options &opt, const extended_option &ext, memcached_st *memc) {
if (auto username = ext.arg) {
- if (!LIBMEMCACHED_WITH_SASL_SUPPORT) {
+#if !LIBMEMCACHED_WITH_SASL_SUPPORT
if (!opt.isset("quiet")) {
std::cerr
<< "SASL username was supplied, but binary was not built with SASL support.\n";
- return false;
}
- }
+ return false;
+#else
if (memc) {
if (MEMCACHED_SUCCESS
!= memcached_set_sasl_auth_data(memc, username, opt.argof("password"))) {
return false;
}
}
+#endif
}
return true;
};
+--------------------------------------------------------------------+
*/
+#pragma once
+
#include <chrono>
using time_clock = std::chrono::high_resolution_clock;
//initialize_sockets();
sock = connect_server(hostname, port);
if (sock == INVALID_SOCKET) {
- fprintf(stderr, "Failed to connect to <%s:%s>: %s\n", hostname ?: "(null)", port ?: "(null)",
+ fprintf(stderr, "Failed to connect to <%s:%s>: %s\n", hostname, port,
strerror(get_socket_errno()));
return EXIT_FAILURE;
}
if (reconnect) {
closesocket(sock);
if ((sock = connect_server(hostname, port)) == INVALID_SOCKET) {
- fprintf(stderr, "Failed to connect to <%s:%s>: %s\n", hostname ?: "(null)",
- port ?: "(null)", strerror(get_socket_errno()));
+ fprintf(stderr, "Failed to connect to <%s:%s>: %s\n", hostname,
+ port, strerror(get_socket_errno()));
fprintf(stderr, "%d of %d tests failed\n", failed, total);
return EXIT_FAILURE;
}
#pragma once
+extern "C" {
+
uint32_t hashkit_one_at_a_time(const char *key, size_t key_length, void *context);
uint32_t hashkit_fnv1_64(const char *key, size_t key_length, void *context);
uint32_t hashkit_jenkins(const char *key, size_t key_length, void *context);
uint32_t hashkit_md5(const char *key, size_t key_length, void *context);
+
+}
#pragma once
-#include "@AUTOHEADER_FILE@"
+#include "@CONFIGURE_FILE_OUT@"
if(HAVE_LIBSASL)
target_link_libraries(libmemcached PUBLIC ${LIBSASL})
endif()
+if(CMAKE_CXX_COMPILER_ID STREQUAL "SunPro")
+ # see https://docs.oracle.com/cd/E77782_01/html/E77789/bkamq.html#OSSCPgrxeu
+ target_link_libraries(libmemcached INTERFACE stdc++ gcc_s CrunG3 c)
+endif()
target_include_directories(libmemcached PRIVATE
${CMAKE_SOURCE_DIR}/src
${CMAKE_BINARY_DIR}/src
# include BACKTRACE_HEADER
-# if HAVE_ABI____CXA_DEMANGLE
+# ifdef HAVE_ABI____CXA_DEMANGLE
# include <cxxabi.h>
-# define USE_DEMANGLE 1
-# else
-# define USE_DEMANGLE 0
# endif
# ifdef HAVE_DLFCN_H
for (int x = 0; x < stack_frames; x++) {
bool was_demangled = false;
- if (USE_DEMANGLE) {
-# ifdef HAVE_DLFCN_H
+# ifdef HAVE_ABI____CXA_DEMANGLE
+# ifdef HAVE_DLFCN_H
Dl_info dlinfo;
if (dladdr(backtrace_buffer[x], &dlinfo)) {
char demangled_buffer[1024];
dlinfo.dli_fname);
}
}
+# endif
# endif
- }
if (was_demangled == false) {
fprintf(stderr, "?%d %p in %s\n", x, backtrace_buffer[x], symbollist[x]);
*/
#include "mem_config.h"
+
+#if HAVE_HTONLL && HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+
#include "libmemcached/byteorder.h"
/* Byte swap a 64-bit number. */
return MEMCACHED_NOT_SUPPORTED;
}
+memcached_return_t memcached_destroy_sasl_auth_data(memcached_st *) {
+ return MEMCACHED_NOT_SUPPORTED;
+}
+
+memcached_return_t memcached_sasl_authenticate_connection(memcached_instance_st *) {
+ return MEMCACHED_NOT_SUPPORTED;
+}
+
#endif
#pragma once
-#include "util/string.hpp"
-
-#define memcached_literal_param util_literal_param
-#define memcached_literal_param_size util_literal_param_size
-#define memcached_string_make_from_cstr util_string_make_from_cstr
-#define memcached_array_length util_array_length
+#define memcached_literal_param(str) (str),strlen(str)
+#define memcached_literal_param_size(str) strlen(str)
+#define memcached_string_make_from_cstr(str) (str),((str)?strlen(str):0)
/**
Strings are always under our control so we make some assumptions
+--------------------------------------------------------------------+
*/
+#pragma once
+
#define MAX_UDP_DATAGRAM_LENGTH 1400
#define UDP_DATAGRAM_HEADER_LENGTH 8
#define UDP_REQUEST_ID_MSG_SIG_DIGITS 10
-check_header(umem.h)
+check_include(umem.h)
add_library(libmemcachedprotocol SHARED
ascii_handler.c
#include <string.h>
#include <inttypes.h>
-#ifndef NDEBUG
-# include <signal.h>
-#endif
-
#include "libmemcachedprotocol/common.h"
-#ifndef NDEBUG
+#ifndef HAVE_UMEM_H
+
+# ifndef NDEBUG
+# include <signal.h>
+
const uint64_t redzone_pattern = 0xdeadbeefcafebabe;
int cache_error = 0;
-#endif
+
+# endif
const size_t initial_pool_size = 64;
ret->constructor = constructor;
ret->destructor = destructor;
-#ifndef NDEBUG
+# ifndef NDEBUG
ret->bufsize = bufsize + 2 * sizeof(redzone_pattern);
-#else
+# else
ret->bufsize = bufsize;
-#endif
+# endif
(void) align;
}
static inline void *get_object(void *ptr) {
-#ifndef NDEBUG
+# ifndef NDEBUG
uint64_t *pre = ptr;
return pre + 1;
-#else
+# else
return ptr;
-#endif
+# endif
}
void cache_destroy(cache_t *cache) {
}
pthread_mutex_unlock(&cache->mutex);
-#ifndef NDEBUG
+# ifndef NDEBUG
if (object) {
/* add a simple form of buffer-check */
uint64_t *pre = ret;
memcpy(((char *) ret) + cache->bufsize - (2 * sizeof(redzone_pattern)), &redzone_pattern,
sizeof(redzone_pattern));
}
-#endif
+# endif
return object;
}
void cache_free(cache_t *cache, void *ptr) {
pthread_mutex_lock(&cache->mutex);
-#ifndef NDEBUG
+# ifndef NDEBUG
/* validate redzone... */
if (memcmp(((char *) ptr) + cache->bufsize - (2 * sizeof(redzone_pattern)), &redzone_pattern,
sizeof(redzone_pattern))
return;
}
ptr = pre;
-#endif
+# endif
if (cache->freecurr < cache->freetotal) {
cache->ptr[cache->freecurr++] = ptr;
} else {
}
pthread_mutex_unlock(&cache->mutex);
}
+
+#endif // HAVE_UMEM_H
#include "libmemcachedutil/common.h"
+#include <alloca.h>
#include <cassert>
#include <cerrno>
+#include <cstring>
#include <pthread.h>
#include <memory>
-/*
- +--------------------------------------------------------------------+
- | libmemcached - C/C++ Client Library for memcached |
- +--------------------------------------------------------------------+
- | Redistribution and use in source and binary forms, with or without |
- | modification, are permitted under the terms of the BSD license. |
- | You should have received a copy of the license in a bundled file |
- | named LICENSE; in case you did not receive a copy you can review |
- | the terms online at: https://opensource.org/licenses/BSD-3-Clause |
- +--------------------------------------------------------------------+
- | Copyright (c) 2006-2014 Brian Aker https://datadifferential.com/ |
- | Copyright (c) 2020 Michael Wallner <mike@php.net> |
- +--------------------------------------------------------------------+
-*/
-
#pragma once
-
#cmakedefine01 LIBMEMCACHED_WITH_SASL_SUPPORT
-
#define LIBMEMCACHED_WITH_SASL_PWDB "@LIBMEMCACHED_WITH_SASL_PWDB@"
#define LIBMEMCACHED_WITH_SASL_CONF "@LIBMEMCACHED_WITH_SASL_CONF@"
-
#cmakedefine WORDS_BIGENDIAN 1
-
#cmakedefine HAVE_ATOMIC_ADD_NV 1
#cmakedefine HAVE_BUILTIN_SYNC 1
#cmakedefine HAVE_BUILTIN_ATOMIC 1
#cmakedefine HAVE_C_STDATOMIC 1
#cmakedefine HAVE_CXX_STDATOMIC 1
#cmakedefine HAVE_ATOMICS 1
-
#cmakedefine HAVE__SC_NPROCESSORS_ONLN 1
#cmakedefine HAVE_ABI____CXA_DEMANGLE 1
#cmakedefine HAVE_BACKTRACE 1
#cmakedefine HAVE_VISIBILITY 1
#cmakedefine HAVE_WINSOCK2_H 1
#cmakedefine HAVE_WS2TCPIP_H 1
-
-#if HAVE_BACKTRACE
# define BACKTRACE_HEADER <@Backtrace_HEADER@>
-#endif
-
-#if HAVE_BYTESWAP
# define BYTESWAP_32 @BYTESWAP_32@
-# cmakedefine BYTESWAP_HEADER <@BYTESWAP_HEADER@>
-#endif
-
+#cmakedefine BYTESWAP_HEADER <@BYTESWAP_HEADER@>
#define HAVE_LIBMEMCACHED 1
+++ /dev/null
-/* $Header: /cvsroot/wikipedia/willow/src/bin/willow/daemon.c,v 1.1 2005/05/02 19:15:21 kateturner Exp $ */
-/* $NetBSD: daemon.c,v 1.9 2003/08/07 16:42:46 agc Exp $ */
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- * Copyright (c) 2010
- * Stewart Smith
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "mem_config.h"
-
-#if defined __SUNPRO_C || defined __DECC || defined __HP_cc
-# pragma ident "@(#)$Header: /cvsroot/wikipedia/willow/src/bin/willow/daemon.c,v 1.1 2005/05/02 19:15:21 kateturner Exp $"
-# pragma ident "$NetBSD: daemon.c,v 1.9 2003/08/07 16:42:46 agc Exp $"
-#endif
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#if HAVE_SYS_WAIT_H
-#include <sys/wait.h>
-#include <signal.h>
-#if HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-#include <sys/select.h>
-
-#include <util/daemon.hpp>
-
-#include <iostream>
-
-namespace datadifferential {
-namespace util {
-
-pid_t parent_pid;
-
-extern "C"
-{
-
-static void sigusr1_handler(int sig)
-{
- if (sig == SIGUSR1)
- {
- _exit(EXIT_SUCCESS);
- }
-}
-
-}
-
-bool daemon_is_ready(bool close_io)
-{
- if (kill(parent_pid, SIGUSR1) == -1)
- {
- perror("kill");
- return false;
- }
-
- if (close_io == false)
- {
- return true;;
- }
-
- int fd;
- if ((fd = open("/dev/null", O_RDWR, 0)) < 0)
- {
- perror("open");
- return false;
- }
- else
- {
- if (dup2(fd, STDIN_FILENO) < 0)
- {
- perror("dup2 stdin");
- return false;
- }
-
- if (dup2(fd, STDOUT_FILENO) < 0)
- {
- perror("dup2 stdout");
- return false;
- }
-
- if (dup2(fd, STDERR_FILENO) < 0)
- {
- perror("dup2 stderr");
- return false;
- }
-
- if (fd > STDERR_FILENO)
- {
- if (close(fd) < 0)
- {
- perror("close");
- return false;
- }
- }
- }
-
- return true;
-}
-
-#ifndef __INTEL_COMPILER
-#pragma GCC diagnostic ignored "-Wold-style-cast"
-#endif
-
-bool daemonize(bool is_chdir, bool wait_sigusr1)
-{
- struct sigaction new_action;
-
- new_action.sa_handler= sigusr1_handler;
- sigemptyset(&new_action.sa_mask);
- new_action.sa_flags= 0;
- sigaction(SIGUSR1, &new_action, NULL);
-
- parent_pid= getpid();
-
- pid_t child= fork();
-
- switch (child)
- {
- case -1:
- return false;
-
- case 0:
- break;
-
- default:
- if (wait_sigusr1)
- {
- /* parent */
- int exit_code= EXIT_FAILURE;
- int status;
- while (waitpid(child, &status, 0) != child)
- { }
-
- if (WIFEXITED(status))
- {
- exit_code= WEXITSTATUS(status);
- }
- if (WIFSIGNALED(status))
- {
- exit_code= EXIT_FAILURE;
- }
- _exit(exit_code);
- }
- else
- {
- _exit(EXIT_SUCCESS);
- }
- }
-
- /* child */
- if (setsid() == -1)
- {
- perror("setsid");
- return false;
- }
-
- if (is_chdir)
- {
- if (chdir("/") < 0)
- {
- perror("chdir");
- return false;
- }
- }
-
- return true;
-}
-
-} /* namespace util */
-} /* namespace datadifferential */
+++ /dev/null
-/* $Header: /cvsroot/wikipedia/willow/src/bin/willow/daemon.c,v 1.1 2005/05/02 19:15:21 kateturner Exp $ */
-/* $NetBSD: daemon.c,v 1.9 2003/08/07 16:42:46 agc Exp $ */
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- * Copyright (c) 2010
- * Stewart Smith
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#pragma once
-
-namespace datadifferential {
-namespace util {
-
-bool daemon_is_ready(bool close_io);
-bool daemonize(bool is_chdir= true, bool wait_sigusr1= true);
-
-} /* namespace util */
-} /* namespace datadifferential */
+++ /dev/null
-/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- *
- * DataDifferential Utility Library
- *
- * Copyright (C) 2011 Data Differential, http://datadifferential.com/
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * * The names of its contributors may not be used to endorse or
- * promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#include "mem_config.h"
-
-#include "util/instance.hpp"
-
-#include <cstdio>
-#include <iostream>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <poll.h>
-#include <sstream>
-#ifdef HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-#include <sys/types.h>
-
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#ifndef INVALID_SOCKET
-# define INVALID_SOCKET -1
-#endif
-
-#ifndef SOCKET_ERROR
-# define SOCKET_ERROR -1
-#endif
-
-#ifndef get_socket_errno
-# define get_socket_errno() errno
-#endif
-
-#ifndef closesocket
-# define closesocket(a) close(a)
-#endif
-
-
-namespace datadifferential {
-namespace util {
-
-Instance::Instance(const std::string& hostname_arg, const std::string& service_arg) :
- _host(hostname_arg),
- _service(service_arg),
- _sockfd(INVALID_SOCKET),
- state(NOT_WRITING),
- _addrinfo(0),
- _addrinfo_next(0),
- _finish_fn(NULL),
- _operations()
- {
- }
-
-Instance::Instance(const std::string& hostname_arg, const in_port_t port_arg) :
- _host(hostname_arg),
- _sockfd(INVALID_SOCKET),
- state(NOT_WRITING),
- _addrinfo(0),
- _addrinfo_next(0),
- _finish_fn(NULL),
- _operations()
- {
- char tmp[BUFSIZ];
- snprintf(tmp, sizeof(tmp), "%u", static_cast<unsigned int>(port_arg));
- _service= tmp;
- }
-
-Instance::~Instance()
-{
- close_socket();
- free_addrinfo();
- for (Operation::vector::iterator iter= _operations.begin(); iter != _operations.end(); ++iter)
- {
- delete *iter;
- }
- _operations.clear();
-
- delete _finish_fn;
-}
-
-bool Instance::run()
-{
- while (not _operations.empty())
- {
- Operation::vector::value_type operation= _operations.back();
-
- switch (state)
- {
- case NOT_WRITING:
- {
- free_addrinfo();
-
- struct addrinfo ai;
- memset(&ai, 0, sizeof(struct addrinfo));
- ai.ai_socktype= SOCK_STREAM;
- ai.ai_protocol= IPPROTO_TCP;
-
- int ret= getaddrinfo(_host.c_str(), _service.c_str(), &ai, &_addrinfo);
- if (ret)
- {
- std::stringstream message;
- message << "Failed to connect on " << _host.c_str() << ":" << _service.c_str() << " with " << gai_strerror(ret);
- _last_error= message.str();
- return false;
- }
- }
- _addrinfo_next= _addrinfo;
- state= CONNECT;
- break;
-
- case NEXT_CONNECT_ADDRINFO:
- if (_addrinfo_next->ai_next == NULL)
- {
- std::stringstream message;
- message << "Error connecting to " << _host.c_str() << "." << std::endl;
- _last_error= message.str();
- return false;
- }
- _addrinfo_next= _addrinfo_next->ai_next;
- /* fall through */
-
- case CONNECT:
- close_socket();
-
- _sockfd= socket(_addrinfo_next->ai_family,
- _addrinfo_next->ai_socktype,
- _addrinfo_next->ai_protocol);
- if (_sockfd == INVALID_SOCKET)
- {
- perror("socket");
- continue;
- }
-
- if (connect(_sockfd, _addrinfo_next->ai_addr, _addrinfo_next->ai_addrlen) < 0)
- {
- switch(errno)
- {
- case EAGAIN:
- case EINTR:
- state= CONNECT;
- break;
-
- case EINPROGRESS:
- state= CONNECTING;
- break;
-
- case ECONNREFUSED:
- case ENETUNREACH:
- case ETIMEDOUT:
- default:
- state= NEXT_CONNECT_ADDRINFO;
- break;
- }
- }
- else
- {
- state= CONNECTING;
- }
- break;
-
- case CONNECTING:
- // Add logic for poll() for nonblocking.
- state= CONNECTED;
- break;
-
- case CONNECTED:
- case WRITING:
- {
- size_t packet_length= operation->size();
- const char *packet= operation->ptr();
-
- while(packet_length)
- {
- ssize_t write_size= send(_sockfd, packet, packet_length, 0);
-
- if (write_size < 0)
- {
- switch(errno)
- {
- default:
- std::cerr << "Failed dureng send(" << strerror(errno) << ")" << std::endl;
- break;
- }
- }
-
- packet_length-= static_cast<size_t>(write_size);
- packet+= static_cast<size_t>(write_size);
- }
- }
- state= READING;
- break;
-
- case READING:
- if (operation->has_response())
- {
- ssize_t read_length;
-
- do
- {
- char buffer[BUFSIZ];
- read_length= ::recv(_sockfd, buffer, sizeof(buffer), 0);
-
- if (read_length < 0)
- {
- switch(errno)
- {
- default:
- _last_error.clear();
- _last_error+= "Error occured while reading data from ";
- _last_error+= _host;
- return false;
- }
- }
- else if (read_length == 0)
- {
- _last_error.clear();
- _last_error+= "Socket was shutdown while reading from ";
- _last_error+= _host;
-
- return false;
- }
-
- operation->push(buffer, static_cast<size_t>(read_length));
-
- } while (more_to_read());
- } // end has_response
-
- state= FINISHED;
- break;
-
- case FINISHED:
- std::string response;
- bool success= operation->response(response);
- if (_finish_fn)
- {
- if (not _finish_fn->call(success, response))
- {
- // Error was sent from _finish_fn
- return false;
- }
- }
-
- if (operation->reconnect())
- {
- }
- _operations.pop_back();
- delete operation;
-
- state= CONNECTED;
- break;
- } // end switch
- }
-
- return true;
-} // end run()
-
-bool Instance::more_to_read() const
-{
- struct pollfd fds;
- fds.fd= _sockfd;
- fds.events = POLLIN;
-
- if (poll(&fds, 1, 5) < 1) // Default timeout is 5
- {
- return false;
- }
-
- return true;
-}
-
-void Instance::close_socket()
-{
- if (_sockfd == INVALID_SOCKET)
- {
- return;
- }
-
- /* in case of death shutdown to avoid blocking at close() */
- if (shutdown(_sockfd, SHUT_RDWR) == SOCKET_ERROR && get_socket_errno() != ENOTCONN)
- {
- perror("shutdown");
- }
- else if (closesocket(_sockfd) == SOCKET_ERROR)
- {
- perror("close");
- }
-
- _sockfd= INVALID_SOCKET;
-}
-
-void Instance::free_addrinfo()
-{
- if (_addrinfo == NULL)
- {
- return;
- }
-
- freeaddrinfo(_addrinfo);
- _addrinfo= NULL;
- _addrinfo_next= NULL;
-}
-
-} /* namespace util */
-} /* namespace datadifferential */
+++ /dev/null
-/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- *
- * DataDifferential Utility Library
- *
- * Copyright (C) 2011 Data Differential, http://datadifferential.com/
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * * The names of its contributors may not be used to endorse or
- * promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-#include <cassert>
-#include <cerrno>
-#include <cstddef>
-#include <cstdio>
-#include <netinet/in.h>
-#include <string>
-#include <sys/socket.h>
-
-#include "util/operation.hpp"
-
-struct addrinfo;
-
-namespace datadifferential {
-namespace util {
-
-class Instance
-{
-private:
- enum connection_state_t {
- NOT_WRITING,
- NEXT_CONNECT_ADDRINFO,
- CONNECT,
- CONNECTING,
- CONNECTED,
- WRITING,
- READING,
- FINISHED
- };
- std::string _last_error;
-
-public: // Callbacks
- class Finish {
-
- public:
- virtual ~Finish() { }
-
- virtual bool call(const bool, const std::string &)= 0;
- };
-
-
-public:
- Instance(const std::string& hostname_arg, const std::string& service_arg);
-
- Instance(const std::string& hostname_arg, const in_port_t port_arg);
-
- ~Instance();
-
- bool run();
-
- void set_finish(Finish *arg)
- {
- _finish_fn= arg;
- }
-
- void push(util::Operation *next)
- {
- _operations.push_back(next);
- }
-
-private:
- void close_socket();
-
- void free_addrinfo();
-
- bool more_to_read() const;
-
- std::string _host;
- std::string _service;
- int _sockfd;
- connection_state_t state;
- struct addrinfo *_addrinfo;
- struct addrinfo *_addrinfo_next;
- Finish *_finish_fn;
- Operation::vector _operations;
-};
-
-} /* namespace util */
-} /* namespace datadifferential */
+++ /dev/null
-/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- *
- * Data Differential Utility library
- *
- * Copyright (C) 2012 Data Differential, http://datadifferential.com/
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * * The names of its contributors may not be used to endorse or
- * promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-#include <cerrno>
-#include <cstdarg>
-#include <cstdio>
-#include <fcntl.h>
-#include <iostream>
-#include <string>
-#include <syslog.h>
-
-#define UTIL_MAX_ERROR_SIZE 2048
-
-namespace datadifferential {
-namespace util {
-
-/** Verbosity levels.
- */
-enum verbose_t
-{
- // Logging this will cause shutdown
- VERBOSE_FATAL= LOG_EMERG, // syslog:LOG_EMERG
-
- VERBOSE_ALERT= LOG_ALERT, // syslog:LOG_ALERT
- VERBOSE_CRITICAL= LOG_CRIT, // syslog:LOG_CRIT
-
- VERBOSE_ERROR= LOG_ERR, // syslog:LOG_ERR
-
- VERBOSE_WARN= LOG_WARNING, // syslog:LOG_WARNING
-
- VERBOSE_NOTICE= LOG_NOTICE, // syslog:LOG_NOTICE
-
- VERBOSE_INFO= LOG_INFO, // syslog:LOG_INFO
-
- VERBOSE_DEBUG= LOG_DEBUG // syslog:LOG_DEBUG
-};
-
-#ifndef __INTEL_COMPILER
-#pragma GCC diagnostic ignored "-Wformat-nonliteral"
-#endif
-
-struct log_info_st
-{
- std::string name;
- std::string filename;
- int fd;
- bool opt_syslog;
- bool opt_file;
- bool init_success;
-
- log_info_st(const std::string& name_arg, const std::string &filename_arg, bool syslog_arg) :
- name(name_arg),
- filename(filename_arg),
- fd(-1),
- opt_syslog(syslog_arg),
- opt_file(false),
- init_success(false)
- {
- if (opt_syslog)
- {
- openlog(name.c_str(), LOG_PID | LOG_NDELAY, LOG_USER);
- }
-
- init();
- }
-
- void init()
- {
- if (filename.size())
- {
- if (filename.compare("stderr") == 0)
- {
- fd= STDERR_FILENO;
- }
- else
- {
- fd= open(filename.c_str(), O_CREAT | O_WRONLY | O_APPEND, 0644);
- if (fd == -1)
- {
- if (opt_syslog)
- {
- char buffer[1024];
- char *getcwd_ret= getcwd(buffer, sizeof(buffer));
- syslog(LOG_ERR, "Could not open log file \"%.*s\", from \"%s\", open failed with (%s)",
- int(filename.size()), filename.c_str(),
- getcwd_ret,
- strerror(errno));
- }
- std::cerr << "Could not open log file for writing, switching to stderr." << std::endl;
-
- fd= STDERR_FILENO;
- }
- }
-
- opt_file= true;
- }
-
- init_success= true;
- }
-
- bool initialized() const
- {
- return init_success;
- }
-
- int file() const
- {
- return fd;
- }
-
- void write(verbose_t verbose, const char *format, ...)
- {
- if (opt_file or opt_syslog)
- {
- va_list args;
- va_start(args, format);
- char mesg[BUFSIZ];
- int mesg_length= vsnprintf(mesg, sizeof(mesg), format, args);
- va_end(args);
-
- if (opt_file)
- {
- char buffer[UTIL_MAX_ERROR_SIZE];
- int buffer_length= snprintf(buffer, sizeof(buffer), "%7s %.*s\n", verbose_name(verbose), mesg_length, mesg);
- if (::write(file(), buffer, buffer_length) == -1)
- {
- std::cerr << "Could not write to log file." << std::endl;
- syslog(LOG_EMERG, "gearmand could not open log file %s, got error %s", filename.c_str(), strerror(errno));
- }
-
- }
-
- if (opt_syslog)
- {
- syslog(int(verbose), "%7s %.*s", verbose_name(verbose), mesg_length, mesg);
- }
- }
- }
-
- ~log_info_st()
- {
- if (fd != -1 and fd != STDERR_FILENO)
- {
- close(fd);
- }
-
- if (opt_syslog)
- {
- closelog();
- }
- }
-
-private:
- const char *verbose_name(verbose_t verbose)
- {
- switch (verbose)
- {
- case VERBOSE_FATAL:
- return "FATAL";
-
- case VERBOSE_ALERT:
- return "ALERT";
-
- case VERBOSE_CRITICAL:
- return "CRITICAL";
-
- case VERBOSE_ERROR:
- return "ERROR";
-
- case VERBOSE_WARN:
- return "WARNING";
-
- case VERBOSE_NOTICE:
- return "NOTICE";
-
- case VERBOSE_INFO:
- return "INFO";
-
- case VERBOSE_DEBUG:
- return "DEBUG";
-
- default:
- break;
- }
-
- return "UNKNOWN";
- }
-};
-
-} // namespace util
-} // namespace datadifferential
+++ /dev/null
-/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- *
- * DataDifferential Utility Library
- *
- * Copyright (C) 2011 Data Differential, http://datadifferential.com/
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * * The names of its contributors may not be used to endorse or
- * promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "mem_config.h"
-
-#include "util/logfile.hpp"
-
-#include <cerrno>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-#include <fcntl.h>
-#include <fstream>
-#include <iostream>
-#include <sstream>
-#include <sys/stat.h>
-#include <sys/types.h>
-#if HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-namespace datadifferential {
-namespace util {
-
-Logfile::Logfile(const std::string &arg) :
- _filename(arg)
-{
- time_t tmp= time(NULL);
- _log_file << "shutdown: " << ctime(&tmp) << std::endl;
-}
-
-Logfile::~Logfile()
-{
- if (not _filename.empty())
- {
- _log_file.close();
- if (access(_filename.c_str(), F_OK) == -1)
- { }
- else if (unlink(_filename.c_str()) == -1)
- { }
- }
-}
-
-bool Logfile::open()
-{
- if (_filename.empty())
- {
- _log_file.open("/dev/stderr");
- return true;
- }
-
- _log_file.open(_filename.c_str());
- if (not _log_file.good())
- {
- return false;
- }
-
- time_t tmp= time(NULL);
- _log_file << "startup: " << ctime(&tmp) << std::endl;
-
- return true;
-}
-
-} /* namespace util */
-} /* namespace datadifferential */
+++ /dev/null
-/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- *
- * DataDifferential Utility Library
- *
- * Copyright (C) 2011 Data Differential, http://datadifferential.com/
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * * The names of its contributors may not be used to endorse or
- * promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-#include <string>
-#include <fstream>
-
-namespace datadifferential {
-namespace util {
-
-class Logfile
-{
-public:
- Logfile(const std::string &arg);
-
- ~Logfile();
-
- std::ofstream &log()
- {
- return _log_file;
- }
-
- bool open();
-
-private:
- const std::string _filename;
- std::ofstream _log_file;
-};
-
-} /* namespace util */
-} /* namespace datadifferential */
+++ /dev/null
-/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- *
- * DataDifferential Utility Library
- *
- * Copyright (C) 2011 Data Differential, http://datadifferential.com/
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * * The names of its contributors may not be used to endorse or
- * promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#include "mem_config.h"
-
-#include "util/operation.hpp"
-#include <string>
-
-namespace datadifferential {
-namespace util {
-
-bool Operation::response(std::string &arg)
-{
- if (_response.empty())
- {
- return false;
- }
-
- if (not memcmp("OK\r\n", &_response[0], 3))
- { }
- else if (not memcmp("OK ", &_response[0], 3))
- {
- arg.append(&_response[3], _response.size() -3);
- }
- else if (not memcmp("ERR ", &_response[0], 4))
- {
- arg.append(&_response[4], _response.size() -4);
- return false;
- }
- else
- {
- arg.append(&_response[0], _response.size());
- }
-
- return true;
-}
-
-} /* namespace util */
-} /* namespace datadifferential */
+++ /dev/null
-/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- *
- * DataDifferential Utility Library
- *
- * Copyright (C) 2011 Data Differential, http://datadifferential.com/
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * * The names of its contributors may not be used to endorse or
- * promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-
-#include <cstring>
-#include <iosfwd>
-#include <vector>
-
-namespace datadifferential {
-namespace util {
-
-class Operation {
- typedef std::vector<char> Packet;
-
-public:
- typedef std::vector<Operation *> vector;
-
- Operation(const char *command, size_t command_length, bool expect_response= true) :
- _expect_response(expect_response),
- packet(),
- _response()
- {
- packet.resize(command_length);
- memcpy(&packet[0], command, command_length);
- }
-
- ~Operation()
- { }
-
- size_t size() const
- {
- return packet.size();
- }
-
- const char* ptr() const
- {
- return &(packet)[0];
- }
-
- bool has_response() const
- {
- return _expect_response;
- }
-
- void push(const char *buffer, size_t buffer_size)
- {
- size_t response_size= _response.size();
- _response.resize(response_size +buffer_size);
- memcpy(&_response[0] +response_size, buffer, buffer_size);
- }
-
- // Return false on error
- bool response(std::string &);
-
- bool reconnect() const
- {
- return false;
- }
-
-private:
- bool _expect_response;
- Packet packet;
- Packet _response;
-};
-
-} /* namespace util */
-} /* namespace datadifferential */
+++ /dev/null
-/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- *
- * DataDifferential Utility Library
- *
- * Copyright (C) 2011 Data Differential, http://datadifferential.com/
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * * The names of its contributors may not be used to endorse or
- * promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "mem_config.h"
-
-#include "util/pidfile.hpp"
-
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-#include <cerrno>
-#include <fcntl.h>
-#include <iostream>
-#include <sstream>
-#include <sys/stat.h>
-#include <sys/types.h>
-#if #if HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-extern "C" {
-
- char pid_file[1024 * 4]= { 0 };
-
- static void remove_pidfile(void)
- {
- if (pid_file[0])
- {
- if (unlink(pid_file) == -1)
- {
- std::cerr << "Could not remove pidfile: " << pid_file << "(" << strerror(errno) << ")" << std::endl;
- }
-
- pid_file[0]= 0;
- }
- }
-
-}
-
-namespace datadifferential {
-namespace util {
-
-Pidfile::Pidfile(const std::string &arg) :
- _last_errno(0),
- _filename(arg)
-{
-}
-
-
-Pidfile::~Pidfile()
-{
- if (not _filename.empty())
- {
- if (access(_filename.c_str(), F_OK) == -1)
- {
- std::stringstream error_stream;
- error_stream << "Could not access the pid file: " << _filename << "(" << strerror(errno) << ")";
- _error_message= error_stream.str();
- }
- else if (unlink(_filename.c_str()) == -1)
- {
- std::stringstream error_stream;
- error_stream << "Could not remove the pid file: " << _filename << "(" << strerror(errno) << ")";
- _error_message= error_stream.str();
- }
- }
- pid_file[0]= 0;
-}
-
-bool Pidfile::create()
-{
- if (_filename.empty())
- {
- return true;
- }
-
- if (access(_filename.c_str(), F_OK) == 0)
- {
- if (unlink(_filename.c_str()) == -1)
- {
- std::stringstream error_stream;
- error_stream << "Unable to remove exisiting file:" << _filename << "(" << strerror(errno) << ")";
- _error_message= error_stream.str();
-
- return false;
- }
- }
-
- int oflags= O_CREAT|O_WRONLY|O_TRUNC;
-#ifdef HAVE_O_CLOEXEC
- oflags= oflags | O_CLOEXEC;
-#endif
-
- int file;
- if ((file = open(_filename.c_str(), oflags, S_IRWXU|S_IRGRP|S_IROTH)) < 0)
- {
- std::stringstream error_stream;
- error_stream << "Could not open pid file for writing: " << _filename << "(" << strerror(errno) << ")";
- _error_message= error_stream.str();
-
- return false;
- }
-
- char buffer[BUFSIZ];
- unsigned long temp= static_cast<unsigned long>(getpid());
- int length= snprintf(buffer, sizeof(buffer), "%lu\n", temp);
- if (write(file, buffer, length) != length)
- {
- std::stringstream error_stream;
- error_stream << "Could not write pid to file: " << _filename << "(" << strerror(errno) << ")";
- _error_message= error_stream.str();
- close(file);
-
- return false;
- }
-
- if (close(file) < 0)
- {
- _error_message+= "Could not close() file after writing pid to it: ";
- _error_message+= _filename;
- return false;
- }
- snprintf(pid_file, sizeof(pid_file), "%s", _filename.c_str());
- atexit(remove_pidfile);
-
- return true;
-}
-
-} /* namespace util */
-} /* namespace datadifferential */
+++ /dev/null
-/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- *
- * DataDifferential Utility Library
- *
- * Copyright (C) 2011 Data Differential, http://datadifferential.com/
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * * The names of its contributors may not be used to endorse or
- * promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-#include <string>
-
-namespace datadifferential {
-namespace util {
-
-class Pidfile
-{
-public:
- Pidfile(const std::string &arg);
-
- ~Pidfile();
-
- const std::string &error_message()
- {
- return _error_message;
- }
-
- bool create();
-
-private:
- int _last_errno;
- const std::string _filename;
- std::string _error_message;
-};
-
-} /* namespace util */
-} /* namespace datadifferential */
+++ /dev/null
-/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- *
- * Data Differential Utility library
- *
- * Copyright (C) 2012 Data Differential, http://datadifferential.com/
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * * The names of its contributors may not be used to endorse or
- * promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "mem_config.h"
-
-#include <cassert>
-#include <cerrno>
-#include <csignal>
-#include <cstdlib>
-#include <cstring>
-#include <iostream>
-
-#include <util/signal.hpp>
-
-namespace datadifferential {
-namespace util {
-
-#define MAGIC_MEMORY 123569
-
-bool SignalThread::is_shutdown()
-{
- bool ret;
- pthread_mutex_lock(&shutdown_mutex);
- ret= bool(__shutdown != SHUTDOWN_RUNNING);
- pthread_mutex_unlock(&shutdown_mutex);
-
- return ret;
-}
-
-void SignalThread::set_shutdown(shutdown_t arg)
-{
- pthread_mutex_lock(&shutdown_mutex);
- __shutdown= arg;
- pthread_mutex_unlock(&shutdown_mutex);
-
- if (arg == SHUTDOWN_GRACEFUL)
- {
- if (pthread_kill(thread, SIGUSR2) == 0)
- {
- void *retval;
- pthread_join(thread, &retval);
- }
- }
-}
-
-shutdown_t SignalThread::get_shutdown()
-{
- shutdown_t local;
- pthread_mutex_lock(&shutdown_mutex);
- local= __shutdown;
- pthread_mutex_unlock(&shutdown_mutex);
-
- return local;
-}
-
-void SignalThread::post()
-{
- sem_post(&lock);
-}
-
-void SignalThread::test()
-{
- assert(magic_memory == MAGIC_MEMORY);
- assert(sigismember(&set, SIGABRT));
- assert(sigismember(&set, SIGINT));
- assert(sigismember(&set, SIGQUIT));
- assert(sigismember(&set, SIGTERM));
- assert(sigismember(&set, SIGUSR2));
-}
-
-void SignalThread::sighup(signal_callback_fn* arg)
-{
- _sighup= arg;
-}
-
-void SignalThread::sighup()
-{
- if (_sighup)
- {
- _sighup();
- }
-}
-
-SignalThread::~SignalThread()
-{
- if (not is_shutdown())
- {
- set_shutdown(SHUTDOWN_GRACEFUL);
- }
-
-#if 0
- if (pthread_equal(thread, pthread_self()) and (pthread_kill(thread, 0) == ESRCH) == true)
- {
- void *retval;
- pthread_join(thread, &retval);
- }
-#endif
- sem_destroy(&lock);
-}
-
-extern "C" {
-
-static void *sig_thread(void *arg)
-{
- SignalThread *context= (SignalThread*)arg;
-
- context->test();
- context->post();
-
- while (context->get_shutdown() == SHUTDOWN_RUNNING)
- {
- int sig;
-
- if (context->wait(sig) == -1)
- {
- std::cerr << "sigwait() returned errno:" << strerror(errno) << std::endl;
- continue;
- }
-
- switch (sig)
- {
- case SIGUSR2:
- break;
-
- case SIGHUP:
- context->sighup();
- break;
-
- case SIGABRT:
- case SIGINT:
- case SIGQUIT:
- case SIGTERM:
- if (context->is_shutdown() == false)
- {
- context->set_shutdown(SHUTDOWN_FORCED);
- }
-
- if (context->exit_on_signal())
- {
- exit(EXIT_SUCCESS);
- }
-
- break;
-
- default:
- std::cerr << "Signal handling thread got unexpected signal " << strsignal(sig) << std::endl;
- break;
- }
- }
-
- return NULL;
-}
-
-}
-
-SignalThread::SignalThread(bool exit_on_signal_arg) :
- _exit_on_signal(exit_on_signal_arg),
- magic_memory(MAGIC_MEMORY),
- __shutdown(SHUTDOWN_RUNNING),
- thread(pthread_self()),
- _sighup(NULL)
-{
- pthread_mutex_init(&shutdown_mutex, NULL);
- sigemptyset(&set);
-
- sigaddset(&set, SIGABRT);
- sigaddset(&set, SIGINT);
- sigaddset(&set, SIGQUIT);
- sigaddset(&set, SIGTERM);
- sigaddset(&set, SIGUSR2);
-
- sem_init(&lock, 0, 0);
-}
-
-
-bool SignalThread::setup()
-{
- set_shutdown(SHUTDOWN_RUNNING);
-
- int error;
- if ((error= pthread_sigmask(SIG_BLOCK, &set, NULL)))
- {
- std::cerr << "pthread_sigmask() died during pthread_sigmask(" << strerror(error) << ")" << std::endl;
- return false;
- }
-
- if ((error= pthread_create(&thread, NULL, &sig_thread, this)))
- {
- std::cerr << "pthread_create() died during pthread_create(" << strerror(error) << ")" << std::endl;
- return false;
- }
-
- sem_wait(&lock);
-
- return true;
-}
-
-} /* namespace util */
-} /* namespace datadifferential */
+++ /dev/null
-/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- *
- * Data Differential Utility library
- *
- * Copyright (C) 2012 Data Differential, http://datadifferential.com/
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * * The names of its contributors may not be used to endorse or
- * promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#pragma once
-
-#include <pthread.h>
-#include <semaphore.h>
-
-#ifdef HAVE_SIGNAL_H
-#include <signal.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef void (signal_callback_fn)();
-
-#ifdef __cplusplus
-}
-#endif
-
-namespace datadifferential {
-namespace util {
-
-enum shutdown_t {
- SHUTDOWN_RUNNING,
- SHUTDOWN_GRACEFUL,
- SHUTDOWN_FORCED
-};
-
-class SignalThread {
- bool _exit_on_signal;
- sigset_t set;
- sem_t lock;
- uint64_t magic_memory;
- volatile shutdown_t __shutdown;
- pthread_mutex_t shutdown_mutex;
-
-public:
-
- SignalThread(bool exit_on_signal_arg= false);
-
- void test();
- void post();
- bool setup();
-
- bool exit_on_signal()
- {
- return _exit_on_signal;
- }
-
- int wait(int& sig)
- {
- return sigwait(&set, &sig);
- }
-
- ~SignalThread();
-
- void set_shutdown(shutdown_t arg);
- bool is_shutdown();
- shutdown_t get_shutdown();
-
- void sighup();
- void sighup(signal_callback_fn* arg);
-
-private:
- pthread_t thread;
- signal_callback_fn* _sighup;
-};
-
-} /* namespace util */
-} /* namespace datadifferential */
+++ /dev/null
-/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
- *
- * DataDifferential Utility Library
- *
- * Copyright (C) 2011-2013 Data Differential, http://datadifferential.com/
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * * The names of its contributors may not be used to endorse or
- * promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-/*
- Simple defines
-*/
-
-#include <cstring>
-#include <cstddef>
-
-#pragma once
-
-#define util_literal_param(X) (X), (static_cast<size_t>((sizeof(X) - 1)))
-#define util_literal_param_size(X) static_cast<size_t>(sizeof(X) - 1)
-
-#define util_literal_compare_param(X) (static_cast<size_t>((sizeof(X) - 1))), (X)
-
-#define util_string_make_from_cstr(X) (X), ((X) ? strlen(X) : 0)
-
-#define util_string_make_from_array(__array) (__array), (strlen(__array))
-
-#define util_array_length(__array) sizeof(__array)/sizeof(&__array)
-
return()
endif()
+configure_init(${CMAKE_CURRENT_BINARY_DIR}/conf.h)
+configure_append("#define MEMCACHED_BINARY getenv_else(\"MEMCACHED_BINARY\", \"@MEMCACHED_BINARY@\")\n")
+configure_define_string(TESTING_ROOT)
+configure_define_string(SOURCES_ROOT)
+configure_define_string(LIBMEMCACHED_WITH_SASL_PWDB)
+configure_define_string(LIBMEMCACHED_WITH_SASL_CONF)
+
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMake")
include(Catch)
-include(CheckTbb)
-check_decl(pipe2 unistd.h)
-check_decl(SOCK_NONBLOCK sys/socket.h)
-check_decl(SOCK_CLOEXEC sys/socket.h)
-check_header(sys/wait.h)
-check_decl(waitid sys/wait.h)
+add_definitions(-D_GNU_SOURCE)
+set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)
+check_symbol(pipe2 unistd.h)
+check_symbol(SOCK_NONBLOCK sys/socket.h)
+check_symbol(SOCK_CLOEXEC sys/socket.h)
+check_include(sys/wait.h)
+check_symbol(waitid sys/wait.h)
if(HAVE_WAITID)
- check_compiles(HAVE_WAITID_NOWAIT "
- siginfo_t s;
- waitid(P_ALL, 0, &s, WNOWAIT|WEXITED);"
- sys/types.h sys/wait.h)
+ check_c_source("
+ #include <sys/types.h>
+ #include <sys/wait.h>
+ int main() {
+ siginfo_t s;
+ return waitid(P_ALL, 0, &s, WNOWAIT|WEXITED);
+ }"
+ HAVE_WAITID_NOWAIT
+ )
endif()
if(NOT HAVE_SYS_WAIT_H)
message(SEND_ERROR "Could not find header <sys/wait.h>")
set(ENV{INVALID_CONFIGURATION} 1)
endif()
-# parallelism
-if(NOT (thread IN_LIST ENABLE_SANITIZERS))
- check_tbb()
-endif()
-
# memcached(1)
if(NOT MEMCACHED_BINARY)
find_package(Memcached)
endif()
file(GLOB_RECURSE TESTING_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp)
-set(TESTING_ROOT ${CMAKE_CURRENT_BINARY_DIR})
-set(SOURCES_ROOT ${CMAKE_SOURCE_DIR})
+set(TESTING_ROOT "${CMAKE_CURRENT_BINARY_DIR}")
+set(SOURCES_ROOT "${CMAKE_SOURCE_DIR}")
set_source_files_properties(main.cpp PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON)
add_executable(runtests ${TESTING_SRC})
set_target_properties(runtests PROPERTIES CXX_STANDARD 17)
${CMAKE_BINARY_DIR}/src)
target_link_libraries(runtests PRIVATE libhashkit libmemcachedinternal libmemcachedutil)
+# parallelism
+if(NOT (thread IN_LIST ENABLE_SANITIZERS))
+ include(CheckTbb)
+endif()
if(HAVE_TBB)
target_link_libraries(runtests PRIVATE ${LIBTBB})
endif()
add_dependencies(runtests ${CLIENTS})
if(TARGET memaslap)
- set(HAVE_MEMASLAP 1)
+ configure_set(HAVE_MEMASLAP 1)
add_dependencies(runtests memaslap)
endif()
-configure_file(conf.h.in conf.h @ONLY)
+configure_file(${CONFIGURE_FILE_IN} ${CONFIGURE_FILE_OUT} @ONLY)
-catch_discover_tests(runtests
- TEST_SPEC "lib*")
-catch_discover_tests(runtests
- TEST_SPEC "hashkit*")
-catch_discover_tests(runtests
- TEST_SPEC "memcached*")
-catch_discover_tests(runtests
- TEST_SPEC "bin/*")
+catch_discover_tests(runtests TEST_SPEC "lib*,hashkit*,memcached*,bin/*")
+--------------------------------------------------------------------+
*/
+#pragma once
+
#include "test/lib/common.hpp"
#include "libmemcached/common.h"
#include "libmemcachedutil/common.h"