diff --git a/configure.ac b/configure.ac index 2d7a172899d5660957f8334eb04cd4498d85efa5..ccdf990bf7631c6e5e4aafa60ebfee3cc07c3a38 100644 --- a/configure.ac +++ b/configure.ac @@ -186,6 +186,11 @@ AC_SUBST(xcbincludedir) XCB_CHECK_VISIBILITY() AC_CHECK_FUNC(getaddrinfo, [AC_DEFINE(HAVE_GETADDRINFO, 1, [getaddrinfo() function is available])], ) +AC_CHECK_HEADER([linux/vm_sockets.h], [], [AC_DEFINE(HAVE_VSOCK_H, 1, [Define to 1 if you have the header file.])], +[#ifdef HAVE_VSOCK_H +#include +#endif +]) case $host_os in # darwin through Snow Leopard has poll() but can't be used to poll character devices. diff --git a/src/xcb_util.c b/src/xcb_util.c index 0296ce0dd55b34da4c9a8a05dbf953b55ad997e8..da346e62d7835de5ab8707501276af1ff5bf862a 100644 --- a/src/xcb_util.c +++ b/src/xcb_util.c @@ -44,6 +44,9 @@ #include #include #include +#ifdef HAVE_VSOCK_H +#include +#endif #include #include #include @@ -216,6 +219,9 @@ int xcb_parse_display(const char *name, char **host, int *displayp, } static int _xcb_open_tcp(const char *host, char *protocol, const unsigned short port); +#ifdef HAVE_VSOCK_H +static int _xcb_open_vsock(const char *host, char *protocol, const unsigned short port); +#endif #ifndef _WIN32 static int _xcb_open_unix(char *protocol, const char *file); #endif /* !WIN32 */ @@ -236,6 +242,14 @@ static int _xcb_open(const char *host, char *protocol, const int display) char *file = NULL; int actual_filelen; +#ifdef HAVE_VSOCK_H + if (protocol && (strcmp("vsock",protocol) == 0)) + { + unsigned short port = X_TCP_PORT + display; + return _xcb_open_vsock(host, protocol, port); + } +#endif + /* If protocol or host is "unix", fall through to Unix socket code below */ if ((!protocol || (strcmp("unix",protocol) != 0)) && (*host != '\0') && (strcmp("unix",host) != 0)) @@ -429,6 +443,49 @@ static int _xcb_open_tcp(const char *host, char *protocol, const unsigned short #endif } +#ifdef HAVE_VSOCK_H +static int _xcb_open_vsock(const char *host, char *protocol, const unsigned short port) +{ + struct sockaddr_vm savm; + int fd; + + if(protocol && strcmp("vsock",protocol)) + return -1; + + fd = _xcb_socket(AF_VSOCK, SOCK_STREAM, 0); + if(fd == -1) + return -1; + + { + socklen_t len = sizeof(int); + int val = 0; + + if((getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &val, &len) == 0) && (val < (64 * 1024))) + { + val = (64 * 1024); + setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &val, sizeof(int)); + } + } + + memset(&savm, 0, sizeof(savm)); + + savm.svm_family = AF_VSOCK; + savm.svm_cid = VMADDR_CID_HOST; + + if(*host != '\0') + savm.svm_cid = (unsigned int)atoi(host); + + savm.svm_port = port; + + if(connect(fd, (struct sockaddr*)&savm, sizeof(savm)) == -1) + { + close(fd); + return -1; + } + return fd; +} +#endif + #ifndef _WIN32 static int _xcb_open_unix(char *protocol, const char *file) {