diff --git a/buffer/buf_test.c b/buffer/buf_test.c index a01700a..83df6f8 100644 --- a/buffer/buf_test.c +++ b/buffer/buf_test.c @@ -279,6 +279,7 @@ size_t __wrap_strlen(const char *s) } bool fail_vsnprintf; +int fail_vsnprintf_value = -1; int fail_vsnprintf_at = -1; extern int __real_vsnprintf(char *str, size_t size, const char *format, va_list ap); @@ -289,7 +290,7 @@ int __wrap_vsnprintf(char *str, size_t size, const char *format, va_list ap) return __real_vsnprintf(str, size, format, ap); } - return -1; + return fail_vsnprintf_value; } void fail_test() @@ -456,6 +457,36 @@ void fail_test() fail_vsnprintf_at = -1; fail_realloc = false; + sc_buf_init(&buf, 3); + fail_vsnprintf_at = 2; + fail_vsnprintf_value = 1000000; + sc_buf_put_text(&buf, "test"); + assert(sc_buf_valid(&buf) == false); + sc_buf_term(&buf); + + sc_buf_init(&buf, 3); + fail_vsnprintf_at = 2; + fail_vsnprintf_value = -1; + sc_buf_put_text(&buf, "test"); + assert(sc_buf_valid(&buf) == false); + sc_buf_term(&buf); + + sc_buf_init(&buf, 3); + fail_vsnprintf_at = 2; + fail_vsnprintf_value = 1000000; + sc_buf_put_fmt(&buf, "%s", "test"); + assert(sc_buf_valid(&buf) == false); + sc_buf_term(&buf); + + fail_vsnprintf_value = -1; + fail_vsnprintf_at = -1; + fail_realloc = false; + + sc_buf_init(&buf, 3); + sc_buf_put_text(&buf, "test"); + assert(sc_buf_valid(&buf) == true); + sc_buf_term(&buf); + } #else void fail_test() diff --git a/buffer/sc_buf.c b/buffer/sc_buf.c index 2837a6f..336a63f 100644 --- a/buffer/sc_buf.c +++ b/buffer/sc_buf.c @@ -739,7 +739,7 @@ void sc_buf_put_text(struct sc_buf *buf, const char *fmt, ...) rc = vsnprintf((char *) sc_buf_wbuf(buf) - offset, quota, fmt, args); va_end(args); - if (rc < 0 || (uint32_t) rc >= quota) { + if (rc < 0 || (uint32_t) rc >= sc_buf_quota(buf)) { sc_buf_set_wpos(buf, 0); buf->error = SC_BUF_OOM; return; diff --git a/logger/CMakeLists.txt b/logger/CMakeLists.txt index 5f09ab7..1ac27e4 100644 --- a/logger/CMakeLists.txt +++ b/logger/CMakeLists.txt @@ -38,7 +38,7 @@ if(SC_BUILD_TEST) target_link_options(${PROJECT_NAME}_test PRIVATE -Wl,--wrap=fprintf,--wrap=vfprintf,--wrap=fopen,--wrap=localtime_r -Wl,--wrap=pthread_mutexattr_init,--wrap=pthread_mutex_init - -Wl,--wrap=fclose) + -Wl,--wrap=fclose,--wrap=ftell) endif () endif () diff --git a/logger/log_test.c b/logger/log_test.c index e2e814e..6c3ca25 100644 --- a/logger/log_test.c +++ b/logger/log_test.c @@ -160,6 +160,17 @@ FILE *__wrap_fopen(const char *filename, const char *mode) return NULL; } +bool mock_ftell = false; +extern long int __real_ftell (FILE *stream); +extern long int __wrap_ftell (FILE *stream) +{ + if (mock_ftell) { + return -1; + } + + return __real_ftell(stream); +} + bool mock_fclose = false; extern int __real_fclose (FILE *__stream); int __wrap_fclose (FILE *__stream) @@ -277,6 +288,10 @@ void fail_test(void) mock_fopen = true; assert(sc_log_set_file("prev.txt", "current.txt") == -1); mock_fopen = false; + mock_ftell = true; + assert(sc_log_set_file("prev.txt", "current.txt") == -1); + mock_ftell = false; + assert(sc_log_set_file("prev.txt", "current.txt") == 0); mock_localtime_r= true; assert(sc_log_error("test") == -1); diff --git a/signal/CMakeLists.txt b/signal/CMakeLists.txt index 7dcd56d..cb8f7b7 100644 --- a/signal/CMakeLists.txt +++ b/signal/CMakeLists.txt @@ -6,9 +6,9 @@ set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_EXTENSIONS OFF) add_library( - sc_signal SHARED - sc_signal.c - sc_signal.h) + sc_signal SHARED + sc_signal.c + sc_signal.h) target_include_directories(sc_signal PUBLIC ${CMAKE_CURRENT_LIST_DIR}) @@ -20,18 +20,18 @@ endif () # --------------------------------------------------------------------------- # # --------------------- Test Configuration Start ---------------------------- # # --------------------------------------------------------------------------- # -if(SC_BUILD_TEST) +if (SC_BUILD_TEST) - include(CTest) - include(CheckCCompilerFlag) + include(CTest) + include(CheckCCompilerFlag) - enable_testing() + enable_testing() - add_executable(${PROJECT_NAME}_test signal_test.c sc_signal.c) + add_executable(${PROJECT_NAME}_test signal_test.c sc_signal.c) - target_compile_options(${PROJECT_NAME}_test PRIVATE -DSC_SIZE_MAX=1400000ul) + target_compile_options(${PROJECT_NAME}_test PRIVATE -DSC_SIZE_MAX=1400000ul) - check_c_source_compiles(" + check_c_source_compiles(" #include #include @@ -42,80 +42,84 @@ if(SC_BUILD_TEST) return 0; }" HAVE_BACKTRACE) - FIND_LIBRARY(EXECINFO_LIBRARY NAMES execinfo) - IF (EXECINFO_LIBRARY) - SET(CMAKE_REQUIRED_LIBRARIES "${EXECINFO_LIBRARY}") - ENDIF(EXECINFO_LIBRARY) + FIND_LIBRARY(EXECINFO_LIBRARY NAMES execinfo) + IF (EXECINFO_LIBRARY) + SET(CMAKE_REQUIRED_LIBRARIES "${EXECINFO_LIBRARY}") + ENDIF (EXECINFO_LIBRARY) - if (${HAVE_BACKTRACE}) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_BACKTRACE") - endif () + if (${HAVE_BACKTRACE}) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_BACKTRACE") + endif () - if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") - if ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR - "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") + if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + if ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR + "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") - target_compile_options(${PROJECT_NAME}_test PRIVATE -fno-omit-frame-pointer) - target_compile_options(${PROJECT_NAME}_test PRIVATE -DSC_HAVE_WRAP -DSC_SIGNAL_TEST) - target_compile_options(${PROJECT_NAME}_test PRIVATE -fno-builtin) - endif () - endif () + target_compile_options(${PROJECT_NAME}_test PRIVATE -fno-omit-frame-pointer) + target_compile_options(${PROJECT_NAME}_test PRIVATE -DSC_HAVE_WRAP -DSC_SIGNAL_TEST) + target_compile_options(${PROJECT_NAME}_test PRIVATE -fno-builtin) + target_link_options(${PROJECT_NAME}_test PRIVATE -Wl,--wrap=signal) - if ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR - "${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang" OR - "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") + endif () + endif () - target_compile_options(${PROJECT_NAME}_test PRIVATE -fno-omit-frame-pointer) + if ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR + "${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang" OR + "${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") - if (SANITIZER) - target_compile_options(${PROJECT_NAME}_test PRIVATE -fsanitize=${SANITIZER}) - target_link_options(${PROJECT_NAME}_test PRIVATE -fsanitize=${SANITIZER}) - endif () - endif () + target_compile_options(${PROJECT_NAME}_test PRIVATE -fno-omit-frame-pointer) + + if (SANITIZER) + target_compile_options(${PROJECT_NAME}_test PRIVATE -fsanitize=${SANITIZER}) + target_link_options(${PROJECT_NAME}_test PRIVATE -fsanitize=${SANITIZER}) + endif () + endif () - add_test(NAME ${PROJECT_NAME}_test COMMAND ${PROJECT_NAME}_test) + add_test(NAME ${PROJECT_NAME}_test COMMAND ${PROJECT_NAME}_test) - SET(MEMORYCHECK_COMMAND_OPTIONS - "-q --log-fd=2 --trace-children=yes --track-origins=yes \ + SET(MEMORYCHECK_COMMAND_OPTIONS + "-q --log-fd=2 --trace-children=yes --track-origins=yes \ --leak-check=full --show-leak-kinds=all \ --error-exitcode=255") - add_custom_target(valgrind_${PROJECT_NAME} ${CMAKE_COMMAND} - -E env CTEST_OUTPUT_ON_FAILURE=1 - ${CMAKE_CTEST_COMMAND} -C $ - --overwrite MemoryCheckCommandOptions=${MEMORYCHECK_COMMAND_OPTIONS} - --verbose -T memcheck WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) + add_custom_target(valgrind_${PROJECT_NAME} ${CMAKE_COMMAND} + -E env CTEST_OUTPUT_ON_FAILURE=1 + ${CMAKE_CTEST_COMMAND} -C $ + --overwrite MemoryCheckCommandOptions=${MEMORYCHECK_COMMAND_OPTIONS} + --verbose -T memcheck WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) - add_custom_target(check_${PROJECT_NAME} ${CMAKE_COMMAND} - -E env CTEST_OUTPUT_ON_FAILURE=1 - ${CMAKE_CTEST_COMMAND} -C $ --verbose - WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) + add_custom_target(check_${PROJECT_NAME} ${CMAKE_COMMAND} + -E env CTEST_OUTPUT_ON_FAILURE=1 + ${CMAKE_CTEST_COMMAND} -C $ --verbose + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) -# ----------------------- - Code Coverage Start ----------------------------- # +# ------------------------- Code Coverage Start ----------------------------- # - if (${CMAKE_BUILD_TYPE} MATCHES "Coverage") - if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") - target_compile_options(${PROJECT_NAME}_test PRIVATE --coverage) - target_link_libraries(${PROJECT_NAME}_test gcov) - else () - message(FATAL_ERROR "Only GCC is supported for coverage") - endif () - endif () + if (${CMAKE_BUILD_TYPE} MATCHES "Coverage") + if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") + target_compile_options(${PROJECT_NAME}_test PRIVATE --coverage) + target_link_libraries(${PROJECT_NAME}_test gcov) + else () + message(FATAL_ERROR "Only GCC is supported for coverage") + endif () + endif () - add_custom_target(coverage_${PROJECT_NAME}) - add_custom_command( - TARGET coverage_${PROJECT_NAME} - COMMAND lcov --capture --directory . - --output-file coverage.info --rc lcov_branch_coverage=1 --rc lcov_excl_br_line='assert' - COMMAND lcov --remove coverage.info '/usr/*' '*example*' '*test*' - --output-file coverage.info --rc lcov_branch_coverage=1 --rc lcov_excl_br_line='assert' - COMMAND lcov --list coverage.info --rc lcov_branch_coverage=1 --rc lcov_excl_br_line='assert' - ) + add_custom_target(coverage_${PROJECT_NAME}) + add_custom_command( + TARGET coverage_${PROJECT_NAME} + COMMAND lcov --capture --directory . + --output-file coverage.info --rc lcov_branch_coverage=1 --rc lcov_excl_br_line='assert' + COMMAND lcov --remove coverage.info '/usr/*' '*example*' '*test*' + --output-file coverage.info --rc lcov_branch_coverage=1 --rc lcov_excl_br_line='assert' + COMMAND lcov --list coverage.info --rc lcov_branch_coverage=1 --rc lcov_excl_br_line='assert' + ) - add_dependencies(coverage_${PROJECT_NAME} check_${PROJECT_NAME}) + add_dependencies(coverage_${PROJECT_NAME} check_${PROJECT_NAME}) # -------------------------- Code Coverage End ------------------------------ # + endif () + # ----------------------- Test Configuration End ---------------------------- # diff --git a/signal/sc_signal.c b/signal/sc_signal.c index 7c465a1..b371813 100644 --- a/signal/sc_signal.c +++ b/signal/sc_signal.c @@ -40,9 +40,9 @@ #if defined(_WIN32) #include - volatile SOCKET sc_signal_shutdown_fd; +volatile SOCKET sc_signal_shutdown_fd; #else - volatile sig_atomic_t sc_signal_shutdown_fd; +volatile sig_atomic_t sc_signal_shutdown_fd; #endif /** @@ -59,14 +59,12 @@ volatile sig_atomic_t sc_signal_will_shutdown; #define get_uint(va, size) \ (size) == 3 ? va_arg(va, unsigned long long) : \ (size) == 2 ? va_arg(va, unsigned long) : \ - (size) == 1 ? va_arg(va, unsigned int) : \ - 0 + va_arg(va, unsigned int) #define get_int(va, size) \ (size) == 3 ? va_arg(va, long long) : \ (size) == 2 ? va_arg(va, long) : \ - (size) == 1 ? va_arg(va, int) : \ - 0 + va_arg(va, int) #define PSIZE sizeof(void *) == sizeof(unsigned long long) ? 3 : 2 @@ -248,32 +246,24 @@ LONG WINAPI sc_signal_on_fatal(PEXCEPTION_POINTERS info) return 0; } -void sc_signal_std_on_fatal(int type) +void sc_signal_std_on_fatal(int sig) { char buf[128]; int fd = sc_signal_log_fd != -1 ? sc_signal_log_fd : _fileno(stderr); - const char *sig_str; + char *sig_str = "unknown signal"; - switch (type) { - case SIGSEGV: + if (sig == SIGSEGV) { sig_str = "SIGSEGV"; - break; - case SIGABRT: + } else if (sig == SIGABRT) { sig_str = "SIGABRT"; - break; - case SIGFPE: + } else if (sig == SIGFPE) { sig_str = "SIGFPE"; - break; - case SIGILL: + } else if (sig == SIGILL) { sig_str = "SIGILL"; - break; - default: - sig_str = "Unknown signal"; - break; } sc_signal_log(fd, buf, sizeof(buf), - "Fatal signal : [%s][%d], shutting down! \n", sig_str, type); + "Fatal signal : [%s][%d], shutting down! \n", sig_str, sig); _Exit(1); } @@ -302,7 +292,7 @@ int sc_signal_init() #else -// clang-format off + // clang-format off #include #include @@ -369,22 +359,19 @@ static void sc_signal_on_shutdown(int sig) int fd = sc_signal_log_fd != -1 ? sc_signal_log_fd : STDOUT_FILENO; char buf[4096], *sig_str = "Shutdown signal"; - switch (sig) { - case SIGINT: + if (sig == SIGINT) { sig_str = "SIGINT"; - break; - case SIGTERM: + } else if (sig == SIGTERM) { sig_str = "SIGTERM"; - break; } sc_signal_log(fd, buf, sizeof(buf), "Received : %s, (%d) \n", sig_str, sig); if (sc_signal_will_shutdown != 0) { sc_signal_log(fd, buf, sizeof(buf), "Forcing shut down! \n"); -#ifdef SC_SIGNAL_TEST + #ifdef SC_SIGNAL_TEST return; -#endif + #endif _Exit(1); } @@ -397,17 +384,17 @@ static void sc_signal_on_shutdown(int sig) sc_signal_log(fd, buf, sizeof(buf), "Failed to send shutdown command, " "shutting down immediately! \n"); -#ifdef SC_SIGNAL_TEST + #ifdef SC_SIGNAL_TEST return; -#endif + #endif _Exit(1); } } else { sc_signal_log(fd, buf, sizeof(buf), "No shutdown handler, shutting down! \n"); -#ifdef SC_SIGNAL_TEST + #ifdef SC_SIGNAL_TEST return; -#endif + #endif _Exit(0); } @@ -423,22 +410,16 @@ static void sc_signal_on_fatal(int sig, siginfo_t *info, void *context) char buf[4096], *sig_str = "unknown signal"; struct sigaction act; - switch (sig) { - case SIGSEGV: + if (sig == SIGSEGV) { sig_str = "SIGSEGV"; - break; - case SIGABRT: + } else if (sig == SIGABRT) { sig_str = "SIGABRT"; - break; - case SIGBUS: + } else if (sig == SIGBUS) { sig_str = "SIGBUS"; - break; - case SIGFPE: + } else if (sig == SIGFPE) { sig_str = "SIGFPE"; - break; - case SIGILL: + } else if (sig == SIGILL) { sig_str = "SIGILL"; - break; } sc_signal_log(fd, buf, sizeof(buf), "\nSignal received : [%d][%s] \n", sig, @@ -493,6 +474,10 @@ int sc_signal_init() rc &= (sigaction(SIGTERM, &action, NULL) == 0); rc &= (sigaction(SIGINT, &action, NULL) == 0); +#ifdef SC_SIGNAL_TEST + rc &= (sigaction(SIGUSR2, &action, NULL) == 0); +#endif + rc &= (sigemptyset(&action.sa_mask) == 0); action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO; action.sa_sigaction = sc_signal_on_fatal; @@ -503,6 +488,10 @@ int sc_signal_init() rc &= (sigaction(SIGFPE, &action, NULL) == 0); rc &= (sigaction(SIGILL, &action, NULL) == 0); +#ifdef SC_SIGNAL_TEST + rc &= (sigaction(SIGSYS, &action, NULL) == 0); +#endif + return rc ? 0 : -1; } diff --git a/signal/signal_test.c b/signal/signal_test.c index 02dd117..63bde6b 100644 --- a/signal/signal_test.c +++ b/signal/signal_test.c @@ -47,12 +47,24 @@ void test2() } #ifdef SC_HAVE_WRAP + #include #include #include #include #include #include +bool fail_signal; +extern void (*__real_signal(int sig, void (*func)(int)))(int); +void (*__wrap_signal(int sig, void (*func)(int)))(int) +{ + if (fail_signal) { + return SIG_ERR; + } + + return __real_signal(sig, func); +} + void sig_handler(int signum) { (void) signum; @@ -85,8 +97,11 @@ void test3() test3x(SIGABRT); test3x(SIGBUS); test3x(SIGFPE); + sc_signal_log_fd = STDOUT_FILENO; test3x(SIGILL); + sc_signal_log_fd = -1; test3x(SIGUSR1); + test3x(SIGSYS); } @@ -106,6 +121,7 @@ void test4x(int signal) } } else { assert(sc_signal_init() == 0); + sc_signal_log_fd = STDOUT_FILENO; sc_signal_shutdown_fd = STDOUT_FILENO; printf("Running child \n"); raise(signal); @@ -119,6 +135,7 @@ void test4() { test4x(SIGINT); test4x(SIGTERM); + test4x(SIGUSR2); } void test5() @@ -217,6 +234,13 @@ void test8() } } +void test9() +{ + fail_signal = true; + assert(sc_signal_init() != 0); + fail_signal = false; +} + #else void test3() { @@ -235,6 +259,10 @@ void test7() } void test8() { +} +void test9() +{ + } #endif @@ -248,6 +276,7 @@ int main() test6(); test7(); test8(); + test9(); return 0; } diff --git a/socket/CMakeLists.txt b/socket/CMakeLists.txt index dd9525c..e72c075 100644 --- a/socket/CMakeLists.txt +++ b/socket/CMakeLists.txt @@ -42,7 +42,8 @@ if(SC_BUILD_TEST) -Wl,--wrap=close,--wrap=malloc,--wrap=realloc,--wrap=epoll_create1 -Wl,--wrap=setsockopt,--wrap=listen,--wrap=fcntl,--wrap=socket -Wl,--wrap=inet_ntop,--wrap=send,--wrap=recv,--wrap=connect - -Wl,--wrap=write,--wrap=read,--wrap=epoll_ctl) + -Wl,--wrap=write,--wrap=read,--wrap=epoll_ctl,--wrap=getsockopt + -Wl,--wrap=epoll_wait,--wrap=getsockname) endif () endif () diff --git a/socket/sock_test.c b/socket/sock_test.c index c13114e..669fec1 100644 --- a/socket/sock_test.c +++ b/socket/sock_test.c @@ -376,7 +376,7 @@ void test1() assert(sc_sock_connect(&sock, "dsadas", "2131", NULL, "50") != 0); assert(sc_sock_connect(&sock, "dsadas", "2131", "s", NULL) != 0); assert(sc_sock_connect(&sock, "127.0.01", "2131", "100.0.0.0", NULL) != 0); - assert(sc_sock_connect(&sock, "127.0.01", "2131", NULL, "9000") != 0); + assert(sc_sock_connect(&sock, "127.0.01", "2131", NULL, "9000") != 0); sc_sock_term(&sock); sc_sock_init(&sock, 0, false, SC_SOCK_INET); @@ -497,7 +497,7 @@ int sc_mutex_init(struct sc_mutex *mtx) // This won't fail as long as we pass correct params. rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); - assert (rc == 0); + assert(rc == 0); // May fail on OOM rc = pthread_mutex_init(&mtx->mtx, &attr); @@ -634,7 +634,7 @@ int __wrap_fcntl(int fd, int cmd, ...) if (test_done) { va_list va; va_start(va, cmd); - void* t = va_arg(va, void*); + void *t = va_arg(va, void *); return __real_fcntl(fd, cmd, t); } @@ -661,6 +661,37 @@ int __wrap_fcntl(int fd, int cmd, ...) return -1; } +int fail_getsockopt; +int fail_getsockopt_result; + +extern int __real_getsockopt(int fd, int level, int optname, + void *restrict optval, socklen_t *restrict optlen); +extern int __wrap_getsockopt(int fd, int level, int optname, + void *restrict optval, socklen_t *restrict optlen) +{ + if (fail_getsockopt) { + *(int *) optval = fail_getsockopt_result; + return fail_getsockopt_result != 0 ? 0 : 10; + } + + return __real_getsockopt(fd, level, optname, optval, optlen); +} + +int fail_epoll_wait; +extern int __real_epoll_wait(int epfd, struct epoll_event *events, + int maxevents, int timeout); +extern int __wrap_epoll_wait(int epfd, struct epoll_event *events, + int maxevents, int timeout) +{ + if (fail_epoll_wait) { + fail_epoll_wait = 0; + errno = EINTR; + return -1; + } + + return __real_epoll_wait(epfd, events, maxevents, timeout); +} + int fail_socket = false; int __real_socket(int domain, int type, int protocol); int __wrap_socket(int domain, int type, int protocol) @@ -768,6 +799,19 @@ int __wrap_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) return __real_epoll_ctl(epfd, op, fd, event); } +int fail_getsockname; +int __real_getsockname (int fd, struct sockaddr * addr, socklen_t * len); +int __wrap_getsockname (int fd, struct sockaddr * addr, socklen_t * len) +{ + if (fail_getsockname) { + struct sockaddr_storage* str = (struct sockaddr_storage*)addr; + str->ss_family = AF_BRIDGE; + return 0; + } + + return __real_getsockname(fd, addr, len); +} + void poll_fail_test() { bool fail; @@ -776,6 +820,11 @@ void poll_fail_test() struct sc_sock_poll poll; struct sc_sock_pipe pipe[301]; + assert(sc_sock_poll_init(&poll) == 0); + fail_epoll_wait = 1; + assert(sc_sock_poll_wait(&poll, 10) == 0); + assert(sc_sock_poll_term(&poll) == 0); + assert(sc_sock_poll_init(&poll) == 0); sc_sock_init(&sock, 0, true, AF_INET); fail_epoll_ctl = true; @@ -1197,6 +1246,14 @@ void sock_fail_test2() sc_sock_print(&client, NULL, 0); fail_inet_ntop = INT32_MAX; assert(sc_sock_term(&client) == 0); + + char buf[128]; + sc_sock_init(&client, 0, false, SC_SOCK_INET); + sc_sock_listen(&client, "127.0.0.1", "8080"); + fail_getsockname = 1; + sc_sock_print(&client, buf, 128); + fail_getsockname = 0; + assert(sc_sock_term(&client) == 0); } void sock_fail_test3() @@ -1272,6 +1329,14 @@ void sock_fail_test3() fail_connect_err = 0; fail_connect = 0; assert(sc_sock_term(&client) == 0); + + sc_sock_init(&client, 0, false, SC_SOCK_INET); + assert(sc_sock_finish_connect(&client) != 0); + fail_getsockopt = 1; + fail_getsockopt_result = -1; + assert(sc_sock_finish_connect(&client) != 0); + fail_getsockopt = 0; + sc_sock_term(&client); } #else diff --git a/string/sc_str.c b/string/sc_str.c index 635f528..dff32f0 100644 --- a/string/sc_str.c +++ b/string/sc_str.c @@ -111,7 +111,7 @@ char *sc_str_create_va(const char *fmt, va_list va) memcpy(str->buf, tmp, str->len + 1); } else { va_copy(args, va); - rc = vsnprintf(str->buf, str->len, fmt, args); + rc = vsnprintf(str->buf, str->len + 1, fmt, args); va_end(args); if (rc < 0 || (uint32_t) rc > str->len) { @@ -272,7 +272,7 @@ void sc_str_token_end(char *str, char **save) return; } - swap(str, (save != NULL && *save != NULL) ? *save : str + strlen(str)); + swap(str, *save); } bool sc_str_trim(char **str, const char *list) diff --git a/string/str_test.c b/string/str_test.c index 43ef3a5..b1e1e29 100644 --- a/string/str_test.c +++ b/string/str_test.c @@ -235,7 +235,27 @@ void test2() fail_vsnprintf_at = -1; fail_vnsprintf_value = -1; + char *x1 = sc_str_create_fmt("%s", tmp); + assert(x1 != NULL); + assert(strcmp(x1, tmp) == 0); + + for (int i =0 ; i < 1499; i++) { + assert(tmp[i] == x1[i]); + } + + sc_str_destroy(x1); free(tmp); + + x1 = NULL; + for (int i = 0; i < 4000; i++) { + sc_str_append_fmt(&x1, "%s", "x"); + } + + for (int i = 0; i < 4000; i++) { + assert(x1[i] == 'x'); + } + assert(sc_str_len(x1) == 4000); + sc_str_destroy(x1); } #endif @@ -298,6 +318,30 @@ void test3() } sc_str_token_end(str, &save); sc_str_destroy(str); + + str = sc_str_create("x,x"); + save = NULL; + sc_str_token_end(str, &save); + sc_str_destroy(str); + + str = sc_str_create("x,x"); + save = NULL; + while ((token = sc_str_token_begin(str, &save, ",")) != NULL) { + assert(strcmp(token, "x") == 0); + break; + } + sc_str_token_end(str, &save); + sc_str_destroy(str); + + str = sc_str_create("x,x"); + save = NULL; + while ((token = sc_str_token_begin(str, &save, ",")) != NULL) { + assert(strcmp(token, "x") == 0); + break; + } + sc_str_token_end(str, &save); + sc_str_token_end(str, &save); + sc_str_destroy(str); } void test4() @@ -360,7 +404,7 @@ void test4() } } - sc_str_token_end(str, NULL); + sc_str_token_end(str, &save); assert(strcmp(str, "tk1;tk2-tk3 tk4 tk5*tk6") == 0); sc_str_destroy(str);