corrected wrong use of O_CLOEXEC and FD_CLOEXEC in some files

This commit is contained in:
hyung-hwan 2018-10-22 03:46:19 +00:00
parent 54cd5401d5
commit ea85e91391
12 changed files with 257 additions and 179 deletions

View File

@ -201,7 +201,7 @@ static qse_sck_hnd_t open_server_socket (int proto, const qse_nwad_t* bindnwad)
} }
s = socket (family, type, proto); s = socket (family, type, proto);
if (!qse_isvalidsckhnd(s)) if (!qse_is_sck_valid(s))
{ {
qse_fprintf (QSE_STDERR, QSE_T("cannot create a socket\n")); qse_fprintf (QSE_STDERR, QSE_T("cannot create a socket\n"));
goto oops; goto oops;
@ -279,7 +279,7 @@ bind_ok:
return s; return s;
oops: oops:
if (qse_isvalidsckhnd(s)) qse_closesckhnd (s); if (qse_is_sck_valid(s)) qse_close_sck (s);
return QSE_INVALID_SCKHND; return QSE_INVALID_SCKHND;
} }
@ -879,7 +879,7 @@ oops:
for (i = 0; i < npios; i++) stop_rewriter (ursd, &ursd->rewriters[i]); for (i = 0; i < npios; i++) stop_rewriter (ursd, &ursd->rewriters[i]);
QSE_MMGR_FREE (ursd->mmgr, ursd->rewriters); QSE_MMGR_FREE (ursd->mmgr, ursd->rewriters);
} }
if (qse_isvalidsckhnd(ursd->sck)) qse_closesckhnd (ursd->sck); if (qse_is_sck_valid(ursd->sck)) qse_close_sck (ursd->sck);
if (ursd->mux) qse_mux_close (ursd->mux); if (ursd->mux) qse_mux_close (ursd->mux);
if (ursd->cmdline) QSE_MMGR_FREE(ursd->mmgr, ursd->cmdline); if (ursd->cmdline) QSE_MMGR_FREE(ursd->mmgr, ursd->cmdline);
@ -897,7 +897,7 @@ static void fini_ursd (ursd_t* ursd)
QSE_MMGR_FREE (ursd->mmgr, ursd->rewriters); QSE_MMGR_FREE (ursd->mmgr, ursd->rewriters);
delete_from_mux (ursd->mux, ursd->sck, TYPE_SOCKET, 0); delete_from_mux (ursd->mux, ursd->sck, TYPE_SOCKET, 0);
qse_closesckhnd (ursd->sck); qse_close_sck (ursd->sck);
qse_mux_close (ursd->mux); qse_mux_close (ursd->mux);
QSE_MMGR_FREE (ursd->mmgr, ursd->cmdline); QSE_MMGR_FREE (ursd->mmgr, ursd->cmdline);

View File

@ -1,3 +1,29 @@
/*
* $Id$
*
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _QSE_SI_NETLINK_H_ #ifndef _QSE_SI_NETLINK_H_
#define _QSE_SI_NETLINK_H_ #define _QSE_SI_NETLINK_H_
@ -26,15 +52,6 @@ typedef int (*qse_nlenum_cb_t) (
extern "C" { extern "C" {
#endif #endif
QSE_EXPORT int qse_nlenum (
int fd,
unsigned int seq,
int type,
int af,
qse_nlenum_cb_t cb,
void* ctx
);
QSE_EXPORT int qse_nlenum_route ( QSE_EXPORT int qse_nlenum_route (
int link_af, int link_af,
int addr_af, int addr_af,

View File

@ -62,43 +62,48 @@
typedef int qse_sck_len_t; typedef int qse_sck_len_t;
#endif #endif
enum qse_shutsckhnd_how_t enum qse_shut_sck_how_t
{ {
QSE_SHUTSCKHND_R = 0, QSE_SHUTSCKHND_R = 0,
QSE_SHUTSCKHND_W = 1, QSE_SHUTSCKHND_W = 1,
QSE_SHUTSCKHND_RW = 2 QSE_SHUTSCKHND_RW = 2
}; };
typedef enum qse_shutsckhnd_how_t qse_shutsckhnd_how_t; typedef enum qse_shut_sck_how_t qse_shut_sck_how_t;
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { extern "C" {
#endif #endif
QSE_EXPORT int qse_isvalidsckhnd ( QSE_EXPORT int qse_is_sck_valid (
qse_sck_hnd_t handle qse_sck_hnd_t handle
); );
QSE_EXPORT void qse_closesckhnd ( QSE_EXPORT void qse_close_sck (
qse_sck_hnd_t handle qse_sck_hnd_t handle
); );
QSE_EXPORT void qse_shutsckhnd ( QSE_EXPORT void qse_shut_sck (
qse_sck_hnd_t handle, qse_sck_hnd_t handle,
qse_shutsckhnd_how_t how qse_shut_sck_how_t how
); );
QSE_EXPORT int qse_setscknonblock ( QSE_EXPORT int qse_set_sck_nonblock (
qse_sck_hnd_t handle, qse_sck_hnd_t handle,
int enabled int enabled
); );
QSE_EXPORT int qse_initsckconn ( QSE_EXPORT int qse_set_sck_cloexec (
qse_sck_hnd_t handle,
int enabled
);
QSE_EXPORT int qse_init_sck_conn (
qse_sck_hnd_t handle, qse_sck_hnd_t handle,
const qse_nwad_t* nwad const qse_nwad_t* nwad
); );
QSE_EXPORT int qse_finisckconn ( QSE_EXPORT int qse_fini_sck_conn (
qse_sck_hnd_t handle qse_sck_hnd_t handle
); );

View File

@ -141,7 +141,7 @@ static int urs_open (qse_httpd_t* httpd, qse_httpd_urs_t* urs)
urs->handle[2] = open_client_socket (httpd, AF_UNIX, type, 0); urs->handle[2] = open_client_socket (httpd, AF_UNIX, type, 0);
#endif #endif
if (qse_isvalidsckhnd(urs->handle[2])) if (qse_is_sck_valid(urs->handle[2]))
{ {
#if defined(AF_UNIX) #if defined(AF_UNIX)
qse_ntime_t now; qse_ntime_t now;
@ -160,15 +160,15 @@ static int urs_open (qse_httpd_t* httpd, qse_httpd_urs_t* urs)
if (bind (urs->handle[2], (struct sockaddr*)&dc->unix_bind_addr, QSE_SIZEOF(dc->unix_bind_addr)) <= -1) if (bind (urs->handle[2], (struct sockaddr*)&dc->unix_bind_addr, QSE_SIZEOF(dc->unix_bind_addr)) <= -1)
{ {
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM()); qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
qse_closesckhnd (urs->handle[2]); qse_close_sck (urs->handle[2]);
urs->handle[2] = QSE_INVALID_SCKHND; urs->handle[2] = QSE_INVALID_SCKHND;
} }
#endif #endif
} }
if (!qse_isvalidsckhnd(urs->handle[0]) && if (!qse_is_sck_valid(urs->handle[0]) &&
!qse_isvalidsckhnd(urs->handle[1]) && !qse_is_sck_valid(urs->handle[1]) &&
!qse_isvalidsckhnd(urs->handle[2])) !qse_is_sck_valid(urs->handle[2]))
{ {
/* don't set the error number here. /* don't set the error number here.
* open_client_socket() or bind() above should set the error number */ * open_client_socket() or bind() above should set the error number */
@ -207,26 +207,26 @@ static int urs_open (qse_httpd_t* httpd, qse_httpd_urs_t* urs)
if (proto == IPPROTO_SCTP) if (proto == IPPROTO_SCTP)
{ {
/* TODO: error handling */ /* TODO: error handling */
if (qse_isvalidsckhnd(urs->handle[0])) listen (urs->handle[0], 99); if (qse_is_sck_valid(urs->handle[0])) listen (urs->handle[0], 99);
if (qse_isvalidsckhnd(urs->handle[1])) listen (urs->handle[1], 99); if (qse_is_sck_valid(urs->handle[1])) listen (urs->handle[1], 99);
/* handle[2] is a unix socket. no special handling for SCTP */ /* handle[2] is a unix socket. no special handling for SCTP */
} }
#endif #endif
urs->handle_count = 3; urs->handle_count = 3;
if (qse_isvalidsckhnd(urs->handle[0])) urs->handle_mask |= (1 << 0); if (qse_is_sck_valid(urs->handle[0])) urs->handle_mask |= (1 << 0);
if (qse_isvalidsckhnd(urs->handle[1])) urs->handle_mask |= (1 << 1); if (qse_is_sck_valid(urs->handle[1])) urs->handle_mask |= (1 << 1);
if (qse_isvalidsckhnd(urs->handle[2])) urs->handle_mask |= (1 << 2); if (qse_is_sck_valid(urs->handle[2])) urs->handle_mask |= (1 << 2);
urs->ctx = dc; urs->ctx = dc;
return 0; return 0;
oops: oops:
if (qse_isvalidsckhnd(urs->handle[0])) qse_closesckhnd (urs->handle[0]); if (qse_is_sck_valid(urs->handle[0])) qse_close_sck (urs->handle[0]);
if (qse_isvalidsckhnd(urs->handle[1])) qse_closesckhnd (urs->handle[1]); if (qse_is_sck_valid(urs->handle[1])) qse_close_sck (urs->handle[1]);
if (qse_isvalidsckhnd(urs->handle[2])) if (qse_is_sck_valid(urs->handle[2]))
{ {
qse_closesckhnd (urs->handle[2]); qse_close_sck (urs->handle[2]);
#if defined(AF_UNIX) #if defined(AF_UNIX)
QSE_UNLINK (dc->unix_bind_addr.sun_path); QSE_UNLINK (dc->unix_bind_addr.sun_path);
#endif #endif
@ -264,11 +264,11 @@ static void urs_close (qse_httpd_t* httpd, qse_httpd_urs_t* urs)
QSE_ASSERT (dc->req_count == 0); QSE_ASSERT (dc->req_count == 0);
if (qse_isvalidsckhnd(urs->handle[0])) qse_closesckhnd (urs->handle[0]); if (qse_is_sck_valid(urs->handle[0])) qse_close_sck (urs->handle[0]);
if (qse_isvalidsckhnd(urs->handle[1])) qse_closesckhnd (urs->handle[1]); if (qse_is_sck_valid(urs->handle[1])) qse_close_sck (urs->handle[1]);
if (qse_isvalidsckhnd(urs->handle[2])) if (qse_is_sck_valid(urs->handle[2]))
{ {
qse_closesckhnd (urs->handle[2]); qse_close_sck (urs->handle[2]);
#if defined(AF_UNIX) #if defined(AF_UNIX)
QSE_UNLINK (dc->unix_bind_addr.sun_path); QSE_UNLINK (dc->unix_bind_addr.sun_path);
#endif #endif

View File

@ -830,7 +830,7 @@ static qse_sck_hnd_t open_client_socket (qse_httpd_t* httpd, int domain, int typ
int flag; int flag;
fd = socket (domain, type, proto); fd = socket (domain, type, proto);
if (!qse_isvalidsckhnd(fd)) if (!qse_is_sck_valid(fd))
{ {
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM()); qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
goto oops; goto oops;
@ -871,7 +871,7 @@ static qse_sck_hnd_t open_client_socket (qse_httpd_t* httpd, int domain, int typ
#endif #endif
*/ */
if (qse_setscknonblock (fd, 1) <= -1) if (qse_set_sck_nonblock (fd, 1) <= -1)
{ {
qse_httpd_seterrnum (httpd, QSE_HTTPD_ESYSERR); qse_httpd_seterrnum (httpd, QSE_HTTPD_ESYSERR);
goto oops; goto oops;
@ -912,7 +912,7 @@ static qse_sck_hnd_t open_client_socket (qse_httpd_t* httpd, int domain, int typ
return fd; return fd;
oops: oops:
if (qse_isvalidsckhnd(fd)) qse_closesckhnd (fd); if (qse_is_sck_valid(fd)) qse_close_sck (fd);
return QSE_INVALID_SCKHND; return QSE_INVALID_SCKHND;
} }
@ -933,7 +933,7 @@ static int server_open (qse_httpd_t* httpd, qse_httpd_server_t* server)
} }
fd = socket (qse_skadfamily(&addr), SOCK_STREAM, IPPROTO_TCP); fd = socket (qse_skadfamily(&addr), SOCK_STREAM, IPPROTO_TCP);
if (!qse_isvalidsckhnd(fd)) if (!qse_is_sck_valid(fd))
{ {
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM()); qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
goto oops; goto oops;
@ -1078,7 +1078,7 @@ bind_ok:
goto oops; goto oops;
} }
if (qse_setscknonblock (fd, 1) <= -1) if (qse_set_sck_nonblock (fd, 1) <= -1)
{ {
qse_httpd_seterrnum (httpd, QSE_HTTPD_ESYSERR); qse_httpd_seterrnum (httpd, QSE_HTTPD_ESYSERR);
goto oops; goto oops;
@ -1088,13 +1088,13 @@ bind_ok:
return 0; return 0;
oops: oops:
if (qse_isvalidsckhnd(fd)) qse_closesckhnd (fd); if (qse_is_sck_valid(fd)) qse_close_sck (fd);
return -1; return -1;
} }
static void server_close (qse_httpd_t* httpd, qse_httpd_server_t* server) static void server_close (qse_httpd_t* httpd, qse_httpd_server_t* server)
{ {
qse_closesckhnd (server->handle); qse_close_sck (server->handle);
} }
static int server_accept ( static int server_accept (
@ -1107,7 +1107,7 @@ static int server_accept (
addrlen = QSE_SIZEOF(addr); addrlen = QSE_SIZEOF(addr);
fd = accept (server->handle, (struct sockaddr*)&addr, &addrlen); fd = accept (server->handle, (struct sockaddr*)&addr, &addrlen);
if (!qse_isvalidsckhnd(fd)) if (!qse_is_sck_valid(fd))
{ {
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM()); qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
goto oops; goto oops;
@ -1128,7 +1128,7 @@ static int server_accept (
if (flag >= 0) fcntl (fd, F_SETFD, flag | FD_CLOEXEC); if (flag >= 0) fcntl (fd, F_SETFD, flag | FD_CLOEXEC);
#endif #endif
if (qse_setscknonblock (fd, 1) <= -1) if (qse_set_sck_nonblock (fd, 1) <= -1)
{ {
qse_httpd_seterrnum (httpd, QSE_HTTPD_ESYSERR); qse_httpd_seterrnum (httpd, QSE_HTTPD_ESYSERR);
goto oops; goto oops;
@ -1194,7 +1194,7 @@ static int server_accept (
return 0; return 0;
oops: oops:
if (qse_isvalidsckhnd(fd)) qse_closesckhnd (fd); if (qse_is_sck_valid(fd)) qse_close_sck (fd);
return -1; return -1;
} }
@ -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_shutsckhnd (client->handle, QSE_SHUTSCKHND_RW); qse_shut_sck (client->handle, QSE_SHUTSCKHND_RW);
qse_closesckhnd (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_shutsckhnd (client->handle, QSE_SHUTSCKHND_RW); qse_shut_sck (client->handle, QSE_SHUTSCKHND_RW);
} }
static qse_ssize_t client_recv ( static qse_ssize_t client_recv (
@ -1424,7 +1424,7 @@ static int peer_open (qse_httpd_t* httpd, qse_httpd_peer_t* peer)
bindaddrsize = qse_nwadtoskad (&peer->local, &bindaddr); bindaddrsize = qse_nwadtoskad (&peer->local, &bindaddr);
fd = socket (qse_skadfamily(&connaddr), SOCK_STREAM, IPPROTO_TCP); fd = socket (qse_skadfamily(&connaddr), SOCK_STREAM, IPPROTO_TCP);
if (!qse_isvalidsckhnd(fd)) if (!qse_is_sck_valid(fd))
{ {
qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM()); qse_httpd_seterrnum (httpd, SKERR_TO_ERRNUM());
goto oops; goto oops;
@ -1456,7 +1456,7 @@ static int peer_open (qse_httpd_t* httpd, qse_httpd_peer_t* peer)
if (flag >= 0) fcntl (fd, F_SETFD, flag | FD_CLOEXEC); if (flag >= 0) fcntl (fd, F_SETFD, flag | FD_CLOEXEC);
#endif #endif
if (qse_setscknonblock (fd, 1) <= -1) if (qse_set_sck_nonblock (fd, 1) <= -1)
{ {
qse_httpd_seterrnum (httpd, QSE_HTTPD_ESYSERR); qse_httpd_seterrnum (httpd, QSE_HTTPD_ESYSERR);
goto oops; goto oops;
@ -1561,7 +1561,7 @@ oops:
#if defined(USE_SSL) #if defined(USE_SSL)
if (ssl) SSL_free (ssl); if (ssl) SSL_free (ssl);
#endif #endif
if (qse_isvalidsckhnd(fd)) qse_closesckhnd (fd); if (qse_is_sck_valid(fd)) qse_close_sck (fd);
return -1; return -1;
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
@ -1575,7 +1575,7 @@ static void peer_close (qse_httpd_t* httpd, qse_httpd_peer_t* peer)
SSL_free (HANDLE_TO_SSL(peer->handle2)); SSL_free (HANDLE_TO_SSL(peer->handle2));
#endif #endif
} }
qse_closesckhnd (peer->handle); qse_close_sck (peer->handle);
} }
static int is_peer_socket_connected (qse_httpd_t* httpd, qse_httpd_peer_t* peer) static int is_peer_socket_connected (qse_httpd_t* httpd, qse_httpd_peer_t* peer)

View File

@ -116,9 +116,9 @@ open_socket:
if (traits & Socket::T_NONBLOCK) fcntl_v |= O_NONBLOCK; if (traits & Socket::T_NONBLOCK) fcntl_v |= O_NONBLOCK;
else fcntl_v &= ~O_NONBLOCK; else fcntl_v &= ~O_NONBLOCK;
#if defined(O_CLOEXEC) #if defined(FD_CLOEXEC)
if (traits & Socket::T_CLOEXEC) fcntl_v |= O_CLOEXEC; if (traits & Socket::T_CLOEXEC) fcntl_v |= FD_CLOEXEC;
else fcntl_v &= ~O_CLOEXEC; else fcntl_v &= ~FD_CLOEXEC;
#endif #endif
if (::fcntl(x, F_SETFL, fcntl_v) == -1) goto fcntl_failure; if (::fcntl(x, F_SETFL, fcntl_v) == -1) goto fcntl_failure;
@ -146,7 +146,7 @@ void Socket::close () QSE_CPP_NOEXCEPT
{ {
if (this->handle != QSE_INVALID_SCKHND) if (this->handle != QSE_INVALID_SCKHND)
{ {
qse_closesckhnd (this->handle); qse_close_sck (this->handle);
this->handle = QSE_INVALID_SCKHND; this->handle = QSE_INVALID_SCKHND;
this->domain = -1; this->domain = -1;
} }
@ -154,16 +154,16 @@ void Socket::close () QSE_CPP_NOEXCEPT
int Socket::getOption (int level, int optname, void* optval, qse_sck_len_t* optlen) QSE_CPP_NOEXCEPT int Socket::getOption (int level, int optname, void* optval, qse_sck_len_t* optlen) QSE_CPP_NOEXCEPT
{ {
QSE_ASSERT (this->handle != QSE_INVALID_SCKHND); QSE_ASSERT (qse_is_sck_valid(this->handle));
int n = ::getsockopt (this->handle, level, optname, (char*)optval, optlen); int n = ::getsockopt(this->handle, level, optname, (char*)optval, optlen);
if (n == -1) this->setErrorCode (syserr_to_errnum(errno)); if (n == -1) this->setErrorCode (syserr_to_errnum(errno));
return n; return n;
} }
int Socket::setOption (int level, int optname, const void* optval, qse_sck_len_t optlen) QSE_CPP_NOEXCEPT int Socket::setOption (int level, int optname, const void* optval, qse_sck_len_t optlen) QSE_CPP_NOEXCEPT
{ {
QSE_ASSERT (this->handle != QSE_INVALID_SCKHND); QSE_ASSERT (qse_is_sck_valid(this->handle));
int n = ::setsockopt (this->handle, level, optname, (const char*)optval, optlen); int n = ::setsockopt(this->handle, level, optname, (const char*)optval, optlen);
if (n == -1) this->setErrorCode (syserr_to_errnum(errno)); if (n == -1) this->setErrorCode (syserr_to_errnum(errno));
return n; return n;
} }
@ -284,7 +284,7 @@ int Socket::shutdown (int how) QSE_CPP_NOEXCEPT
int Socket::connect (const SocketAddress& target) QSE_CPP_NOEXCEPT int Socket::connect (const SocketAddress& target) QSE_CPP_NOEXCEPT
{ {
QSE_ASSERT (this->handle != QSE_INVALID_SCKHND); QSE_ASSERT (qse_is_sck_valid(this->handle));
if (::connect(this->handle, (struct sockaddr*)target.getAddrPtr(), target.getAddrSize()) == -1) if (::connect(this->handle, (struct sockaddr*)target.getAddrPtr(), target.getAddrSize()) == -1)
{ {
@ -297,7 +297,7 @@ int Socket::connect (const SocketAddress& target) QSE_CPP_NOEXCEPT
int Socket::bind (const SocketAddress& target) QSE_CPP_NOEXCEPT int Socket::bind (const SocketAddress& target) QSE_CPP_NOEXCEPT
{ {
QSE_ASSERT (this->handle != QSE_INVALID_SCKHND); QSE_ASSERT (qse_is_sck_valid(this->handle));
if (::bind(this->handle, (struct sockaddr*)target.getAddrPtr(), target.getAddrSize()) == -1) if (::bind(this->handle, (struct sockaddr*)target.getAddrPtr(), target.getAddrSize()) == -1)
{ {
@ -375,7 +375,7 @@ int Socket::bindToIfce (const qse_wchar_t* ifce) QSE_CPP_NOEXCEPT
int Socket::listen (int backlog) QSE_CPP_NOEXCEPT int Socket::listen (int backlog) QSE_CPP_NOEXCEPT
{ {
QSE_ASSERT (this->handle != QSE_INVALID_SCKHND); QSE_ASSERT (qse_is_sck_valid(this->handle));
if (::listen(this->handle, backlog) == -1) if (::listen(this->handle, backlog) == -1)
{ {
@ -391,7 +391,7 @@ int Socket::accept (Socket* newsck, SocketAddress* newaddr, int traits) QSE_CPP_
int newfd, flag_v; int newfd, flag_v;
qse_sklen_t addrlen; qse_sklen_t addrlen;
QSE_ASSERT (this->handle != QSE_INVALID_SCKHND); QSE_ASSERT (qse_is_sck_valid(this->handle));
#if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC) && defined(HAVE_ACCEPT4) #if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC) && defined(HAVE_ACCEPT4)
@ -440,9 +440,9 @@ int Socket::accept (Socket* newsck, SocketAddress* newaddr, int traits) QSE_CPP_
if (traits & Socket::T_NONBLOCK) flag_v |= O_NONBLOCK; if (traits & Socket::T_NONBLOCK) flag_v |= O_NONBLOCK;
else flag_v &= ~O_NONBLOCK; else flag_v &= ~O_NONBLOCK;
#if defined(O_CLOEXEC) #if defined(FD_CLOEXEC)
if (traits & Socket::T_CLOEXEC) flag_v |= O_CLOEXEC; if (traits & Socket::T_CLOEXEC) flag_v |= FD_CLOEXEC;
else flag_v &= ~O_CLOEXEC; else flag_v &= ~FD_CLOEXEC;
#endif #endif
if (::fcntl(newfd, F_SETFL, flag_v) == -1) goto fcntl_failure; if (::fcntl(newfd, F_SETFL, flag_v) == -1) goto fcntl_failure;
@ -456,7 +456,7 @@ accept_done:
qse_ssize_t Socket::send (const void* buf, qse_size_t len) QSE_CPP_NOEXCEPT qse_ssize_t Socket::send (const void* buf, qse_size_t len) QSE_CPP_NOEXCEPT
{ {
QSE_ASSERT (this->handle != QSE_INVALID_SCKHND); QSE_ASSERT (qse_is_sck_valid(this->handle));
qse_ssize_t n = ::send(this->handle, buf, len, 0); qse_ssize_t n = ::send(this->handle, buf, len, 0);
if (n == -1) if (n == -1)
@ -470,7 +470,7 @@ qse_ssize_t Socket::send (const void* buf, qse_size_t len) QSE_CPP_NOEXCEPT
qse_ssize_t Socket::send (const void* buf, qse_size_t len, const SocketAddress& dstaddr) QSE_CPP_NOEXCEPT qse_ssize_t Socket::send (const void* buf, qse_size_t len, const SocketAddress& dstaddr) QSE_CPP_NOEXCEPT
{ {
QSE_ASSERT (this->handle != QSE_INVALID_SCKHND); QSE_ASSERT (qse_is_sck_valid(this->handle));
qse_ssize_t n = ::sendto(this->handle, buf, len, 0, (struct sockaddr*)dstaddr.getAddrPtr(), dstaddr.getAddrSize()); qse_ssize_t n = ::sendto(this->handle, buf, len, 0, (struct sockaddr*)dstaddr.getAddrPtr(), dstaddr.getAddrSize());
if (n == -1) if (n == -1)
@ -484,7 +484,7 @@ qse_ssize_t Socket::send (const void* buf, qse_size_t len, const SocketAddress&
int Socket::sendx (const void* buf, qse_size_t len, qse_size_t* total_sent) QSE_CPP_NOEXCEPT int Socket::sendx (const void* buf, qse_size_t len, qse_size_t* total_sent) QSE_CPP_NOEXCEPT
{ {
QSE_ASSERT (this->handle != QSE_INVALID_SCKHND); QSE_ASSERT (qse_is_sck_valid(this->handle));
qse_size_t pos = 0; qse_size_t pos = 0;
@ -507,7 +507,7 @@ int Socket::sendx (const void* buf, qse_size_t len, qse_size_t* total_sent) QSE_
int Socket::sendx (const void* buf, qse_size_t len, const SocketAddress& dstaddr, qse_size_t* total_sent) QSE_CPP_NOEXCEPT int Socket::sendx (const void* buf, qse_size_t len, const SocketAddress& dstaddr, qse_size_t* total_sent) QSE_CPP_NOEXCEPT
{ {
QSE_ASSERT (this->handle != QSE_INVALID_SCKHND); QSE_ASSERT (qse_is_sck_valid(this->handle));
qse_size_t pos = 0; qse_size_t pos = 0;
@ -530,7 +530,7 @@ int Socket::sendx (const void* buf, qse_size_t len, const SocketAddress& dstaddr
int Socket::sendx (qse_ioptl_t* iov, int count, qse_size_t* total_sent) QSE_CPP_NOEXCEPT int Socket::sendx (qse_ioptl_t* iov, int count, qse_size_t* total_sent) QSE_CPP_NOEXCEPT
{ {
QSE_ASSERT (this->handle != QSE_INVALID_SCKHND); QSE_ASSERT (qse_is_sck_valid(this->handle));
#if defined(HAVE_SENDMSG) || defined(HAVE_WRITEV) #if defined(HAVE_SENDMSG) || defined(HAVE_WRITEV)
int index = 0; int index = 0;
@ -629,7 +629,7 @@ int Socket::sendx (qse_ioptl_t* iov, int count, qse_size_t* total_sent) QSE_CPP_
qse_ssize_t Socket::receive (void* buf, qse_size_t len) QSE_CPP_NOEXCEPT qse_ssize_t Socket::receive (void* buf, qse_size_t len) QSE_CPP_NOEXCEPT
{ {
QSE_ASSERT (this->handle != QSE_INVALID_SCKHND); QSE_ASSERT (qse_is_sck_valid(this->handle));
qse_ssize_t n = ::recv(this->handle, buf, len, 0); qse_ssize_t n = ::recv(this->handle, buf, len, 0);
if (n == -1) if (n == -1)
@ -643,7 +643,7 @@ qse_ssize_t Socket::receive (void* buf, qse_size_t len) QSE_CPP_NOEXCEPT
qse_ssize_t Socket::receive (void* buf, qse_size_t len, SocketAddress& srcaddr) QSE_CPP_NOEXCEPT qse_ssize_t Socket::receive (void* buf, qse_size_t len, SocketAddress& srcaddr) QSE_CPP_NOEXCEPT
{ {
QSE_ASSERT (this->handle != QSE_INVALID_SCKHND); QSE_ASSERT (qse_is_sck_valid(this->handle));
qse_sklen_t addrlen = srcaddr.getAddrCapa(); qse_sklen_t addrlen = srcaddr.getAddrCapa();
qse_ssize_t n = ::recvfrom(this->handle, buf, len, 0, (struct sockaddr*)srcaddr.getAddrPtr(), &addrlen); qse_ssize_t n = ::recvfrom(this->handle, buf, len, 0, (struct sockaddr*)srcaddr.getAddrPtr(), &addrlen);
@ -868,27 +868,6 @@ int Socket::get_ifce_address (int cmd, const void* name, qse_size_t len, bool wc
struct ifreq ifr; struct ifreq ifr;
QSE_MEMSET (&ifr, 0, QSE_SIZEOF(ifr)); QSE_MEMSET (&ifr, 0, QSE_SIZEOF(ifr));
#if 0
if (wchar)
{
qse_size_t wlen, mlen = QSE_COUNTOF(ifr.ifr_name);
if (qse_wcstombs((const qse_wchar_t*)name, &wlen, ifr.ifr_name, &mlen) <= -1 ||
((const qse_wchar_t*)name)[wlen] != QSE_WT('\0'))
{
this->setErrorCode (E_EINVAL);
return -1;
}
}
else
{
qse_size_t mlen = qse_mbsxcpy(ifr.ifr_name, QSE_COUNTOF(ifr.ifr_name), (const qse_mchar_t*)name);
if (((const qse_mchar_t*)name)[mlen] != QSE_MT('\0'))
{
this->setErrorCode (E_EINVAL);
return -1;
}
}
#else
if (wchar) if (wchar)
{ {
qse_size_t wlen = len, mlen = QSE_COUNTOF(ifr.ifr_name) - 1; qse_size_t wlen = len, mlen = QSE_COUNTOF(ifr.ifr_name) - 1;
@ -908,7 +887,6 @@ int Socket::get_ifce_address (int cmd, const void* name, qse_size_t len, bool wc
return -1; return -1;
} }
} }
#endif
#if defined(HAVE_GETIFADDRS) #if defined(HAVE_GETIFADDRS)
struct ifaddrs* ifa; struct ifaddrs* ifa;

View File

@ -271,11 +271,11 @@ int TcpServer::setup_listeners (const qse_char_t* addrs) QSE_CPP_NOEXCEPT
goto oops; goto oops;
} }
#if defined(O_CLOEXEC) #if defined(FD_CLOEXEC)
fcv = ::fcntl(pfd[0], F_GETFD, 0); fcv = ::fcntl(pfd[0], F_GETFD, 0);
if (fcv >= 0) ::fcntl(pfd[0], F_SETFD, fcv | O_CLOEXEC); if (fcv >= 0) ::fcntl(pfd[0], F_SETFD, fcv | FD_CLOEXEC);
fcv = ::fcntl(pfd[1], F_GETFD, 0); fcv = ::fcntl(pfd[1], F_GETFD, 0);
if (fcv >= 0) ::fcntl(pfd[1], F_SETFD, fcv | O_CLOEXEC); if (fcv >= 0) ::fcntl(pfd[1], F_SETFD, fcv | FD_CLOEXEC);
#endif #endif
#if defined(O_NONBLOCK) #if defined(O_NONBLOCK)
fcv = ::fcntl(pfd[0], F_GETFL, 0); fcv = ::fcntl(pfd[0], F_GETFL, 0);

View File

@ -893,6 +893,13 @@ int qse_fio_init (
fio->errnum = syserr_to_errnum (errno); fio->errnum = syserr_to_errnum (errno);
return -1; return -1;
} }
else
{
#if !defined(O_CLOEXEC) && defined(FD_CLOEXEC)
int flag = fcntl(handle, F_GETFD);
if (flag >= 0) fcntl (handle, F_SETFD, flag | FD_CLOEXEC);
#endif
}
/* set some file access hints */ /* set some file access hints */
#if defined(POSIX_FADV_RANDOM) #if defined(POSIX_FADV_RANDOM)

View File

@ -314,9 +314,9 @@ int qse_mux_init (
#elif defined(USE_KQUEUE) #elif defined(USE_KQUEUE)
#if defined(HAVE_KQUEUE1) && defined(O_CLOEXEC) #if defined(HAVE_KQUEUE1) && defined(O_CLOEXEC)
mux->kq = kqueue1 (O_CLOEXEC); mux->kq = kqueue1(O_CLOEXEC);
#else #else
mux->kq = kqueue (); mux->kq = kqueue();
#endif #endif
if (mux->kq <= -1) if (mux->kq <= -1)
{ {
@ -328,16 +328,16 @@ int qse_mux_init (
/* nothing to do */ /* nothing to do */
#elif defined(FD_CLOEXEC) #elif defined(FD_CLOEXEC)
{ {
int flag = fcntl (mux->kq, F_GETFD); int flag = fcntl(mux->kq, F_GETFD);
if (flag >= 0) fcntl (mux->kq, F_SETFD, flag | FD_CLOEXEC); if (flag >= 0) fcntl (mux->kq, F_SETFD, flag | FD_CLOEXEC);
} }
#endif #endif
#elif defined(USE_EPOLL) #elif defined(USE_EPOLL)
#if defined(HAVE_EPOLL_CREATE1) && defined(O_CLOEXEC) #if defined(HAVE_EPOLL_CREATE1) && defined(O_CLOEXEC)
mux->fd = epoll_create1 (O_CLOEXEC); mux->fd = epoll_create1(O_CLOEXEC);
#else #else
mux->fd = epoll_create (capahint); mux->fd = epoll_create(capahint);
#endif #endif
if (mux->fd <= -1) if (mux->fd <= -1)
{ {
@ -349,7 +349,7 @@ int qse_mux_init (
/* nothing to do */ /* nothing to do */
#elif defined(FD_CLOEXEC) #elif defined(FD_CLOEXEC)
{ {
int flag = fcntl (mux->fd, F_GETFD); int flag = fcntl(mux->fd, F_GETFD);
if (flag >= 0) fcntl (mux->fd, F_SETFD, flag | FD_CLOEXEC); if (flag >= 0) fcntl (mux->fd, F_SETFD, flag | FD_CLOEXEC);
} }
#endif #endif

View File

@ -1,12 +1,38 @@
/*
* $Id$
*
Copyright (c) 2006-2014 Chung, Hyung-Hwan. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* copied from musl */ /* copied from musl */
#include <qse/si/netlink.h> #include <qse/si/netlink.h>
#include <qse/si/sck.h>
#include "../cmn/mem-prv.h" #include "../cmn/mem-prv.h"
#include "../cmn/syscall.h"
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <syscall.h>
#include <sys/socket.h> #include <sys/socket.h>
/* linux/netlink.h */ /* linux/netlink.h */
@ -36,23 +62,23 @@
struct rtattr struct rtattr
{ {
unsigned short rta_len; unsigned short int rta_len;
unsigned short rta_type; unsigned short int rta_type;
}; };
struct rtgenmsg struct rtgenmsg
{ {
unsigned char rtgen_family; unsigned char rtgen_family;
}; };
struct ifinfomsg struct ifinfomsg
{ {
unsigned char ifi_family; unsigned char ifi_family;
unsigned char __ifi_pad; unsigned char __ifi_pad;
unsigned short ifi_type; unsigned short int ifi_type;
int ifi_index; int ifi_index;
unsigned ifi_flags; unsigned int ifi_flags;
unsigned ifi_change; unsigned int ifi_change;
}; };
/* linux/if_link.h */ /* linux/if_link.h */
@ -66,17 +92,17 @@ struct ifinfomsg
struct ifaddrmsg struct ifaddrmsg
{ {
qse_uint8_t ifa_family; qse_uint8_t ifa_family;
qse_uint8_t ifa_prefixlen; qse_uint8_t ifa_prefixlen;
qse_uint8_t ifa_flags; qse_uint8_t ifa_flags;
qse_uint8_t ifa_scope; qse_uint8_t ifa_scope;
qse_uint32_t ifa_index; qse_uint32_t ifa_index;
}; };
#define IFA_ADDRESS 1 #define IFA_ADDRESS 1
#define IFA_LOCAL 2 #define IFA_LOCAL 2
#define IFA_LABEL 3 #define IFA_LABEL 3
#define IFA_BROADCAST 4 #define IFA_BROADCAST 4
/* musl */ /* musl */
@ -96,12 +122,12 @@ struct ifaddrmsg
#define NLMSG_RTA(nlh,len) ((void*)((char*)(nlh)+QSE_SIZEOF(struct qse_nlmsg_hdr_t)+NETLINK_ALIGN(len))) #define NLMSG_RTA(nlh,len) ((void*)((char*)(nlh)+QSE_SIZEOF(struct qse_nlmsg_hdr_t)+NETLINK_ALIGN(len)))
#define NLMSG_RTAOK(rta,nlh) RTA_OK(rta,NLMSG_DATAEND(nlh)) #define NLMSG_RTAOK(rta,nlh) RTA_OK(rta,NLMSG_DATAEND(nlh))
int qse_nlenum(int fd, unsigned int seq, int type, int af, qse_nlenum_cb_t cb, void *ctx) static int netlink_enumerate(int fd, unsigned int seq, int type, int af, qse_nlenum_cb_t cb, void *ctx)
{ {
struct qse_nlmsg_hdr_t *h; struct qse_nlmsg_hdr_t *h;
union union
{ {
qse_uint8_t buf[8192]; qse_uint8_t buf[8192]; /* TODO: is this large enough? */
struct struct
{ {
struct qse_nlmsg_hdr_t nlh; struct qse_nlmsg_hdr_t nlh;
@ -109,7 +135,7 @@ int qse_nlenum(int fd, unsigned int seq, int type, int af, qse_nlenum_cb_t cb, v
} req; } req;
struct qse_nlmsg_hdr_t reply; struct qse_nlmsg_hdr_t reply;
} u; } u;
int r, ret; int r;
QSE_MEMSET(&u.req, 0, QSE_SIZEOF(u.req)); QSE_MEMSET(&u.req, 0, QSE_SIZEOF(u.req));
u.req.nlh.nlmsg_len = QSE_SIZEOF(u.req); u.req.nlh.nlmsg_len = QSE_SIZEOF(u.req);
@ -118,7 +144,7 @@ int qse_nlenum(int fd, unsigned int seq, int type, int af, qse_nlenum_cb_t cb, v
u.req.nlh.nlmsg_seq = seq; u.req.nlh.nlmsg_seq = seq;
u.req.g.rtgen_family = af; u.req.g.rtgen_family = af;
r = send(fd, &u.req, QSE_SIZEOF(u.req), 0); r = send(fd, &u.req, QSE_SIZEOF(u.req), 0);
if (r < 0) return r; if (r == -1) return -1;
while (1) while (1)
{ {
@ -129,24 +155,37 @@ int qse_nlenum(int fd, unsigned int seq, int type, int af, qse_nlenum_cb_t cb, v
{ {
if (h->nlmsg_type == NLMSG_DONE) return 0; if (h->nlmsg_type == NLMSG_DONE) return 0;
if (h->nlmsg_type == NLMSG_ERROR) return -1; if (h->nlmsg_type == NLMSG_ERROR) return -1;
ret = cb(h, ctx); if (cb(h, ctx) <= -1) return -1;
if (ret) return ret;
} }
} }
return 0;
} }
int qse_nlenum_route (int link_af, int addr_af, qse_nlenum_cb_t cb, void *ctx) int qse_nlenum_route (int link_af, int addr_af, qse_nlenum_cb_t cb, void *ctx)
{ {
int fd, r; int fd, rc;
#if defined(SOCK_CLOEXEC)
fd = socket(PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE); fd = socket(PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
if (fd <= -1) return -1; if (fd <= -1) return -1;
#else
fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if (fd <= -1) return -1;
else
{
#if defined(FD_CLOEXEC)
int flag = fcntl(fd, F_GETFD);
if (flag >= 0) fcntl (fd, F_SETFD, flag | FD_CLOEXEC);
#endif
}
#endif
r = qse_nlenum(fd, 1, RTM_GETLINK, link_af, cb, ctx); rc = enumerate_netlink(fd, 1, RTM_GETLINK, link_af, cb, ctx);
if (!r) r = qse_nlenum(fd, 2, RTM_GETADDR, addr_af, cb, ctx); if (rc >= 0) rc = netlink_enumerate(fd, 2, RTM_GETADDR, addr_af, cb, ctx);
QSE_CLOSE (fd); qse_close_sck (fd);
return r; return rc;
} }
#if 0 #if 0
@ -159,7 +198,7 @@ int qse_nlenum_route (int link_af, int addr_af, qse_nlenum_cb_t cb, void *ctx)
#include <syscall.h> #include <syscall.h>
#include <net/if.h> #include <net/if.h>
#include <netinet/in.h> #include <netinet/in.h>
#include "netlink.h"
#define IFADDRS_HASH_SIZE 64 #define IFADDRS_HASH_SIZE 64
@ -169,9 +208,9 @@ int qse_nlenum_route (int link_af, int addr_af, qse_nlenum_cb_t cb, void *ctx)
* to extend ssl_addr - callers should be able to still use it. */ * to extend ssl_addr - callers should be able to still use it. */
struct sockaddr_ll_hack struct sockaddr_ll_hack
{ {
unsigned short sll_family, sll_protocol; unsigned short int sll_family, sll_protocol;
int sll_ifindex; int sll_ifindex;
unsigned short sll_hatype; unsigned short int sll_hatype;
unsigned char sll_pkttype, sll_halen; unsigned char sll_pkttype, sll_halen;
unsigned char sll_addr[24]; unsigned char sll_addr[24];
}; };
@ -195,9 +234,9 @@ struct ifaddrs_storage
struct ifaddrs_ctx struct ifaddrs_ctx
{ {
struct ifaddrs_storage *first; struct ifaddrs_storage* first;
struct ifaddrs_storage *last; struct ifaddrs_storage* last;
struct ifaddrs_storage *hash[IFADDRS_HASH_SIZE]; struct ifaddrs_storage* hash[IFADDRS_HASH_SIZE];
}; };
void freeifaddrs(struct ifaddrs *ifp) void freeifaddrs(struct ifaddrs *ifp)
@ -247,7 +286,7 @@ static void gen_netmask(struct sockaddr **r, int af, union sockany *sa, int pref
copy_addr(r, af, sa, addr, sizeof(addr), 0); copy_addr(r, af, sa, addr, sizeof(addr), 0);
} }
static void copy_lladdr(struct sockaddr **r, union sockany *sa, void *addr, size_t addrlen, int ifindex, unsigned short hatype) static void copy_lladdr(struct sockaddr **r, union sockany *sa, void *addr, size_t addrlen, int ifindex, unsigned short int hatype)
{ {
if (addrlen > sizeof(sa->ll.sll_addr)) return; if (addrlen > sizeof(sa->ll.sll_addr)) return;
sa->ll.sll_family = AF_PACKET; sa->ll.sll_family = AF_PACKET;
@ -258,36 +297,43 @@ static void copy_lladdr(struct sockaddr **r, union sockany *sa, void *addr, size
*r = &sa->sa; *r = &sa->sa;
} }
static int netlink_msg_to_ifaddr(void *pctx, struct qse_nlmsg_hdr_t *h) static int netlink_msg_to_ifaddr (qse_nlmsg_hdr_t* h, void* pctx)
{ {
struct ifaddrs_ctx *ctx = pctx; struct ifaddrs_ctx* ctx = pctx;
struct ifaddrs_storage *ifs, *ifs0; struct ifaddrs_storage *ifs, *ifs0;
struct ifinfomsg *ifi = NLMSG_DATA(h); struct ifinfomsg *ifi = NLMSG_DATA(h);
struct ifaddrmsg *ifa = NLMSG_DATA(h); struct ifaddrmsg *ifa = NLMSG_DATA(h);
struct rtattr *rta; struct rtattr *rta;
int stats_len = 0; int stats_len = 0;
if (h->nlmsg_type == RTM_NEWLINK) { if (h->nlmsg_type == RTM_NEWLINK)
for (rta = NLMSG_RTA(h, sizeof(*ifi)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) { {
for (rta = NLMSG_RTA(h, sizeof(*ifi)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta))
{
if (rta->rta_type != IFLA_STATS) continue; if (rta->rta_type != IFLA_STATS) continue;
stats_len = RTA_DATALEN(rta); stats_len = RTA_DATALEN(rta);
break; break;
} }
} else { }
else
{
for (ifs0 = ctx->hash[ifa->ifa_index % IFADDRS_HASH_SIZE]; ifs0; ifs0 = ifs0->hash_next) for (ifs0 = ctx->hash[ifa->ifa_index % IFADDRS_HASH_SIZE]; ifs0; ifs0 = ifs0->hash_next)
if (ifs0->index == ifa->ifa_index) {
break; if (ifs0->index == ifa->ifa_index) break;
}
if (!ifs0) return 0; if (!ifs0) return 0;
} }
ifs = calloc(1, sizeof(struct ifaddrs_storage) + stats_len); ifs = calloc(1, sizeof(struct ifaddrs_storage) + stats_len);
if (ifs == 0) return -1; if (ifs == 0) return -1;
if (h->nlmsg_type == RTM_NEWLINK) { if (h->nlmsg_type == RTM_NEWLINK)
{
ifs->index = ifi->ifi_index; ifs->index = ifi->ifi_index;
ifs->ifa.ifa_flags = ifi->ifi_flags; ifs->ifa.ifa_flags = ifi->ifi_flags;
for (rta = NLMSG_RTA(h, sizeof(*ifi)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) { for (rta = NLMSG_RTA(h, sizeof(*ifi)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta))
{
switch (rta->rta_type) { switch (rta->rta_type) {
case IFLA_IFNAME: case IFLA_IFNAME:
if (RTA_DATALEN(rta) < sizeof(ifs->name)) { if (RTA_DATALEN(rta) < sizeof(ifs->name)) {
@ -312,7 +358,9 @@ static int netlink_msg_to_ifaddr(void *pctx, struct qse_nlmsg_hdr_t *h)
ifs->hash_next = ctx->hash[bucket]; ifs->hash_next = ctx->hash[bucket];
ctx->hash[bucket] = ifs; ctx->hash[bucket] = ifs;
} }
} else { }
else
{
ifs->ifa.ifa_name = ifs0->ifa.ifa_name; ifs->ifa.ifa_name = ifs0->ifa.ifa_name;
ifs->ifa.ifa_flags = ifs0->ifa.ifa_flags; ifs->ifa.ifa_flags = ifs0->ifa.ifa_flags;
for (rta = NLMSG_RTA(h, sizeof(*ifa)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) { for (rta = NLMSG_RTA(h, sizeof(*ifa)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
@ -350,22 +398,25 @@ static int netlink_msg_to_ifaddr(void *pctx, struct qse_nlmsg_hdr_t *h)
gen_netmask(&ifs->ifa.ifa_netmask, ifa->ifa_family, &ifs->netmask, ifa->ifa_prefixlen); gen_netmask(&ifs->ifa.ifa_netmask, ifa->ifa_family, &ifs->netmask, ifa->ifa_prefixlen);
} }
if (ifs->ifa.ifa_name) { if (ifs->ifa.ifa_name)
{
if (!ctx->first) ctx->first = ifs; if (!ctx->first) ctx->first = ifs;
if (ctx->last) ctx->last->ifa.ifa_next = &ifs->ifa; if (ctx->last) ctx->last->ifa.ifa_next = &ifs->ifa;
ctx->last = ifs; ctx->last = ifs;
} else { }
else
{
free(ifs); free(ifs);
} }
return 0; return 0;
} }
int getifaddrs(struct ifaddrs **ifap) int getifaddrs (struct ifaddrs **ifap)
{ {
struct ifaddrs_ctx _ctx, *ctx = &_ctx; struct ifaddrs_ctx _ctx, *ctx = &_ctx;
int r; int r;
QSE_MEMSET(ctx, 0, sizeof *ctx); QSE_MEMSET(ctx, 0, sizeof *ctx);
r = __rtnetlink_enumerate(AF_UNSPEC, AF_UNSPEC, netlink_msg_to_ifaddr, ctx); r = qse_nlenum_route(AF_UNSPEC, AF_UNSPEC, netlink_msg_to_ifaddr, ctx);
if (r == 0) *ifap = &ctx->first->ifa; if (r == 0) *ifap = &ctx->first->ifa;
else freeifaddrs(&ctx->first->ifa); else freeifaddrs(&ctx->first->ifa);
return r; return r;

View File

@ -1053,7 +1053,7 @@ int qse_nwio_init (
goto oops; goto oops;
} }
qse_closesckhnd (nwio->handle); /* close the listening socket */ qse_close_sck (nwio->handle); /* close the listening socket */
nwio->handle = handle; /* set the handle to the accepted socket */ nwio->handle = handle; /* set the handle to the accepted socket */
} }
else if (flags & QSE_NWIO_UDP) else if (flags & QSE_NWIO_UDP)
@ -1150,7 +1150,7 @@ oops:
nwio->tio = QSE_NULL; nwio->tio = QSE_NULL;
} }
if (qse_isvalidsckhnd(nwio->handle)) qse_closesckhnd (nwio->handle); if (qse_is_sck_valid(nwio->handle)) qse_close_sck (nwio->handle);
return -1; return -1;
} }
@ -1164,7 +1164,7 @@ void qse_nwio_fini (qse_nwio_t* nwio)
nwio->tio = QSE_NULL; nwio->tio = QSE_NULL;
} }
qse_closesckhnd (nwio->handle); qse_close_sck (nwio->handle);
} }
qse_mmgr_t* qse_nwio_getmmgr (qse_nwio_t* nwio) qse_mmgr_t* qse_nwio_getmmgr (qse_nwio_t* nwio)

View File

@ -76,7 +76,7 @@
# define SHUT_RDWR 2 # define SHUT_RDWR 2
#endif #endif
QSE_INLINE int qse_isvalidsckhnd (qse_sck_hnd_t handle) QSE_INLINE int qse_is_sck_valid (qse_sck_hnd_t handle)
{ {
#if defined(_WIN32) #if defined(_WIN32)
return handle != QSE_INVALID_SCKHND; return handle != QSE_INVALID_SCKHND;
@ -95,7 +95,7 @@ QSE_INLINE int qse_isvalidsckhnd (qse_sck_hnd_t handle)
#endif #endif
} }
QSE_INLINE void qse_closesckhnd (qse_sck_hnd_t handle) QSE_INLINE void qse_close_sck (qse_sck_hnd_t handle)
{ {
#if defined(_WIN32) #if defined(_WIN32)
closesocket (handle); closesocket (handle);
@ -114,7 +114,7 @@ QSE_INLINE void qse_closesckhnd (qse_sck_hnd_t handle)
#endif #endif
} }
QSE_INLINE void qse_shutsckhnd (qse_sck_hnd_t handle, qse_shutsckhnd_how_t how) QSE_INLINE void qse_shut_sck (qse_sck_hnd_t handle, qse_shut_sck_how_t how)
{ {
static int how_v[] = { SHUT_RD, SHUT_WR, SHUT_RDWR }; static int how_v[] = { SHUT_RD, SHUT_WR, SHUT_RDWR };
@ -148,7 +148,7 @@ QSE_INLINE void qse_shutsckhnd (qse_sck_hnd_t handle, qse_shutsckhnd_how_t how)
#endif #endif
} }
int qse_setscknonblock (qse_sck_hnd_t handle, int enabled) int qse_set_sck_nonblock (qse_sck_hnd_t handle, int enabled)
{ {
#if defined(_WIN32) #if defined(_WIN32)
if (ioctlsocket (handle, FIONBIO, &enabled) == SOCKET_ERROR) return -1; if (ioctlsocket (handle, FIONBIO, &enabled) == SOCKET_ERROR) return -1;
@ -166,18 +166,38 @@ int qse_setscknonblock (qse_sck_hnd_t handle, int enabled)
#elif defined(O_NONBLOCK) #elif defined(O_NONBLOCK)
int flag = fcntl (handle, F_GETFL); int flag = fcntl(handle, F_GETFL);
if (flag >= 0) flag = fcntl (handle, F_SETFL, (enabled? (flag | O_NONBLOCK): (flag & ~O_NONBLOCK))); if (flag >= 0) flag = fcntl(handle, F_SETFL, (enabled? (flag | O_NONBLOCK): (flag & ~O_NONBLOCK)));
if (flag <= -1) return -1; if (flag <= -1) return -1;
return 0; return 0;
#else #else
return -1; return -1;
#endif #endif
} }
int qse_initsckconn (qse_sck_hnd_t handle, const qse_nwad_t* nwad) int qse_set_sck_cloexec (qse_sck_hnd_t handle, int enabled)
{
#if defined(_WIN32)
return -1;
#elif defined(__OS2__)
return -1;
#elif defined(__DOS__)
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)));
if (flag <= -1) return -1;
return 0;
#else
return -1;
#endif
}
int qse_init_sck_conn (qse_sck_hnd_t handle, const qse_nwad_t* nwad)
{ {
int n; int n;
#if defined(_WIN32) #if defined(_WIN32)
@ -203,7 +223,7 @@ int qse_initsckconn (qse_sck_hnd_t handle, const qse_nwad_t* nwad)
} }
/* attempt to connet */ /* attempt to connet */
n = connect (handle, (struct sockaddr*)&skad, skadlen); n = connect(handle, (struct sockaddr*)&skad, skadlen);
if (n == -1 && WSAGetLastError() != WSAEWOULDBLOCK) if (n == -1 && WSAGetLastError() != WSAEWOULDBLOCK)
{ {
/* attempt to restore to the blocking mode upon failure. /* attempt to restore to the blocking mode upon failure.
@ -233,12 +253,12 @@ int qse_initsckconn (qse_sck_hnd_t handle, const qse_nwad_t* nwad)
/* switch to the non-blocking mode */ /* switch to the non-blocking mode */
saved = fcntl (handle, F_GETFL, 0); saved = fcntl (handle, F_GETFL, 0);
if (saved == -1) return -1; if (saved == -1) return -1;
if (fcntl (handle, F_SETFL, saved | O_NONBLOCK) == -1) return -1; if (fcntl(handle, F_SETFL, saved | O_NONBLOCK) == -1) return -1;
/* attempt to connet */ /* attempt to connet */
do do
{ {
n = connect (handle, (struct sockaddr*)&skad, skadlen); n = connect(handle, (struct sockaddr*)&skad, skadlen);
} }
while (n == -1 && errno == EINTR); while (n == -1 && errno == EINTR);
@ -253,7 +273,7 @@ int qse_initsckconn (qse_sck_hnd_t handle, const qse_nwad_t* nwad)
return (n == 0)? 1: 0; /* 1: connected, 0: in progress */ return (n == 0)? 1: 0; /* 1: connected, 0: in progress */
} }
int qse_finisckconn (qse_sck_hnd_t handle) int qse_fini_sck_conn (qse_sck_hnd_t handle)
{ {
int ret; int ret;
qse_sck_len_t len; qse_sck_len_t len;
@ -275,7 +295,7 @@ int qse_finisckconn (qse_sck_hnd_t handle)
else if (ret == EINPROGRESS) else if (ret == EINPROGRESS)
#endif #endif
{ {
return 0; /* in preogress */ return 0; /* in progress */
} }
else if (ret != 0) else if (ret != 0)
{ {