linux-user: add SO_LINGER to {g,s}etsockopt
PATCH 1/1 linux-user: add SO_LINGER to {g,s}etsockopt
Original implementation for setsockopt by Chen Gang[1]; all bugs mine, including removing assignment for optname which hopefully makes the logic easier to follow and moving some variables to make the code more selfcontained.
[1] http://patchwork.ozlabs.org/patch/565659/
Signed-off-by Carlo Marcelo Arenas Belón <[email protected]>
Co-Authored-By Chen Gang <[email protected]>
--- linux-user/syscall.c | 52 ++++++++++++++++++++++++++++++++++++++- linux-user/syscall_defs.h | 5 ++++ 2 files changed, 56 insertions(+), 1 deletion(-)
linux-user/syscall.c +51 -1
@@ -3290,6 +3290,24 @@ set_timeout:unlock_user (dev_ifname, optval_addr,0 );return ret; } +case TARGET_SO_LINGER : + { +struct linger lg; +struct target_linger *tlg; + +if (optlen !=sizeof (struct target_linger )) { +return -TARGET_EINVAL ; + } +if (!lock_user_struct (VERIFY_READ , tlg, optval_addr,1 )) { +return -TARGET_EFAULT ; + } +__get_user (lg.l_onoff, &tlg->l_onoff); +__get_user (lg.l_linger, &tlg->l_linger); + ret =get_errno (setsockopt (sockfd,SOL_SOCKET ,SO_LINGER , + &lg,sizeof (lg))); +unlock_user_struct (tlg, optval_addr,0 ); +return ret; + }/* Options with 'int' argument. */ case TARGET_SO_DEBUG : optname =SO_DEBUG ;
@@ -3381,7 +3399,6 @@ static abi_long do_getsockopt(int sockfd, int level, int optname, level =SOL_SOCKET ;switch (optname) {/* These don't just return a single integer */ -case TARGET_SO_LINGER :case TARGET_SO_RCVTIMEO :case TARGET_SO_SNDTIMEO :case TARGET_SO_PEERNAME :
@@ -3419,6 +3436,39 @@ static abi_long do_getsockopt(int sockfd, int level, int optname, }break ; } +case TARGET_SO_LINGER : + { +struct linger lg; +socklen_t lglen; +struct target_linger *tlg; + +if (get_user_u32 (len, optlen)) { +return -TARGET_EFAULT ; + } +if (len <0 ) { +return -TARGET_EINVAL ; + } + + lglen =sizeof (lg); + ret =get_errno (getsockopt (sockfd, level,SO_LINGER , + &lg, &lglen)); +if (ret <0 ) { +return ret; + } +if (len > lglen) { + len = lglen; + } +if (!lock_user_struct (VERIFY_WRITE , tlg, optval_addr,0 )) { +return -TARGET_EFAULT ; + } +__put_user (lg.l_onoff, &tlg->l_onoff); +__put_user (lg.l_linger, &tlg->l_linger); +unlock_user_struct (tlg, optval_addr,1 ); +if (put_user_u32 (len, optlen)) { +return -TARGET_EFAULT ; + } +break ; + }/* Options with 'int' argument. */ case TARGET_SO_DEBUG : optname =SO_DEBUG ;
linux-user/syscall_defs.h +5 -0
@@ -203,6 +203,11 @@ struct target_ip_mreq_source {uint32_t imr_sourceaddr; }; +struct target_linger { +abi_int l_onoff;/* Linger active */ +abi_int l_linger;/* How long to linger for */ +}; +struct target_timeval {abi_long tv_sec;abi_long tv_usec;
Signature · 1 line
2.18.0
Re: [Qemu-devel] [PATCH] linux-user: add SO_LINGER to {g, s}etsockopt
Le 24/08/2018 à 10:56, Carlo Marcelo Arenas Belón a écrit :
Quoted 5 lines
Original implementation for setsockopt by Chen Gang[1]; all bugs mine, including removing assignment for optname which hopefully makes the logic easier to follow and moving some variables to make the code more selfcontained.
Quoted 9 lines
[1] http://patchwork.ozlabs.org/patch/565659/
Signed-off-by Carlo Marcelo Arenas Belón <[email protected]>Co-Authored-By Chen Gang <[email protected]>--- linux-user/syscall.c | 52 ++++++++++++++++++++++++++++++++++++++- linux-user/syscall_defs.h | 5 ++++ 2 files changed, 56 insertions(+), 1 deletion(-)
Reviewed-by Laurent Vivier <[email protected]>