Import LibreSSL v2.4.2 to vendor branch
[dragonfly.git] / crypto / libressl / crypto / compat / posix_win.c
blob110323a3df373b7952a5068d9b79d13890aa4679
1 /*
2 * Public domain
4 * BSD socket emulation code for Winsock2
5 * File IO compatibility shims
6 * Brent Cook <bcook@openbsd.org>
7 */
9 #define NO_REDEF_POSIX_FUNCTIONS
11 #include <windows.h>
12 #include <ws2tcpip.h>
14 #include <errno.h>
15 #include <stdint.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <unistd.h>
21 void
22 posix_perror(const char *s)
24 fprintf(stderr, "%s: %s\n", s, strerror(errno));
27 FILE *
28 posix_fopen(const char *path, const char *mode)
30 if (strchr(mode, 'b') == NULL) {
31 char *bin_mode = NULL;
32 if (asprintf(&bin_mode, "%sb", mode) == -1)
33 return NULL;
34 FILE *f = fopen(path, bin_mode);
35 free(bin_mode);
36 return f;
39 return fopen(path, mode);
42 char *
43 posix_fgets(char *s, int size, FILE *stream)
45 char *ret = fgets(s, size, stream);
46 if (ret != NULL) {
47 size_t end = strlen(ret);
48 if (end >= 2 && ret[end - 2] == '\r' && ret[end - 1] == '\n') {
49 ret[end - 2] = '\n';
50 ret[end - 1] = '\0';
53 return ret;
56 int
57 posix_rename(const char *oldpath, const char *newpath)
59 return MoveFileEx(oldpath, newpath, MOVEFILE_REPLACE_EXISTING) ? 0 : -1;
62 static int
63 wsa_errno(int err)
65 switch (err) {
66 case WSAENOBUFS:
67 errno = ENOMEM;
68 break;
69 case WSAEACCES:
70 errno = EACCES;
71 break;
72 case WSANOTINITIALISED:
73 errno = EPERM;
74 break;
75 case WSAEHOSTUNREACH:
76 case WSAENETDOWN:
77 errno = EIO;
78 break;
79 case WSAEFAULT:
80 errno = EFAULT;
81 break;
82 case WSAEINTR:
83 errno = EINTR;
84 break;
85 case WSAEINVAL:
86 errno = EINVAL;
87 break;
88 case WSAEINPROGRESS:
89 errno = EINPROGRESS;
90 break;
91 case WSAEWOULDBLOCK:
92 errno = EAGAIN;
93 break;
94 case WSAEOPNOTSUPP:
95 errno = ENOTSUP;
96 break;
97 case WSAEMSGSIZE:
98 errno = EFBIG;
99 break;
100 case WSAENOTSOCK:
101 errno = ENOTSOCK;
102 break;
103 case WSAENOPROTOOPT:
104 errno = ENOPROTOOPT;
105 break;
106 case WSAECONNREFUSED:
107 errno = ECONNREFUSED;
108 break;
109 case WSAEAFNOSUPPORT:
110 errno = EAFNOSUPPORT;
111 break;
112 case WSAENETRESET:
113 case WSAENOTCONN:
114 case WSAECONNABORTED:
115 case WSAECONNRESET:
116 case WSAESHUTDOWN:
117 case WSAETIMEDOUT:
118 errno = EPIPE;
119 break;
121 return -1;
125 posix_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
127 int rc = connect(sockfd, addr, addrlen);
128 if (rc == SOCKET_ERROR)
129 return wsa_errno(WSAGetLastError());
130 return rc;
134 posix_close(int fd)
136 if (closesocket(fd) == SOCKET_ERROR) {
137 int err = WSAGetLastError();
138 return err == WSAENOTSOCK ?
139 close(fd) : wsa_errno(err);
141 return 0;
144 ssize_t
145 posix_read(int fd, void *buf, size_t count)
147 ssize_t rc = recv(fd, buf, count, 0);
148 if (rc == SOCKET_ERROR) {
149 int err = WSAGetLastError();
150 return err == WSAENOTSOCK ?
151 read(fd, buf, count) : wsa_errno(err);
153 return rc;
156 ssize_t
157 posix_write(int fd, const void *buf, size_t count)
159 ssize_t rc = send(fd, buf, count, 0);
160 if (rc == SOCKET_ERROR) {
161 int err = WSAGetLastError();
162 return err == WSAENOTSOCK ?
163 write(fd, buf, count) : wsa_errno(err);
165 return rc;
169 posix_getsockopt(int sockfd, int level, int optname,
170 void *optval, socklen_t *optlen)
172 int rc = getsockopt(sockfd, level, optname, (char *)optval, optlen);
173 return rc == 0 ? 0 : wsa_errno(WSAGetLastError());
178 posix_setsockopt(int sockfd, int level, int optname,
179 const void *optval, socklen_t optlen)
181 int rc = setsockopt(sockfd, level, optname, (char *)optval, optlen);
182 return rc == 0 ? 0 : wsa_errno(WSAGetLastError());
185 #ifdef _MSC_VER
186 int gettimeofday(struct timeval * tp, struct timezone * tzp)
189 * Note: some broken versions only have 8 trailing zero's, the correct
190 * epoch has 9 trailing zero's
192 static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL);
194 SYSTEMTIME system_time;
195 FILETIME file_time;
196 uint64_t time;
198 GetSystemTime(&system_time);
199 SystemTimeToFileTime(&system_time, &file_time);
200 time = ((uint64_t)file_time.dwLowDateTime);
201 time += ((uint64_t)file_time.dwHighDateTime) << 32;
203 tp->tv_sec = (long)((time - EPOCH) / 10000000L);
204 tp->tv_usec = (long)(system_time.wMilliseconds * 1000);
205 return 0;
208 unsigned int sleep(unsigned int seconds)
210 Sleep(seconds * 1000);
211 return seconds;
214 #endif