diff --git a/CMakeLists.txt b/CMakeLists.txt index 413ed968d..57044d6bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,6 +98,8 @@ option(WITH_DLT_DAEMON_VSOCK_IPC "Set to ON to enable VSOCK support in daemon" option(WITH_DLT_LIB_VSOCK_IPC "Set to ON to enable VSOCK support in library (DLT_IPC is not used in library)" OFF) set(DLT_VSOCK_PORT "13490" CACHE STRING "VSOCK port number for logging traffic.") +set(DLT_WRITEV_TIMEOUT_SEC "1" CACHE STRING "Set sec timeout for writev to prevent blocking indefinitely") +set(DLT_WRITEV_TIMEOUT_USEC "0" CACHE STRING "Set usec timeout for writev to prevent blocking indefinitely") # RPM settings set(GENIVI_RPM_RELEASE "1") # ${DLT_REVISION}") @@ -135,6 +137,8 @@ include_directories( ) add_definitions(-D_GNU_SOURCE) +add_definitions(-DDLT_WRITEV_TIMEOUT_SEC=${DLT_WRITEV_TIMEOUT_SEC}) +add_definitions(-DDLT_WRITEV_TIMEOUT_USEC=${DLT_WRITEV_TIMEOUT_USEC}) if(NOT DLT_IPC STREQUAL "UNIX_SOCKET" AND NOT DLT_IPC STREQUAL "FIFO") message(FATAL_ERROR "${DLT_IPC} is not a valid value for DLT_IPC") diff --git a/src/daemon/dlt_daemon_client.c b/src/daemon/dlt_daemon_client.c index 9ebbd2390..b256988c1 100644 --- a/src/daemon/dlt_daemon_client.c +++ b/src/daemon/dlt_daemon_client.c @@ -1622,7 +1622,7 @@ void dlt_daemon_control_callsw_cinjection(int sock, /* write to FIFO */ DltReturnValue ret = - dlt_user_log_out3(context->user_handle, &(userheader), sizeof(DltUserHeader), + dlt_user_log_out3_with_timeout(context->user_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgInjection), userbuffer, (size_t) data_length_inject); diff --git a/src/daemon/dlt_daemon_common.c b/src/daemon/dlt_daemon_common.c index 6ba5935dc..c5fcbb1c2 100644 --- a/src/daemon/dlt_daemon_common.c +++ b/src/daemon/dlt_daemon_common.c @@ -1380,7 +1380,7 @@ int dlt_daemon_user_send_log_level(DltDaemon *daemon, DltDaemonContext *context, /* log to FIFO */ errno = 0; - ret = dlt_user_log_out2(context->user_handle, + ret = dlt_user_log_out2_with_timeout(context->user_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgLogLevel)); @@ -1416,7 +1416,7 @@ int dlt_daemon_user_send_log_state(DltDaemon *daemon, DltDaemonApplication *app, logstate.log_state = daemon->connectionState; /* log to FIFO */ - ret = dlt_user_log_out2(app->user_handle, + ret = dlt_user_log_out2_with_timeout(app->user_handle, &(userheader), sizeof(DltUserHeader), &(logstate), sizeof(DltUserControlMsgLogState)); diff --git a/src/shared/dlt_user_shared.c b/src/shared/dlt_user_shared.c index 90b26233e..c6bc4966f 100644 --- a/src/shared/dlt_user_shared.c +++ b/src/shared/dlt_user_shared.c @@ -71,6 +71,7 @@ #include #include /* writev() */ +#include /* timeval */ #include "dlt_user_shared.h" #include "dlt_user_shared_cfg.h" @@ -125,6 +126,28 @@ DltReturnValue dlt_user_log_out2(int handle, void *ptr1, size_t len1, void *ptr2 return DLT_RETURN_OK; } +DltReturnValue dlt_user_log_out2_with_timeout(int handle, void *ptr1, size_t len1, void *ptr2, size_t len2) +{ + if (handle < 0) + /* Invalid handle */ + return DLT_RETURN_ERROR; + + fd_set fds; + FD_ZERO(&fds); + FD_SET(handle, &fds); + + struct timeval tv = { DLT_WRITEV_TIMEOUT_SEC, DLT_WRITEV_TIMEOUT_USEC }; + if (select(handle+1, NULL, &fds, NULL, &tv) < 0) { + return DLT_RETURN_ERROR; + } + + if (FD_ISSET(handle, &fds)) { + return dlt_user_log_out2(handle, ptr1, len1, ptr2, len2); + } else { + return DLT_RETURN_ERROR; + } +} + DltReturnValue dlt_user_log_out3(int handle, void *ptr1, size_t len1, void *ptr2, size_t len2, void *ptr3, size_t len3) { struct iovec iov[3]; @@ -175,4 +198,26 @@ DltReturnValue dlt_user_log_out3(int handle, void *ptr1, size_t len1, void *ptr2 } return DLT_RETURN_OK; -} \ No newline at end of file +} + +DltReturnValue dlt_user_log_out3_with_timeout(int handle, void *ptr1, size_t len1, void *ptr2, size_t len2, void *ptr3, size_t len3) +{ + if (handle < 0) + /* Invalid handle */ + return DLT_RETURN_ERROR; + + fd_set fds; + FD_ZERO(&fds); + FD_SET(handle, &fds); + + struct timeval tv = { DLT_WRITEV_TIMEOUT_SEC, DLT_WRITEV_TIMEOUT_USEC }; + if (select(handle+1, NULL, &fds, NULL, &tv) < 0) { + return DLT_RETURN_ERROR; + } + + if (FD_ISSET(handle, &fds)) { + return dlt_user_log_out3(handle, ptr1, len1, ptr2, len2, ptr3, len3); + } else { + return DLT_RETURN_ERROR; + } +} diff --git a/src/shared/dlt_user_shared.h b/src/shared/dlt_user_shared.h index 5a82cee1b..4417894d1 100644 --- a/src/shared/dlt_user_shared.h +++ b/src/shared/dlt_user_shared.h @@ -211,6 +211,17 @@ int dlt_user_check_userheader(DltUserHeader *userheader); */ DltReturnValue dlt_user_log_out2(int handle, void *ptr1, size_t len1, void *ptr2, size_t len2); +/** + * Atomic write to file descriptor, using vector of 2 elements with a timeout of 1s + * @param handle file descriptor + * @param ptr1 generic pointer to first segment of data to be written + * @param len1 length of first segment of data to be written + * @param ptr2 generic pointer to second segment of data to be written + * @param len2 length of second segment of data to be written + * @return Value from DltReturnValue enum + */ +DltReturnValue dlt_user_log_out2_with_timeout(int handle, void *ptr1, size_t len1, void *ptr2, size_t len2); + /** * Atomic write to file descriptor, using vector of 3 elements * @param handle file descriptor @@ -224,4 +235,18 @@ DltReturnValue dlt_user_log_out2(int handle, void *ptr1, size_t len1, void *ptr2 */ DltReturnValue dlt_user_log_out3(int handle, void *ptr1, size_t len1, void *ptr2, size_t len2, void *ptr3, size_t len3); +/** + * Atomic write to file descriptor, using vector of 3 elements with a timeout of 1s + * @param handle file descriptor + * @param ptr1 generic pointer to first segment of data to be written + * @param len1 length of first segment of data to be written + * @param ptr2 generic pointer to second segment of data to be written + * @param len2 length of second segment of data to be written + * @param ptr3 generic pointer to third segment of data to be written + * @param len3 length of third segment of data to be written + * @return Value from DltReturnValue enum + */ +DltReturnValue dlt_user_log_out3_with_timeout(int handle, void *ptr1, size_t len1, void *ptr2, size_t len2, void *ptr3, size_t len3); + + #endif /* DLT_USER_SHARED_H */