fixed flaws in socket opening functions

This commit is contained in:
hyung-hwan 2022-01-25 08:37:14 +00:00
parent 601707ab40
commit 81c1e4b315
4 changed files with 70 additions and 26 deletions

View File

@ -64,12 +64,19 @@
enum qse_shut_sck_how_t enum qse_shut_sck_how_t
{ {
QSE_SHUTSCKHND_R = 0, QSE_SHUT_SCK_R = 0,
QSE_SHUTSCKHND_W = 1, QSE_SHUT_SCK_W = 1,
QSE_SHUTSCKHND_RW = 2 QSE_SHUT_SCK_RW = 2
}; };
typedef enum qse_shut_sck_how_t qse_shut_sck_how_t; 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) #if defined(__cplusplus)
extern "C" { extern "C" {
#endif #endif
@ -78,6 +85,13 @@ QSE_EXPORT int qse_is_sck_valid (
qse_sck_hnd_t handle 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_EXPORT void qse_close_sck (
qse_sck_hnd_t handle qse_sck_hnd_t handle
); );

View File

@ -1202,13 +1202,13 @@ oops:
static void client_close (qse_httpd_t* httpd, qse_httpd_client_t* client) 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); qse_close_sck (client->handle);
} }
static void client_shutdown (qse_httpd_t* httpd, qse_httpd_client_t* client) 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 ( static qse_ssize_t client_recv (

View File

@ -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 Socket::open (int domain, int type, int protocol, int traits) QSE_CPP_NOEXCEPT
{ {
int x; int x;
int fcntl_v = 0;
#if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC) #if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC)
if (traits & Socket::T_NONBLOCK) type |= SOCK_NONBLOCK; if (traits & Socket::T_NONBLOCK) type |= SOCK_NONBLOCK;
@ -106,24 +105,13 @@ open_socket:
if (traits) if (traits)
{ {
fcntl_v = ::fcntl(x, F_GETFL, 0); if (((traits & Socket::T_CLOEXEC) && qse_set_sck_cloexec(x, 1) <= -1) ||
if (fcntl_v == -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)); this->setErrorFmt (syserr_to_errnum(errno), QSE_T("%hs"), strerror(errno));
::close (x); ::close (x);
return -1; 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: done:

View File

@ -95,6 +95,48 @@ QSE_INLINE int qse_is_sck_valid (qse_sck_hnd_t handle)
#endif #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) QSE_INLINE void qse_close_sck (qse_sck_hnd_t handle)
{ {
#if defined(_WIN32) #if defined(_WIN32)
@ -110,7 +152,7 @@ QSE_INLINE void qse_close_sck (qse_sck_hnd_t handle)
t_close (handle); t_close (handle);
#else #else
QSE_CLOSE (handle); close (handle);
#endif #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? */ /* Is this correct? */
switch (how) switch (how)
{ {
case QSE_SHUTSCKHND_R: case QSE_SHUT_SCK_R:
t_rcvrel (handle); t_rcvrel (handle);
break; break;
case QSE_SHUTSCKHND_W: case QSE_SHUT_SCK_W:
t_sndrel (handle); t_sndrel (handle);
break; break;
case QSE_SHUTSCKHND_RW: case QSE_SHUT_SCK_RW:
t_rcvrel (handle); t_rcvrel (handle);
t_sndrel (handle); t_sndrel (handle);
break; break;
@ -188,8 +230,8 @@ int qse_set_sck_cloexec (qse_sck_hnd_t handle, int enabled)
return -1; return -1;
#elif defined(FD_CLOEXEC) #elif defined(FD_CLOEXEC)
int flag = fcntl(handle, F_GETFL); int flag = fcntl(handle, F_GETFD);
if (flag >= 0) flag = fcntl(handle, F_SETFL, (enabled? (flag | FD_CLOEXEC): (flag & ~FD_CLOEXEC))); if (flag >= 0) flag = fcntl(handle, F_SETFD, (enabled? (flag | FD_CLOEXEC): (flag & ~FD_CLOEXEC)));
if (flag <= -1) return -1; if (flag <= -1) return -1;
return 0; return 0;
#else #else
@ -406,7 +448,7 @@ void qse_sck_fini (qse_sck_t* sck)
#elif defined(__DOS__) #elif defined(__DOS__)
close_s (sck->handle) close_s (sck->handle)
#else #else
QSE_CLOSE (sck->handle); close (sck->handle);
#endif #endif
} }