]> git.meshlink.io Git - catta/commitdiff
add an alias for poll and implement pipe in terms of sockets
authorSven M. Hallberg <pesco@khjk.org>
Mon, 1 Sep 2014 21:21:27 +0000 (23:21 +0200)
committerSven M. Hallberg <pesco@khjk.org>
Mon, 1 Sep 2014 21:26:05 +0000 (23:26 +0200)
src/compat/windows/wincompat.c
src/compat/windows/wincompat.h
src/simple-watch.c

index 67cf85364b9047097d82ec6434128c8c31871ecb..4433b5b54648be93ff1fec50c7baa2674a74d11f 100644 (file)
@@ -208,6 +208,52 @@ int ioctl(int d, unsigned long request, int *p)
     return 0;
 }
 
+int pipe(int pipefd[2])
+{
+    int lsock = INVALID_SOCKET;
+    struct sockaddr_in laddr;
+    socklen_t laddrlen = sizeof(laddr);
+
+    pipefd[0] = pipefd[1] = INVALID_SOCKET;
+
+    // bind a listening socket to a TCP port on localhost
+    laddr.sin_family = AF_INET;
+    laddr.sin_port = 0;
+    laddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+    if((lsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == SOCKET_ERROR)
+        goto fail;
+    if(bind(lsock, (struct sockaddr *)&laddr, sizeof(laddr)) == SOCKET_ERROR)
+        goto fail;
+    if(listen(lsock, 1) == SOCKET_ERROR)
+        goto fail;
+
+    // determine which address (i.e. port) we got bound to
+    if(getsockname(lsock, (struct sockaddr *)&laddr, &laddrlen) == SOCKET_ERROR)
+        goto fail;
+    assert(laddrlen == sizeof(laddr));
+    laddr.sin_family = AF_INET;
+    laddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+    // connect and accept
+    if((pipefd[0] = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == SOCKET_ERROR)
+        goto fail;
+    if(connect(pipefd[0], (const struct sockaddr *)&laddr, sizeof(laddr)) == SOCKET_ERROR)
+        goto fail;
+    if((pipefd[1] = accept(lsock, NULL, NULL)) == SOCKET_ERROR)
+        goto fail;
+
+    // close the listener
+    closesocket(lsock);
+
+    return 0;
+
+fail:
+    errno = wsa_errno();
+    closesocket(pipefd[0]);
+    closesocket(lsock);
+    return -1;
+}
+
 int uname(struct utsname *buf)
 {
     SYSTEM_INFO si;
index b5020226a8e5465ea406bc56105e3d61a7fdd0c9..c736f75f938dc03868c75accbad1354239e21d37 100644 (file)
@@ -83,6 +83,14 @@ ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
 int ioctl(int d, unsigned long request, int *p);
 
 
+// Windows lacks poll, but WSAPoll is good enough for us.
+#define poll(fds, nfds, timeout) WSAPoll(fds, nfds, timeout)
+
+// Windows lacks pipe. It has an equivalent CreatePipe but we really need
+// something to give to WSAPoll, so we fake it with a local TCP socket. (ugh)
+int pipe(int pipefd[2]);
+
+
 // Windows logically doesn't have uname, so we supply a replacement.
 
 struct utsname {
index 253ad501533282b0c8b48db64d31340d426fba77..77da9f84e0e3a099e71ee0f56b27bc13cd475a27 100644 (file)
@@ -33,6 +33,8 @@
 #include <catta/malloc.h>
 #include <catta/timeval.h>
 #include <catta/simple-watch.h>
+#include "fdutil.h"                 // catta_set_nonblock
+#include "internal.h"               // closesocket
 
 struct CattaWatch {
     CattaSimplePoll *simple_poll;
@@ -115,20 +117,6 @@ static void clear_wakeup(CattaSimplePoll *s) {
             break;
 }
 
-static int set_nonblock(int fd) {
-    int n;
-
-    assert(fd >= 0);
-
-    if ((n = fcntl(fd, F_GETFL)) < 0)
-        return -1;
-
-    if (n & O_NONBLOCK)
-        return 0;
-
-    return fcntl(fd, F_SETFL, n|O_NONBLOCK);
-}
-
 static CattaWatch* watch_new(const CattaPoll *api, int fd, CattaWatchEvent event, CattaWatchCallback callback, void *userdata) {
     CattaWatch *w;
     CattaSimplePoll *s;
@@ -326,8 +314,8 @@ CattaSimplePoll *catta_simple_poll_new(void) {
         return NULL;
     }
 
-    set_nonblock(s->wakeup_pipe[0]);
-    set_nonblock(s->wakeup_pipe[1]);
+    catta_set_nonblock(s->wakeup_pipe[0]);
+    catta_set_nonblock(s->wakeup_pipe[1]);
 
     s->api.userdata = s;
 
@@ -374,10 +362,10 @@ void catta_simple_poll_free(CattaSimplePoll *s) {
     catta_free(s->pollfds);
 
     if (s->wakeup_pipe[0] >= 0)
-        close(s->wakeup_pipe[0]);
+        closesocket(s->wakeup_pipe[0]);
 
     if (s->wakeup_pipe[1] >= 0)
-        close(s->wakeup_pipe[1]);
+        closesocket(s->wakeup_pipe[1]);
 
     catta_free(s);
 }