]> git.meshlink.io Git - catta/blob - src/compat/windows/wincompat.h
readpipe/writepite/closepipe for fake pipes on Windows
[catta] / src / compat / windows / wincompat.h
1 #ifndef foowincompatfoo
2 #define foowincompatfoo
3
4 // This file and its companion wincompat.c provide some Posix interfaces to
5 // Windows APIs so the rest of the code can keep using them.
6
7
8 // require at least Windows Vista
9 #undef WINVER
10 #undef _WIN32_WINNT
11 #define WINVER 0x0600
12 #define _WIN32_WINNT WINVER
13
14 #include <winsock2.h>
15 #include <ws2tcpip.h>
16 #include <mswsock.h>
17
18
19 // wrappers around WSAStartup/WSACleanup to avoid clutter
20 void winsock_init(void);
21 void winsock_exit(void);
22
23
24 // the equivalent of strerror(errno) for Windows sockets
25 char *errnostrsocket(void);
26
27
28 // Winsock doesn't have recvmsg/sendmsg but offers the same functionality
29 // with WSARecvMsg/WSASendMsg, so we implement the former in terms of the
30 // latter.
31
32 struct iovec {                   /* Scatter/gather array items */
33    void  *iov_base;              /* Starting address */
34    size_t iov_len;               /* Number of bytes to transfer */
35 };
36
37 struct msghdr {
38    void         *msg_name;       /* optional address */
39    socklen_t     msg_namelen;    /* size of address */
40    struct iovec *msg_iov;        /* scatter/gather array */
41    size_t        msg_iovlen;     /* # elements in msg_iov */
42    void         *msg_control;    /* ancillary data, see below */
43    size_t        msg_controllen; /* ancillary data buffer len */
44    int           msg_flags;      /* flags on received message */
45 };
46
47 // MSDN says this struct is called wsacmsghdr but MingW uses _WSACMSGHDR.
48 // TODO: Verify what it is on actual Windows.
49 // cf. http://msdn.microsoft.com/en-us/library/ms741645(v=vs.85).aspx
50 #ifdef __MINGW32__
51 #define cmsghdr _WSACMSGHDR     // as in 'struct cmsghdr'
52 #else
53 #define cmsghdr wsacmsghdr      // as in 'struct cmsghdr'
54 #endif
55
56 static inline struct cmsghdr *CMSG_FIRSTHDR(struct msghdr *m) {
57     WSAMSG wm;
58     wm.Control.len = m->msg_controllen;
59     wm.Control.buf = m->msg_control;
60     return WSA_CMSG_FIRSTHDR(&wm);
61 }
62
63 static inline struct cmsghdr *CMSG_NXTHDR(struct msghdr *m, struct cmsghdr *c) {
64     WSAMSG wm;
65     wm.Control.len = m->msg_controllen;
66     wm.Control.buf = m->msg_control;
67     return WSA_CMSG_NXTHDR(&wm, c);
68 }
69
70 #define CMSG_SPACE(len) WSA_CMSG_SPACE(len)
71 #define CMSG_LEN(len) WSA_CMSG_LEN(len)
72
73 // we're going to be naughty and redefine CMSG_DATA as an alias even though it
74 // is also a constant defined in wincrypt.h which we don't care about.
75 #undef CMSG_DATA
76 #define CMSG_DATA(c) WSA_CMSG_DATA(c)
77
78 ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
79 ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
80
81 // ESHUTDOWN does not seem to exist on Windows, even though WSAESHUTDOWN does.
82 // MingW doesn't define it and MSDN doesn't list it, so we alias it to EBADF.
83 // cf. http://msdn.microsoft.com/en-us/library/5814770t.aspx
84 #ifndef ESHUTDOWN
85 #define ESHUTDOWN EBADF
86 #endif
87
88
89 // Windows doesn't have ioctl but offers ioctlsocket for some socket-related
90 // functions. Unfortunately, argument types differ, so we implement a
91 // (restricted) wrapper.
92 int ioctl(int d, unsigned long request, int *p);
93
94
95 // Windows lacks poll, but WSAPoll is good enough for us.
96 #define poll(fds, nfds, timeout) WSAPoll(fds, nfds, timeout)
97
98 // Windows lacks pipe. It has an equivalent CreatePipe but we really need
99 // something to give to WSAPoll, so we fake it with a local TCP socket. (ugh)
100 int pipe(int pipefd[2]);
101
102 // pipe(socket)-specific read/write/close equivalents
103 #define closepipe closesocket
104 #define writepipe(s,buf,len) send(s, buf, len, 0)
105 #define readpipe(s,buf,len) recv(s, buf, len, 0)
106
107
108 // Windows logically doesn't have uname, so we supply a replacement.
109
110 struct utsname {
111    char sysname[9];    /* Operating system name (e.g., "Linux") */
112    char nodename[MAX_COMPUTERNAME_LENGTH+1];
113                        /* Name within "some implementation-defined network" */
114    char release[9];    /* Operating system release (e.g., "2.6.28") */
115    char version[9];    /* Operating system version */
116    char machine[9];    /* Hardware identifier */
117 };
118
119 int uname(struct utsname *buf);
120
121
122 #endif