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;
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 {
#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;
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;
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;
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);
}