diff --git a/qse/include/qse/si/sck.h b/qse/include/qse/si/sck.h index fadbb696..a8e2b339 100644 --- a/qse/include/qse/si/sck.h +++ b/qse/include/qse/si/sck.h @@ -64,12 +64,19 @@ enum qse_shut_sck_how_t { - QSE_SHUTSCKHND_R = 0, - QSE_SHUTSCKHND_W = 1, - QSE_SHUTSCKHND_RW = 2 + QSE_SHUT_SCK_R = 0, + QSE_SHUT_SCK_W = 1, + QSE_SHUT_SCK_RW = 2 }; typedef enum qse_shut_sck_how_t qse_shut_sck_how_t; +enum qse_sck_trait_t +{ + QSE_SCK_TRAIT_NONBLOCK = (1 << 0), + QSE_SCK_TRAIT_CLOEXEC = (1 << 1) +}; +typedef enum qse_sck_trait_t qse_sck_trait_t; + #if defined(__cplusplus) extern "C" { #endif @@ -78,6 +85,13 @@ QSE_EXPORT int qse_is_sck_valid ( qse_sck_hnd_t handle ); +QSE_EXPORT qse_sck_hnd_t qse_open_sck ( + int family, + int type, + int protocol, + int traits +); + QSE_EXPORT void qse_close_sck ( qse_sck_hnd_t handle ); diff --git a/qse/lib/http/httpd-std.c b/qse/lib/http/httpd-std.c index 68338b76..8fdaf32d 100644 --- a/qse/lib/http/httpd-std.c +++ b/qse/lib/http/httpd-std.c @@ -1202,13 +1202,13 @@ oops: static void client_close (qse_httpd_t* httpd, qse_httpd_client_t* client) { - qse_shut_sck (client->handle, QSE_SHUTSCKHND_RW); + qse_shut_sck (client->handle, QSE_SHUT_SCK_RW); qse_close_sck (client->handle); } static void client_shutdown (qse_httpd_t* httpd, qse_httpd_client_t* client) { - qse_shut_sck (client->handle, QSE_SHUTSCKHND_RW); + qse_shut_sck (client->handle, QSE_SHUT_SCK_RW); } static qse_ssize_t client_recv ( diff --git a/qse/lib/si/Socket.cpp b/qse/lib/si/Socket.cpp index 519e5110..9179852e 100644 --- a/qse/lib/si/Socket.cpp +++ b/qse/lib/si/Socket.cpp @@ -77,7 +77,6 @@ int Socket::fdopen (int handle) QSE_CPP_NOEXCEPT int Socket::open (int domain, int type, int protocol, int traits) QSE_CPP_NOEXCEPT { int x; - int fcntl_v = 0; #if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC) if (traits & Socket::T_NONBLOCK) type |= SOCK_NONBLOCK; @@ -106,24 +105,13 @@ open_socket: if (traits) { - fcntl_v = ::fcntl(x, F_GETFL, 0); - if (fcntl_v == -1) + if (((traits & Socket::T_CLOEXEC) && qse_set_sck_cloexec(x, 1) <= -1) || + ((traits & Socket::T_NONBLOCK) && qse_set_sck_nonblock(x, 1) <= -1)) { - fcntl_failure: this->setErrorFmt (syserr_to_errnum(errno), QSE_T("%hs"), strerror(errno)); ::close (x); return -1; } - - if (traits & Socket::T_NONBLOCK) fcntl_v |= O_NONBLOCK; - else fcntl_v &= ~O_NONBLOCK; - - #if defined(FD_CLOEXEC) - if (traits & Socket::T_CLOEXEC) fcntl_v |= FD_CLOEXEC; - else fcntl_v &= ~FD_CLOEXEC; - #endif - - if (::fcntl(x, F_SETFL, fcntl_v) == -1) goto fcntl_failure; } done: diff --git a/qse/lib/si/sck.c b/qse/lib/si/sck.c index 22a490c8..ce2fdf3b 100644 --- a/qse/lib/si/sck.c +++ b/qse/lib/si/sck.c @@ -95,6 +95,48 @@ QSE_INLINE int qse_is_sck_valid (qse_sck_hnd_t handle) #endif } +qse_sck_hnd_t qse_open_sck (int family, int type, int protocol, int traits) +{ + int x; + +#if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC) + if (traits & QSE_SCK_TRAIT_NONBLOCK) type |= SOCK_NONBLOCK; + if (traits & QSE_SCK_TRAIT_CLOEXEC) type |= SOCK_CLOEXEC; +open_socket: +#endif + x = socket(family, type, protocol); + if (x == -1) + { + #if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC) + if (errno == EINVAL && (type & (SOCK_NONBLOCK | SOCK_CLOEXEC))) + { + type &= ~(SOCK_NONBLOCK | SOCK_CLOEXEC); + goto open_socket; + } + #endif + return -1; + } + else + { + #if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC) + if (type & (SOCK_NONBLOCK | SOCK_CLOEXEC)) goto done; + #endif + } + + if (traits) + { + if (((traits & QSE_SCK_TRAIT_CLOEXEC) && qse_set_sck_cloexec(x, 1) <= -1) || + ((traits & QSE_SCK_TRAIT_NONBLOCK) && qse_set_sck_nonblock(x, 1) <= -1)) + { + close (x); + return -1; + } + } + +done: + return x; +} + QSE_INLINE void qse_close_sck (qse_sck_hnd_t handle) { #if defined(_WIN32) @@ -110,7 +152,7 @@ QSE_INLINE void qse_close_sck (qse_sck_hnd_t handle) t_close (handle); #else - QSE_CLOSE (handle); + close (handle); #endif } @@ -131,13 +173,13 @@ QSE_INLINE void qse_shut_sck (qse_sck_hnd_t handle, qse_shut_sck_how_t how) /* Is this correct? */ switch (how) { - case QSE_SHUTSCKHND_R: + case QSE_SHUT_SCK_R: t_rcvrel (handle); break; - case QSE_SHUTSCKHND_W: + case QSE_SHUT_SCK_W: t_sndrel (handle); break; - case QSE_SHUTSCKHND_RW: + case QSE_SHUT_SCK_RW: t_rcvrel (handle); t_sndrel (handle); break; @@ -188,8 +230,8 @@ int qse_set_sck_cloexec (qse_sck_hnd_t handle, int enabled) return -1; #elif defined(FD_CLOEXEC) - int flag = fcntl(handle, F_GETFL); - if (flag >= 0) flag = fcntl(handle, F_SETFL, (enabled? (flag | FD_CLOEXEC): (flag & ~FD_CLOEXEC))); + int flag = fcntl(handle, F_GETFD); + if (flag >= 0) flag = fcntl(handle, F_SETFD, (enabled? (flag | FD_CLOEXEC): (flag & ~FD_CLOEXEC))); if (flag <= -1) return -1; return 0; #else @@ -406,7 +448,7 @@ void qse_sck_fini (qse_sck_t* sck) #elif defined(__DOS__) close_s (sck->handle) #else - QSE_CLOSE (sck->handle); + close (sck->handle); #endif }