]> git.meshlink.io Git - catta/blob - src/compat/windows/wincompat.h
fix gcc mingw compile (gcc 5.1 x86_64)
[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 #include <sys/types.h>
18
19
20 // wrappers around WSAStartup/WSACleanup to avoid clutter
21 void winsock_init(void);
22 void winsock_exit(void);
23
24
25 // the equivalent of strerror(errno) for Windows sockets
26 char *errnostrsocket(void);
27
28
29 // Winsock doesn't have recvmsg/sendmsg but offers the same functionality
30 // with WSARecvMsg/WSASendMsg, so we implement the former in terms of the
31 // latter.
32
33 struct iovec {                   /* Scatter/gather array items */
34    void  *iov_base;              /* Starting address */
35    size_t iov_len;               /* Number of bytes to transfer */
36 };
37
38 struct msghdr {
39    void         *msg_name;       /* optional address */
40    socklen_t     msg_namelen;    /* size of address */
41    struct iovec *msg_iov;        /* scatter/gather array */
42    size_t        msg_iovlen;     /* # elements in msg_iov */
43    void         *msg_control;    /* ancillary data, see below */
44    size_t        msg_controllen; /* ancillary data buffer len */
45    int           msg_flags;      /* flags on received message */
46 };
47
48 // MSDN says this struct is called wsacmsghdr but MingW uses _WSACMSGHDR.
49 // TODO: Verify what it is on actual Windows.
50 // cf. http://msdn.microsoft.com/en-us/library/ms741645(v=vs.85).aspx
51 // -->
52 // MingW32 x86 4.8.1 uses wsacmsghdr, MingW x86_x64 uses _WSACMSGHDR and Visual Studio 2015 RC (ws2def.h) defines:
53 // #if(_WIN32_WINNT >= 0x0600)
54 // #define _WSACMSGHDR cmsghdr
55 // #endif //(_WIN32_WINNT>=0x0600)
56 // typedef struct _WSACMSGHDR {
57 //     SIZE_T      cmsg_len;
58 //     INT         cmsg_level;
59 //     INT         cmsg_type;
60 //     /* followed by UCHAR cmsg_data[] */
61 // } WSACMSGHDR, *PWSACMSGHDR, FAR *LPWSACMSGHDR;
62 #ifdef __MINGW32__
63   #ifdef __MINGW64_VERSION_MAJOR
64     #define cmsghdr _WSACMSGHDR     // as in 'struct cmsghdr'
65   #else
66     #define cmsghdr wsacmsghdr      // as in 'struct cmsghdr'
67   #endif
68 #elif (_WIN32_WINNT < 0x0600)
69   #define cmsghdr _WSACMSGHDR
70 #endif
71
72 // VS2015 ws2def.h already defines: #define CMSG_FIRSTHDR WSA_CMSG_FIRSTHDR
73 #ifdef CMSG_FIRSTHDR
74 #undef CMSG_FIRSTHDR
75 #endif
76 static inline struct cmsghdr *CMSG_FIRSTHDR(struct msghdr *m) {
77     WSAMSG wm;
78     wm.Control.len = m->msg_controllen;
79     wm.Control.buf = (char*)m->msg_control;
80     return WSA_CMSG_FIRSTHDR(&wm);
81 }
82
83 // VS2015 ws2def.h already defines: #define CMSG_NXTHDR WSA_CMSG_NXTHDR
84 #ifdef CMSG_NXTHDR
85 #undef CMSG_NXTHDR
86 #endif
87 static inline struct cmsghdr *CMSG_NXTHDR(struct msghdr *m, struct cmsghdr *c) {
88     WSAMSG wm;
89     wm.Control.len = m->msg_controllen;
90     wm.Control.buf = (char*)m->msg_control;
91     return WSA_CMSG_NXTHDR(&wm, c);
92 }
93
94 #ifndef CMSG_SPACE
95  #define CMSG_SPACE(len) WSA_CMSG_SPACE(len)
96 #endif
97 #ifndef CMSG_LEN
98  #define CMSG_LEN(len) WSA_CMSG_LEN(len)
99 #endif
100
101 // we're going to be naughty and redefine CMSG_DATA as an alias even though it
102 // is also a constant defined in wincrypt.h which we don't care about.
103 #undef CMSG_DATA
104 #define CMSG_DATA(c) WSA_CMSG_DATA(c)
105
106 #ifdef _MSC_VER
107    // VS2012 and up has no ssize_t defined, before it was defined as unsigned int
108    #ifndef _SSIZE_T
109    #define _SSIZE_T
110    typedef signed int        ssize_t;
111    #endif
112 #endif
113
114 ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);
115 ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);
116
117 // ESHUTDOWN does not seem to exist on Windows, even though WSAESHUTDOWN does.
118 // MingW doesn't define it and MSDN doesn't list it, so we alias it to EBADF.
119 // cf. http://msdn.microsoft.com/en-us/library/5814770t.aspx
120 #ifndef ESHUTDOWN
121 #define ESHUTDOWN EBADF
122 #endif
123
124
125 // Windows doesn't have ioctl but offers ioctlsocket for some socket-related
126 // functions. Unfortunately, argument types differ, so we implement a
127 // (restricted) wrapper.
128 int ioctl(int d, unsigned long request, int *p);
129
130
131 // Windows lacks poll, but WSAPoll is good enough for us.
132 #define poll(fds, nfds, timeout) WSAPoll(fds, nfds, timeout)
133
134 // Windows lacks pipe. It has an equivalent CreatePipe but we really need
135 // something to give to WSAPoll, so we fake it with a local TCP socket. (ugh)
136 int pipe(int pipefd[2]);
137
138 // pipe(socket)-specific read/write/close equivalents
139 #define closepipe closesocket
140 #define writepipe(s,buf,len) send(s, buf, len, 0)
141 #define readpipe(s,buf,len) recv(s, buf, len, 0)
142
143
144 // Windows logically doesn't have uname, so we supply a replacement.
145
146 struct utsname {
147    char sysname[9];    /* Operating system name (e.g., "Linux") */
148    char nodename[MAX_COMPUTERNAME_LENGTH+1];
149                        /* Name within "some implementation-defined network" */
150    char release[9];    /* Operating system release (e.g., "2.6.28") */
151    char version[9];    /* Operating system version */
152    char machine[9];    /* Hardware identifier */
153 };
154
155 int uname(struct utsname *buf);
156
157
158 #endif