mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-12-02 03:47:53 +08:00
Hook getsockopt for get socket's IO timeout in fiber module.
This commit is contained in:
parent
5c85d8fe63
commit
b563e34dc4
@ -55,6 +55,9 @@ fcntl_fn *sys_fcntl = NULL;
|
|||||||
setsockopt_fn __sys_setsockopt = NULL;
|
setsockopt_fn __sys_setsockopt = NULL;
|
||||||
setsockopt_fn *sys_setsockopt = NULL;
|
setsockopt_fn *sys_setsockopt = NULL;
|
||||||
|
|
||||||
|
getsockopt_fn __sys_getsockopt = NULL;
|
||||||
|
getsockopt_fn *sys_getsockopt = NULL;
|
||||||
|
|
||||||
read_fn __sys_read = NULL;
|
read_fn __sys_read = NULL;
|
||||||
read_fn *sys_read = NULL;
|
read_fn *sys_read = NULL;
|
||||||
|
|
||||||
@ -250,6 +253,7 @@ static void hook_api(void)
|
|||||||
LOAD_FN("accept", accept_fn, __sys_accept, sys_accept, 1);
|
LOAD_FN("accept", accept_fn, __sys_accept, sys_accept, 1);
|
||||||
LOAD_FN("connect", connect_fn, __sys_connect, sys_connect, 1);
|
LOAD_FN("connect", connect_fn, __sys_connect, sys_connect, 1);
|
||||||
LOAD_FN("setsockopt", setsockopt_fn, __sys_setsockopt, sys_setsockopt, 1);
|
LOAD_FN("setsockopt", setsockopt_fn, __sys_setsockopt, sys_setsockopt, 1);
|
||||||
|
LOAD_FN("getsockopt", getsockopt_fn, __sys_getsockopt, sys_getsockopt, 1);
|
||||||
LOAD_FN("sleep", sleep_fn, __sys_sleep, sys_sleep, 1);
|
LOAD_FN("sleep", sleep_fn, __sys_sleep, sys_sleep, 1);
|
||||||
LOAD_FN("fcntl", fcntl_fn, __sys_fcntl, sys_fcntl, 1);
|
LOAD_FN("fcntl", fcntl_fn, __sys_fcntl, sys_fcntl, 1);
|
||||||
LOAD_FN("read", read_fn, __sys_read, sys_read, 1);
|
LOAD_FN("read", read_fn, __sys_read, sys_read, 1);
|
||||||
|
@ -46,6 +46,7 @@ typedef socket_t (WSAAPI *WSAAccept_fn)(SOCKET, struct sockaddr FAR *,
|
|||||||
|
|
||||||
typedef int (*fcntl_fn)(int, int, ...);
|
typedef int (*fcntl_fn)(int, int, ...);
|
||||||
typedef int (*setsockopt_fn)(socket_t, int, int, const void *, socklen_t);
|
typedef int (*setsockopt_fn)(socket_t, int, int, const void *, socklen_t);
|
||||||
|
typedef int (*getsockopt_fn)(socket_t, int, int, void *, socklen_t*);
|
||||||
typedef unsigned (*sleep_fn)(unsigned int seconds);
|
typedef unsigned (*sleep_fn)(unsigned int seconds);
|
||||||
typedef ssize_t (*read_fn)(socket_t, void *, size_t);
|
typedef ssize_t (*read_fn)(socket_t, void *, size_t);
|
||||||
typedef ssize_t (*readv_fn)(socket_t, const struct iovec *, int);
|
typedef ssize_t (*readv_fn)(socket_t, const struct iovec *, int);
|
||||||
@ -154,6 +155,7 @@ extern WSAAccept_fn *sys_WSAAccept;
|
|||||||
|
|
||||||
extern fcntl_fn *sys_fcntl;
|
extern fcntl_fn *sys_fcntl;
|
||||||
extern setsockopt_fn *sys_setsockopt;
|
extern setsockopt_fn *sys_setsockopt;
|
||||||
|
extern getsockopt_fn *sys_getsockopt;
|
||||||
extern sleep_fn *sys_sleep;
|
extern sleep_fn *sys_sleep;
|
||||||
|
|
||||||
extern read_fn *sys_read;
|
extern read_fn *sys_read;
|
||||||
|
@ -554,17 +554,16 @@ int setsockopt(int sockfd, int level, int optname,
|
|||||||
|
|
||||||
if (sys_setsockopt == NULL) {
|
if (sys_setsockopt == NULL) {
|
||||||
hook_once();
|
hook_once();
|
||||||
|
|
||||||
|
if (sys_setsockopt == NULL) {
|
||||||
|
msg_error("sys_setsockopt null");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!var_hook_sys_api || (optname != SO_RCVTIMEO
|
if (!var_hook_sys_api || (optname != SO_RCVTIMEO
|
||||||
&& optname != SO_SNDTIMEO)) {
|
&& optname != SO_SNDTIMEO)) {
|
||||||
return sys_setsockopt ? (*sys_setsockopt)(sockfd, level,
|
return (*sys_setsockopt)(sockfd, level, optname, optval, optlen);
|
||||||
optname, optval, optlen) : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sys_setsockopt == NULL) {
|
|
||||||
msg_error("sys_setsockopt null");
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (optlen) {
|
switch (optlen) {
|
||||||
@ -588,6 +587,7 @@ int setsockopt(int sockfd, int level, int optname,
|
|||||||
val = tm->tv_sec + tm->tv_usec / 1000000;
|
val = tm->tv_sec + tm->tv_usec / 1000000;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
acl_fiber_set_error(FIBER_EINVAL);
|
||||||
msg_error("invalid optlen=%d", (int) optlen);
|
msg_error("invalid optlen=%d", (int) optlen);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -642,4 +642,90 @@ int setsockopt(int sockfd, int level, int optname,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getsockopt(int sockfd, int level, int optname,
|
||||||
|
void *optval, socklen_t *optlen)
|
||||||
|
{
|
||||||
|
FILE_EVENT *fe;
|
||||||
|
|
||||||
|
if (sys_getsockopt == NULL) {
|
||||||
|
hook_once();
|
||||||
|
|
||||||
|
if (sys_getsockopt == NULL) {
|
||||||
|
msg_error("sys_getsockopt null");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!var_hook_sys_api || (optname != SO_RCVTIMEO
|
||||||
|
&& optname != SO_SNDTIMEO)) {
|
||||||
|
return (*sys_getsockopt)(sockfd, level, optname, optval, optlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optval == NULL || optlen == NULL) {
|
||||||
|
acl_fiber_set_error(FIBER_EINVAL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fe = fiber_file_open(sockfd);
|
||||||
|
|
||||||
|
#if defined(SYS_WIN)
|
||||||
|
if (*optlen < (socklen_t) sizeof(int)) {
|
||||||
|
acl_fiber_set_error(FIBER_EINVAL);
|
||||||
|
msg_error("optlen(%d) too short < %zd", (int) (*optlen), sizeof(int));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optname == SO_RCVTIMEO) {
|
||||||
|
if (fe->r_timeout < 0) {
|
||||||
|
*((int*) optval) = fe->r_timeout;
|
||||||
|
} else {
|
||||||
|
*((int*) optval) = fe->r_timeout / 1000;
|
||||||
|
}
|
||||||
|
} else if (optname == SO_SNDTIMEO) {
|
||||||
|
if (fe->w_timeout < 0) {
|
||||||
|
*((int*) optval) = fe->w_timeout;
|
||||||
|
} else {
|
||||||
|
*((int*) optval) = fe->w_timeout / 1000;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return -1; // xxx
|
||||||
|
}
|
||||||
|
|
||||||
|
*optlen = (socklen_t) sizeof(int);
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
if (*optlen < (socklen_t) sizeof(struct timeval)) {
|
||||||
|
acl_fiber_set_error(FIBER_EINVAL);
|
||||||
|
msg_error("optlen(%d) too short < %zd",
|
||||||
|
(int) (*optlen), sizeof(struct timeval));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optname == SO_RCVTIMEO) {
|
||||||
|
struct timeval *tm = (struct timeval*) optval;
|
||||||
|
if (fe->r_timeout < 0) {
|
||||||
|
tm->tv_sec = 0;
|
||||||
|
tm->tv_usec = 0;
|
||||||
|
} else {
|
||||||
|
tm->tv_sec = fe->r_timeout / 1000;
|
||||||
|
tm->tv_usec = 1000000 * (fe->r_timeout % 1000);
|
||||||
|
}
|
||||||
|
} else if (optname == SO_SNDTIMEO) {
|
||||||
|
struct timeval *tm = (struct timeval*) optval;
|
||||||
|
if (fe->w_timeout < 0) {
|
||||||
|
tm->tv_sec = 0;
|
||||||
|
tm->tv_usec = 0;
|
||||||
|
} else {
|
||||||
|
tm->tv_sec = fe->w_timeout / 1000;
|
||||||
|
tm->tv_usec = 1000000 * (fe->w_timeout % 1000);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return -1; // xxx
|
||||||
|
}
|
||||||
|
|
||||||
|
*optlen = (socklen_t) sizeof(struct timeval);
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user