From: Pablo Virolainen <Pablo.Virolainen@nomovok.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH] for some socket operations and trivial compiler warning fix
Date: Thu, 13 Jul 2006 15:50:21 +0300 [thread overview]
Message-ID: <44B6418D.3080809@nomovok.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 102 bytes --]
The patch should add support for SO_LINGER, SO_RCVTIMEO, SO_SNDTIMEO,
SO_PEERCRED and SO_PEERNAME.
[-- Attachment #2: qemu_socket.patch --]
[-- Type: text/x-patch, Size: 5049 bytes --]
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;
}
[-- Attachment #3: qemu_trivial_warling.patch --]
[-- Type: text/x-patch, Size: 1041 bytes --]
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
reply other threads:[~2006-07-13 12:50 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=44B6418D.3080809@nomovok.com \
--to=pablo.virolainen@nomovok.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).