All of lore.kernel.org
 help / color / mirror / Atom feed
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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.