[Spice-devel] [PATCH usbredir 2/5] Revise to support a UNIX domain socket.

Jeremy White jwhite at codeweavers.com
Wed Dec 9 14:16:26 PST 2015


Signed-off-by: Jeremy White <jwhite at codeweavers.com>
---
 connectkernel/connectkernel.c | 133 +++++++++++++++++++++++++++++-------------
 1 file changed, 92 insertions(+), 41 deletions(-)

diff --git a/connectkernel/connectkernel.c b/connectkernel/connectkernel.c
index cf665e5..b9ed114 100644
--- a/connectkernel/connectkernel.c
+++ b/connectkernel/connectkernel.c
@@ -4,6 +4,7 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
+#include <sys/un.h>
 #include <fcntl.h>
 #include <netdb.h>
 #include <unistd.h>
@@ -12,17 +13,84 @@ void usage(const char *argv0)
 {
     fprintf(stderr, "%s: Connect a remote USB device to the usbredir kernel module.\n", argv0);
     fprintf(stderr, "Usage:\n");
-    fprintf(stderr, "    %s devid server port [--attach attach]\n", argv0);
+    fprintf(stderr, "    %s devid < server port | --socket file > ] [--attach attach]\n", argv0);
     fprintf(stderr, "where devid is a unique identifier for this connection, server:port\n");
     fprintf(stderr, "is the address of a TCP server that is listening, waiting to export a USBREDIR device.\n");
-    fprintf(stderr, "Generally, you invoke %s to connect to a usbredirserver process.\n", argv0);
+    fprintf(stderr, "If you specify --socket, then you need to supply the name of a  UNIX domain socket.\n");
 }
 
+int connect_tcp(char *server, char *port)
+{
+    struct addrinfo hints, *res, *rp;
+    int rc;
+    int s;
+
+    memset(&hints, 0, sizeof(hints));
+    hints.ai_family = AF_INET;
+    hints.ai_socktype = SOCK_STREAM;
+    hints.ai_flags = AI_NUMERICSERV;
+
+    /* get all possible addresses */
+    rc = getaddrinfo(server, port, &hints, &res);
+    if (rc < 0)
+    {
+
+        fprintf(stderr, "Error resolving %s:%s\n", server, port);
+        return -1;
+    }
+
+    for (rp = res; rp; rp = rp->ai_next)
+    {
+        s = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
+        if (s < 0)
+        {
+            perror("socket");
+            return -2;
+        }
+
+        if (connect(s, rp->ai_addr, rp->ai_addrlen) == 0)
+            break;
+
+    }
+
+    if (! rp)
+    {
+        fprintf(stderr, "Error: unable to connect.\n");
+        return -3;
+    }
+
+    freeaddrinfo(res);
+
+    return s;
+}
+
+int connect_unix(char *fname)
+{
+    int s;
+    struct sockaddr_un addr;
+
+    s = socket(AF_UNIX, SOCK_STREAM, 0);
+    if (s < 0)
+    {
+        perror("socket");
+        return s;
+    }
+
+    memset(&addr, 0, sizeof(addr));
+    addr.sun_family = AF_UNIX;
+    strncpy(addr.sun_path, fname, sizeof(addr.sun_path)-1);
+
+    if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) != 0)
+    {
+        perror("connect");
+        return -1;
+    }
+
+    return s;
+}
 
 int main(int argc, char *argv[])
 {
-	struct addrinfo hints, *res, *rp;
-        int rc;
         int s;
         int fd;
         int i;
@@ -31,6 +99,7 @@ int main(int argc, char *argv[])
         char *devid = NULL;
         char *server = NULL;
         char *port = NULL;
+        int socket = 0;
 
 
         /* Poor man's argument parsing */
@@ -47,6 +116,17 @@ int main(int argc, char *argv[])
                 attach_file = argv[i];
                 break;
             }
+            else if (strcmp(argv[i], "--socket") == 0)
+            {
+                if (i == (argc - 1))
+                {
+                    fprintf(stderr, "Error: you must supply a path to the socket.\n");
+                    exit(1);
+                }
+                server = argv[++i];
+                socket = 1;
+                continue;
+            }
             else if (!devid)
                 devid = argv[i];
             else if (!server)
@@ -61,49 +141,20 @@ int main(int argc, char *argv[])
             }
         }
 
-        if (!devid || !server || !port)
+        if (!devid || (socket && !server) || (!socket && (!server || !port)))
         {
-            fprintf(stderr, "Error: specify device id, server and port\n");
+            fprintf(stderr, "Error: specify device id, and then server and port or --socket\n");
             usage(argv[0]);
             exit(1);
         }
 
-	memset(&hints, 0, sizeof(hints));
-	hints.ai_family = AF_INET;
-	hints.ai_socktype = SOCK_STREAM;
-	hints.ai_flags = AI_NUMERICSERV;
-
-	/* get all possible addresses */
-	rc = getaddrinfo(server, port, &hints, &res);
-	if (rc < 0)
-        {
-
-            fprintf(stderr, "Error resolving %s:%s\n", server, port);
-            exit(1);
-        }
-
-	for (rp = res; rp; rp = rp->ai_next)
-        {
-            s = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
-            if (s < 0)
-            {
-                perror("socket");
-                exit(2);
-            }
-
-            rc = connect(s, rp->ai_addr, rp->ai_addrlen);
-            if (rc == 0)
-                break;
-
-        }
-
-        if (! rp)
-        {
-            fprintf(stderr, "Error: unable to connect.\n");
-            exit(3);
-        }
+        if (socket)
+            s = connect_unix(server);
+        else
+            s = connect_tcp(server, port);
 
-	freeaddrinfo(res);
+        if (s < 0)
+            exit(s);
 
         fd = open(attach_file, O_WRONLY);
         if (fd == -1)
-- 
2.1.4



More information about the Spice-devel mailing list