Message ID | 20170919230643.87425-3-carenas@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Le 20/09/2017 à 01:06, Carlo Marcelo Arenas Belón a écrit : > Signed-off-by: Carlo Marcelo Arenas Belón <carenas@gmail.com> > --- > linux-user/syscall.c | 34 +++++++++++++++++++++++++++++++++- > 1 file changed, 33 insertions(+), 1 deletion(-) > > diff --git a/linux-user/syscall.c b/linux-user/syscall.c > index ad689dad50..91bd27c63a 100644 > --- a/linux-user/syscall.c > +++ b/linux-user/syscall.c > @@ -3178,7 +3178,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: > @@ -3216,6 +3215,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; > You should merge PATCH 2/3 and PATCH 3/3. Reviewed-by: Laurent Vivier <laurent@vivier.eu>
diff --git a/linux-user/syscall.c b/linux-user/syscall.c index ad689dad50..91bd27c63a 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -3178,7 +3178,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: @@ -3216,6 +3215,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;
Signed-off-by: Carlo Marcelo Arenas Belón <carenas@gmail.com> --- linux-user/syscall.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-)