#include <assert.h>
#include <stdint.h>
+#include <catta/log.h>
+
// helper: convert WSAGetLastError() to an errno constant
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];
+
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, WSAGetLastError(), 0, buf, sizeof(buf), NULL);
+
+ return buf;
+}
+
ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags)
{
LPFN_WSARECVMSG WSARecvMsg = NULL;
msg->msg_flags = (int)wsamsg.dwFlags;
// all flags that fit into dwFlags also fit into msg_flags (see above)
+ catta_log_debug("recvmsg: %u bytes received", (unsigned int)bytesrcvd);
return bytesrcvd;
}
return -1;
}
+ // XXX debug, remove
+ {
+ char where[64];
+ struct sockaddr *sa = msg->msg_name;
+
+ if(sa->sa_family == AF_INET)
+ inet_ntop(sa->sa_family, &((struct sockaddr_in *)sa)->sin_addr, where, sizeof(where));
+ else
+ inet_ntop(sa->sa_family, &((struct sockaddr_in6 *)sa)->sin6_addr, where, sizeof(where));
+ catta_log_debug("sendmsg: %u bytes to %s", (unsigned int)bytessent, where);
+ }
return bytessent;
}
+int ioctl(int d, unsigned long request, int *p)
+{
+ u_long arg = 0;
+
+ 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 = 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;