1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
10 /* Some of our own infrastructure where the Winsock stuff was too hairy
11 * to dump into a clean Unix program */
13 typedef WSABUF sg_buf;
15 #define SG_ADVANCE(SG, N) \
18 : ((SG)->buf += (N), (SG)->len -= (N), 0))
20 #define SG_LEN(SG) ((SG)->len + 0)
21 #define SG_BUF(SG) ((SG)->buf + 0)
22 #define SG_SET(SG, B, N) ((SG)->buf = (char *)(B),(SG)->len = (N))
24 #define SOCKET_INITIALIZE() 0
25 #define SOCKET_CLEANUP()
26 #define SOCKET_ERRNO (TranslatedWSAGetLastError())
27 #define SOCKET_SET_ERRNO(x) (TranslatedWSASetLastError(x))
28 #define SOCKET_NFDS(f) (0) /* select()'s first arg is ignored */
29 #define SOCKET_READ(fd, b, l) (recv(fd, b, l, 0))
30 #define SOCKET_WRITE(fd, b, l) (send(fd, b, l, 0))
31 #define SOCKET_CONNECT connect /* XXX */
32 #define SOCKET_GETSOCKNAME getsockname /* XXX */
33 #define SOCKET_CLOSE close /* XXX */
34 #define SOCKET_EINTR WSAEINTR
37 * Return -1 for error or number of bytes written. TMP is a temporary
38 * variable; must be declared by the caller, and must be used by this macro (to
39 * avoid compiler warnings).
41 /* WSASend returns 0 or SOCKET_ERROR. */
42 #define SOCKET_WRITEV_TEMP DWORD
43 #define SOCKET_WRITEV(FD, SG, LEN, TMP) \
44 (WSASend((FD), (SG), (LEN), &(TMP), 0, 0, 0) ? \
45 (ssize_t)-1 : (ssize_t)(TMP))
47 #define SHUTDOWN_READ SD_RECEIVE
48 #define SHUTDOWN_WRITE SD_SEND
49 #define SHUTDOWN_BOTH SD_BOTH
52 * Define any missing POSIX socket errors. This is for compatibility with
53 * older versions of MSVC (pre-2010).
56 #define EINPROGRESS WSAEINPROGRESS
59 #define EWOULDBLOCK WSAEWOULDBLOCK
62 #define ECONNRESET WSAECONNRESET
65 #define ECONNABORTED WSAECONNABORTED
68 #define ECONNREFUSED WSAECONNREFUSED
71 #define EHOSTUNREACH WSAEHOSTUNREACH
74 #define ETIMEDOUT WSAETIMEDOUT
77 /* Translate posix_error to its Winsock counterpart and set the last Winsock
78 * error to the result. */
79 static __inline void TranslatedWSASetLastError(int posix_error)
82 switch (posix_error) {
86 wsa_error = WSAEINPROGRESS; break;
88 wsa_error = WSAEWOULDBLOCK; break;
90 wsa_error = WSAECONNRESET; break;
92 wsa_error = WSAECONNABORTED; break;
94 wsa_error = WSAECONNREFUSED; break;
96 wsa_error = WSAEHOSTUNREACH; break;
98 wsa_error = WSAETIMEDOUT; break;
100 wsa_error = WSAEAFNOSUPPORT; break;
102 wsa_error = WSAEINVAL; break;
104 /* Ideally, we would log via k5-trace here, but we have no context. */
105 wsa_error = WSAEINVAL; break;
107 WSASetLastError(wsa_error);
111 * Translate Winsock errors to their POSIX counterparts. This is necessary for
112 * MSVC 2010+, where both Winsock and POSIX errors are defined.
114 static __inline int TranslatedWSAGetLastError()
116 int err = WSAGetLastError();
121 err = EINPROGRESS; break;
123 err = EWOULDBLOCK; break;
125 err = ECONNRESET; break;
126 case WSAECONNABORTED:
127 err = ECONNABORTED; break;
128 case WSAECONNREFUSED:
129 err = ECONNREFUSED; break;
130 case WSAEHOSTUNREACH:
131 err = EHOSTUNREACH; break;
133 err = ETIMEDOUT; break;
134 case WSAEAFNOSUPPORT:
135 err = EAFNOSUPPORT; break;
139 /* Ideally, we would log via k5-trace here, but we have no context. */
145 #elif defined(__palmos__)
147 /* If this source file requires it, define struct sockaddr_in (and possibly
148 * other things related to network I/O). */
150 #include "autoconf.h"
152 typedef int socklen_t;
154 #else /* UNIX variants */
156 #include "autoconf.h"
158 #include <sys/types.h>
159 #include <netinet/in.h> /* For struct sockaddr_in and in_addr */
160 #include <arpa/inet.h> /* For inet_ntoa */
162 #include <string.h> /* For memset */
164 #ifndef HAVE_NETDB_H_H_ERRNO
165 extern int h_errno; /* In case it's missing, e.g., HP-UX 10.20. */
168 #include <sys/param.h> /* For MAXHOSTNAMELEN */
169 #include <sys/socket.h> /* For SOCK_*, AF_*, etc */
170 #include <sys/time.h> /* For struct timeval */
171 #include <net/if.h> /* For struct ifconf, for localaddr.c */
172 #ifdef HAVE_SYS_UIO_H
173 #include <sys/uio.h> /* For struct iovec, for sg_buf */
175 #ifdef HAVE_SYS_FILIO_H
176 #include <sys/filio.h> /* For FIONBIO on Solaris. */
180 * Either size_t or int or unsigned int is probably right. Under
181 * SunOS 4, it looks like int is desired, according to the accept man
184 #ifndef HAVE_SOCKLEN_T
185 typedef int socklen_t;
188 #ifndef HAVE_STRUCT_SOCKADDR_STORAGE
189 struct krb5int_sockaddr_storage {
190 struct sockaddr_in s;
191 /* Plenty of slop just in case we get an ipv6 address anyways. */
194 #define sockaddr_storage krb5int_sockaddr_storage
197 /* Unix equivalents of Winsock calls */
199 #define INVALID_SOCKET ((SOCKET)~0)
200 #define closesocket close
201 #define ioctlsocket ioctl
202 #define SOCKET_ERROR (-1)
204 typedef struct iovec sg_buf;
206 #define SG_ADVANCE(SG, N) \
207 ((SG)->iov_len < (N) \
209 : ((SG)->iov_base = (char *) (SG)->iov_base + (N), \
210 (SG)->iov_len -= (N), 0))
212 #define SG_LEN(SG) ((SG)->iov_len + 0)
213 #define SG_BUF(SG) ((char*)(SG)->iov_base + 0)
214 #define SG_SET(SG, B, L) ((SG)->iov_base = (char*)(B), (SG)->iov_len = (L))
216 #define SOCKET_INITIALIZE() (0) /* No error (or anything else) */
217 #define SOCKET_CLEANUP() /* nothing */
218 #define SOCKET_ERRNO errno
219 #define SOCKET_SET_ERRNO(x) (errno = (x))
220 #define SOCKET_NFDS(f) ((f)+1) /* select() arg for a single fd */
221 #define SOCKET_READ read
222 #define SOCKET_WRITE write
224 socket_connect(int fd, const struct sockaddr *addr, socklen_t addrlen)
231 st = connect(fd, addr, addrlen);
236 st = setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &set, sizeof(set));
243 #define SOCKET_CONNECT socket_connect
244 #define SOCKET_GETSOCKNAME getsockname
245 #define SOCKET_CLOSE close
246 #define SOCKET_EINTR EINTR
247 #define SOCKET_WRITEV_TEMP int
248 static inline ssize_t
249 socket_sendmsg(SOCKET fd, sg_buf *iov, int iovcnt)
255 flags |= MSG_NOSIGNAL;
258 memset(&msg, 0, sizeof(msg));
260 msg.msg_iovlen = iovcnt;
262 return sendmsg(fd, &msg, flags);
264 /* Use TMP to avoid compiler warnings and keep things consistent with
265 * Windows version. */
266 #define SOCKET_WRITEV(FD, SG, LEN, TMP) \
267 ((TMP) = socket_sendmsg((FD), (SG), (LEN)), (TMP))
269 #define SHUTDOWN_READ 0
270 #define SHUTDOWN_WRITE 1
271 #define SHUTDOWN_BOTH 2
273 #ifndef HAVE_INET_NTOP
274 #define inet_ntop(AF,SRC,DST,CNT) \
277 ? (SOCKET_SET_ERRNO(ENOSPC), (const char *)NULL) \
278 : (sprintf((DST), "%d.%d.%d.%d", \
279 ((const unsigned char *)(const void *)(SRC))[0] & 0xff, \
280 ((const unsigned char *)(const void *)(SRC))[1] & 0xff, \
281 ((const unsigned char *)(const void *)(SRC))[2] & 0xff, \
282 ((const unsigned char *)(const void *)(SRC))[3] & 0xff), \
284 : (SOCKET_SET_ERRNO(EAFNOSUPPORT), (const char *)NULL))
285 #define HAVE_INET_NTOP
293 extern int socket (int, int, int) /*@*/;
297 #endif /*_PORT_SOCKET_H*/