qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] for some socket operations and trivial compiler warning fix
@ 2006-07-13 12:50 Pablo Virolainen
  0 siblings, 0 replies; only message in thread
From: Pablo Virolainen @ 2006-07-13 12:50 UTC (permalink / raw)
  To: qemu-devel

[-- 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
 

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2006-07-13 12:50 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-07-13 12:50 [Qemu-devel] [PATCH] for some socket operations and trivial compiler warning fix Pablo Virolainen

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).