X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=src%2Fcompat%2Fwindows%2Fwincompat.c;h=63f3e7de1469a6cc71a348c796aee6b7655763be;hb=f195c1bda3616129bc28d33aae71f9d2dd9047ce;hp=1a05d9f58551a91589472cf95d65211c46db5dca;hpb=473963ea000bfe23a0d4754988223e4e6e2fb3f2;p=catta diff --git a/src/compat/windows/wincompat.c b/src/compat/windows/wincompat.c index 1a05d9f..63f3e7d 100644 --- a/src/compat/windows/wincompat.c +++ b/src/compat/windows/wincompat.c @@ -3,6 +3,9 @@ #include #include #include +#include + +#include // helper: convert WSAGetLastError() to an errno constant static int wsa_errno(void) @@ -29,6 +32,33 @@ static int wsa_errno(void) } } +void winsock_init(void) +{ + WSADATA wsa; + int error; + + if((error = WSAStartup(MAKEWORD(2,2), &wsa)) != 0) + catta_log_error("WSAStartup() failed: %d", error); +} + +void winsock_exit(void) +{ + if(WSACleanup() == SOCKET_ERROR) + catta_log_warn("WSACleanup() failed: %d", WSAGetLastError()); +} + +char *errnostrsocket(void) +{ + static char buf[256]; + + int err = WSAGetLastError(); + int len = snprintf(buf, sizeof(buf), "[%i] ", err); + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, err, 0, buf + len, sizeof(buf) - len, NULL); + + return buf; +} + ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags) { LPFN_WSARECVMSG WSARecvMsg = NULL; @@ -190,6 +220,70 @@ ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags) return bytessent; } +int ioctl(int d, unsigned long request, int *p) +{ + u_long arg = *p; + + if(ioctlsocket(d, request, &arg) == SOCKET_ERROR) { + errno = wsa_errno(); + return -1; + } + + if(arg > INT_MAX) { + errno = EINVAL; + return -1; + } + + *p = arg; + return 0; +} + +int pipe(int pipefd[2]) +{ + int lsock = (int)INVALID_SOCKET; + struct sockaddr_in laddr; + socklen_t laddrlen = sizeof(laddr); + + pipefd[0] = pipefd[1] = (int)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; @@ -203,7 +297,8 @@ int uname(struct utsname *buf) strncpy(buf->version, "unknown", sizeof(buf->sysname)-1); // we don't need it // computer (node) name - if(GetComputerName(buf->nodename, sizeof(buf->nodename)-1) == 0) { + DWORD nodename_size = sizeof(buf->nodename)-1; + if(GetComputerName(buf->nodename, &nodename_size) == 0) { errno = EFAULT; return -1; }