%% options copyright owner = Dirk Krause copyright year = 2015-xxxx SPDX-License-Identifier: BSD-3-Clause %% module #include "dk4conf.h" #include "dk4sock.h" #if DK4_HAVE_LIMITS_H #ifndef LIMITS_H_INCLUDED #include #define LIMITS_H_INCLUDED 1 #endif #endif #if DK4_HAVE_STDINT_H #ifndef STDINT_H_INCLUDED #if defined(__cplusplus) && (!defined(__STDC_LIMIT_MACROS)) #define __STDC_LIMIT_MACROS 1 #endif #if defined(__cplusplus) && (!defined(__STDC_CONSTANT_MACROS)) #define __STDC_CONSTANT_MACROS 1 #endif #include #define STDINT_H_INCLUDED 1 #endif #endif #if DK4_HAVE_STRING_H #ifndef STRING_H_INCLUDED #include #define STRING_H_INCLUDED 1 #endif #endif #include "dk4numco.h" #if DK4_HAVE_ASSERT_H #ifndef ASSERT_H_INCLUDED #include #define ASSERT_H_INCLUDED 1 #endif #endif $!trace-include int dk4socket_send( dk4_socket_t sock, const void *buf, size_t *pszbuf, int flags, long secs, long usecs, dk4_er_t *erp ) { fd_set wfds; struct timeval to; #if DK4_HAVE_SSIZE_T ssize_t bwr; #else int bwr; #endif int res; int back = DK4_SOCKET_RESULT_FAILED; #if DK4_USE_ASSERT assert(INVALID_SOCKET != sock); assert(NULL != buf); assert(NULL != pszbuf); assert(0 < *pszbuf); #endif if ((INVALID_SOCKET != sock) && (NULL != buf) && (NULL != pszbuf)) { if (0 < *pszbuf) { #if DK4_HAVE_SSIZE_T if ((dk4_um_t)(*pszbuf) <= (dk4_um_t)(SIZE_MAX / 2)) #else if ((dk4_um_t)(*pszbuf) <= (dk4_um_t)(INT_MAX)) #endif { if ((0L != secs) || (0L != usecs)) { /* Timeout, check writability. */ FD_ZERO(&wfds); FD_SET(sock, &wfds); to.tv_sec = secs; to.tv_usec = usecs; dk4socket_error_reset(); res = select(((int)sock + 1), NULL, &wfds, NULL, &to); if (0 < res) { if (FD_ISSET(sock, &wfds)) { back = DK4_SOCKET_RESULT_SUCCESS; } else { /* Timeout */ dk4error_set_simple_error_code(erp, DK4_E_SOCKET_TIMEOUT); } } else { #if DK4_ON_WINDOWS if (SOCKET_ERROR == res) #else if (-1 == res) #endif { /* select error */ dk4socket_error_report(erp, DK4_E_SOCKET_SELECT); } else { /* Timeout */ dk4error_set_simple_error_code(erp, DK4_E_SOCKET_TIMEOUT); } } } else { /* No timeout, can continue sending immediately. */ back = DK4_SOCKET_RESULT_SUCCESS; } if (DK4_SOCKET_RESULT_SUCCESS == back) { back = DK4_SOCKET_RESULT_FAILED; /* Really send. */ dk4socket_error_reset(); #if DK4_ON_WINDOWS bwr = send(sock, buf, (int)(*pszbuf), flags); #else bwr = send(sock, buf, *pszbuf, flags); #endif if (0 <= bwr) { if ((size_t)bwr == *pszbuf) { back = DK4_SOCKET_RESULT_SUCCESS; } else { back = DK4_SOCKET_RESULT_IN_PROGRESS; } *pszbuf = (size_t)bwr; } else { dk4socket_error_report(erp, DK4_E_SOCKET_SEND); *pszbuf = 0; } } else { *pszbuf = 0; } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); *pszbuf = 0; } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); *pszbuf = 0; } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); if (NULL != pszbuf) { *pszbuf = 0; } } return back; } int dk4socket_recv( dk4_socket_t sock, void *buf, size_t *pszbuf, int flags, long secs, long usecs, dk4_er_t *erp ) { fd_set rfds; struct timeval to; #if DK4_HAVE_SSIZE_T ssize_t bwr; #else int bwr; #endif int res; int back = DK4_SOCKET_RESULT_FAILED; #if DK4_USE_ASSERT assert(INVALID_SOCKET != sock); assert(NULL != buf); assert(NULL != pszbuf); assert(0 < *pszbuf); #endif if ((INVALID_SOCKET != sock) && (NULL != buf) && (NULL != pszbuf)) { if (0 < *pszbuf) { #if DK4_HAVE_SSIZE_T if ((dk4_um_t)(*pszbuf) <= (dk4_um_t)(SIZE_MAX / 2)) #else if ((dk4_um_t)(*pszbuf) <= (dk4_um_t)(INT_MAX)) #endif { if ((0L != secs) || (0L != usecs)) { /* Timeout, check readability. */ FD_ZERO(&rfds); FD_SET(sock, &rfds); to.tv_sec = secs; to.tv_usec = usecs; dk4socket_error_reset(); res = select(((int)sock + 1), &rfds, NULL, NULL, &to); if (0 < res) { if (FD_ISSET(sock, &rfds)) { back = DK4_SOCKET_RESULT_SUCCESS; } else { dk4error_set_simple_error_code(erp, DK4_E_SOCKET_TIMEOUT); } } else { #if DK4_ON_WINDOWS if (SOCKET_ERROR == res) #else if (-1 == res) #endif { dk4socket_error_report(erp, DK4_E_SOCKET_SELECT); } else { dk4error_set_simple_error_code(erp, DK4_E_SOCKET_TIMEOUT); } } } else { /* No timeout. */ back = DK4_SOCKET_RESULT_SUCCESS; } if (DK4_SOCKET_RESULT_SUCCESS == back) { back = DK4_SOCKET_RESULT_FAILED; dk4socket_error_reset(); #if DK4_ON_WINDOWS bwr = recv(sock, buf, (int)(*pszbuf), flags); #else bwr = recv(sock, buf, *pszbuf, flags); #endif if (0 <= bwr) { back = DK4_SOCKET_RESULT_SUCCESS; *pszbuf = (size_t)bwr; } else { dk4socket_error_report(erp, DK4_E_SOCKET_RECV); *pszbuf = 0; } } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } return back; }