From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1G10e6-0000nf-NE for qemu-devel@nongnu.org; Thu, 13 Jul 2006 08:50:22 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1G10e2-0000n1-Nr for qemu-devel@nongnu.org; Thu, 13 Jul 2006 08:50:21 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1G10e2-0000my-HG for qemu-devel@nongnu.org; Thu, 13 Jul 2006 08:50:18 -0400 Received: from [217.30.189.230] (helo=mail.nomovok.com) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA:32) (Exim 4.52) id 1G10fn-0002vX-Fs for qemu-devel@nongnu.org; Thu, 13 Jul 2006 08:52:08 -0400 Received: from [85.77.96.209] (GYZMMCMVIII.dsl.saunalahti.fi [85.77.96.209]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.nomovok.com (Postfix) with ESMTP id 7F6A1D94208 for ; Thu, 13 Jul 2006 15:50:12 +0300 (EEST) Message-ID: <44B6418D.3080809@nomovok.com> Date: Thu, 13 Jul 2006 15:50:21 +0300 From: Pablo Virolainen MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------070301050209080305040302" Subject: [Qemu-devel] [PATCH] for some socket operations and trivial compiler warning fix Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org This is a multi-part message in MIME format. --------------070301050209080305040302 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit The patch should add support for SO_LINGER, SO_RCVTIMEO, SO_SNDTIMEO, SO_PEERCRED and SO_PEERNAME. --------------070301050209080305040302 Content-Type: text/x-patch; name="qemu_socket.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="qemu_socket.patch" Index: linux-user/syscall.c =================================================================== RCS file: /sources/qemu/qemu/linux-user/syscall.c,v retrieving revision 1.75 diff -u -r1.75 syscall.c --- linux-user/syscall.c 27 Jun 2006 21:08:10 -0000 1.75 +++ linux-user/syscall.c 13 Jul 2006 10:00:09 -0000 @@ -509,20 +509,28 @@ msgh->msg_controllen = tswapl(space); } +static long do_setsockopt_timehelper(int sockfd, int level, int optname, + target_ulong optval, target_ulong optlen) +{ + int len; + struct timeval tv; + if (get_user(len, &optlen) || + !access_ok(VERIFY_READ,optval,sizeof(struct target_timeval))) + return -EFAULT; + + if (len != sizeof(struct target_timeval)) + return -EINVAL; + + target_to_host_timeval(&tv,optval); + return get_errno(setsockopt(sockfd, level, optname, &tv, sizeof(struct timeval))); +} + static long do_setsockopt(int sockfd, int level, int optname, target_ulong optval, socklen_t optlen) { int val, ret; switch(level) { - case SOL_TCP: - /* TCP options all take an 'int' value. */ - if (optlen < sizeof(uint32_t)) - return -EINVAL; - - val = tget32(optval); - ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val))); - break; case SOL_IP: switch(optname) { case IP_TOS: @@ -606,20 +614,39 @@ optname = SO_RCVLOWAT; break; case TARGET_SO_RCVTIMEO: - optname = SO_RCVTIMEO; + ret = do_setsockopt_timehelper(sockfd,level,SO_RCVTIMEO,optval,optlen); break; case TARGET_SO_SNDTIMEO: - optname = SO_SNDTIMEO; + ret = do_setsockopt_timehelper(sockfd,level,SO_SNDTIMEO,optval,optlen); break; + case TARGET_SO_LINGER: { + struct linger tmp; + struct linger *target = (struct linger *) optval; + if (optlen == sizeof(struct linger) && + get_user(tmp.l_onoff,&target->l_onoff) && + get_user(tmp.l_linger,&target->l_linger)) { + ret = get_errno(setsockopt(sockfd, level, SO_LINGER, &tmp, sizeof(struct linger))); + } else { + /* Just to make strace look better */ + ret = get_errno(setsockopt(sockfd, level, SO_LINGER, &optval,optlen)); + } + return ret; + break; + } break; default: goto unimplemented; } - if (optlen < sizeof(uint32_t)) - return -EINVAL; - - val = tget32(optval); - ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, sizeof(val))); + goto int_case; + break; + case SOL_TCP: + int_case: + /* TCP options all take an 'int' value. */ + if (optlen < sizeof(uint32_t)) + return -EINVAL; + + val = tget32(optval); + ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val))); break; default: unimplemented: @@ -629,6 +656,40 @@ return ret; } +static long do_getsockopt_structhelper(int sockfd, int level, int optname, + target_ulong optval, target_ulong optlen) +{ + int ret,len,i; + /* Let's assume 32-bit parameters */ + if (get_user(len, &optlen)) + return -EFAULT; + if (len < 0) + return -EINVAL; + ret = get_errno(getsockopt(sockfd, level, optname, &optval, &len)); + for(i = 0; i < len && optval != 0; i += 4) { + /* This could propably be done more efficiently */ + tput32(optval + i, optval + i); + } + return ret; +} + +static long do_getsockopt_timehelper(int sockfd, int level, int optname, + target_ulong optval, target_ulong optlen) +{ + int ret,len; + struct timeval tv; + static socklen_t olen=sizeof(struct timeval); + if (get_user(len, &optlen)) + return -EFAULT; + if (len != sizeof(struct target_timeval)) + return -EINVAL; + ret = get_errno(getsockopt(sockfd, level, optname, &tv, &olen)); + if (ret==0) { + host_to_target_timeval(optval,&tv); + } + return ret; +} + static long do_getsockopt(int sockfd, int level, int optname, target_ulong optval, target_ulong optlen) { @@ -638,13 +699,28 @@ case TARGET_SOL_SOCKET: level = SOL_SOCKET; switch (optname) { + /* These don't just return a single integer */ case TARGET_SO_LINGER: + ret = do_getsockopt_structhelper(sockfd,level,SO_LINGER,optval,optlen); + break; case TARGET_SO_RCVTIMEO: + ret = do_getsockopt_timehelper(sockfd,level,SO_RCVTIMEO,optval,optlen); + break; case TARGET_SO_SNDTIMEO: + ret = do_getsockopt_timehelper(sockfd,level,SO_SNDTIMEO,optval,optlen); + break; case TARGET_SO_PEERCRED: + ret = do_getsockopt_structhelper(sockfd,level,SO_PEERCRED,optval,optlen); + break; case TARGET_SO_PEERNAME: - /* These don't just return a single integer */ - goto unimplemented; + if (get_user(len, &optlen)) + return -EFAULT; + if (len < 0) + return -EINVAL; + ret = get_errno(getsockopt(sockfd, level, optname, &optval, &len)); + if (put_user(len, &optlen)) + return -EFAULT; + break; default: goto int_case; } --------------070301050209080305040302 Content-Type: text/x-patch; name="qemu_trivial_warling.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="qemu_trivial_warling.patch" Index: linux-user/syscall.c =================================================================== RCS file: /sources/qemu/qemu/linux-user/syscall.c,v retrieving revision 1.75 diff -u -r1.75 syscall.c --- linux-user/syscall.c 27 Jun 2006 21:08:10 -0000 1.75 +++ linux-user/syscall.c 13 Jul 2006 10:00:09 -0000 @@ -1054,6 +1141,13 @@ /* XXX: suppress this function and call directly the related socket functions */ +#if defined(TARGET_NR_accept) || defined(TARGET_NR_getpeername) || \ + defined(TARGET_NR_getsockname) || defined(TARGET_NR_listen) || \ + defined(TARGET_NR_recv) || defined(TARGET_NR_recvfrom) || \ + defined(TARGET_NR_recvmsg) || defined(TARGET_NR_send) || \ + defined(TARGET_NR_sendto) || defined(TARGET_NR_shutdown) || \ + defined(TARGET_NR_socketpair) + static long do_socketcallwrapper(int num, long arg1, long arg2, long arg3, long arg4, long arg5, long arg6) { @@ -1068,6 +1162,7 @@ return do_socketcall(num, (target_ulong) args); } +#endif #define N_SHM_REGIONS 32 --------------070301050209080305040302--