luci-lib-nixio: always assume Linux target (#307)
[project/luci.git] / libs / luci-lib-nixio / src / mingw-compat.c
1 /*
2  * nixio - Linux I/O library for lua
3  *
4  *   Copyright (C) 2009 Steven Barth <steven@midlink.org>
5  *
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License.
17  */
18
19 #include "nixio.h"
20 #include <string.h>
21 #include <fcntl.h>
22 #include <errno.h>
23 #include <sys/locking.h>
24 #include <sys/time.h>
25 #include <sys/utime.h>
26
27 void nixio_open__mingw(lua_State *L) {
28         _fmode = _O_BINARY;
29
30         WSADATA wsa;
31
32         if (WSAStartup(MAKEWORD(2, 2), &wsa)) {
33                 luaL_error(L, "Unable to initialize Winsock");
34         }
35
36         lua_newtable(L);
37
38         NIXIO_WSA_CONSTANT(WSAEACCES);
39         NIXIO_WSA_CONSTANT(WSAEINTR);
40         NIXIO_WSA_CONSTANT(WSAEINVAL);
41         NIXIO_WSA_CONSTANT(WSAEBADF);
42         NIXIO_WSA_CONSTANT(WSAEFAULT);
43         NIXIO_WSA_CONSTANT(WSAEMFILE);
44         NIXIO_WSA_CONSTANT(WSAENAMETOOLONG);
45         NIXIO_WSA_CONSTANT(WSAELOOP);
46         NIXIO_WSA_CONSTANT(WSAEAFNOSUPPORT);
47         NIXIO_WSA_CONSTANT(WSAENOBUFS);
48         NIXIO_WSA_CONSTANT(WSAEPROTONOSUPPORT);
49         NIXIO_WSA_CONSTANT(WSAENOPROTOOPT);
50         NIXIO_WSA_CONSTANT(WSAEADDRINUSE);
51         NIXIO_WSA_CONSTANT(WSAENETDOWN);
52         NIXIO_WSA_CONSTANT(WSAENETUNREACH);
53         NIXIO_WSA_CONSTANT(WSAECONNABORTED);
54         NIXIO_WSA_CONSTANT(WSAECONNRESET);
55
56         lua_setfield(L, -2, "const_sock");
57 }
58
59 const char* nixio__mgw_inet_ntop
60 (int af, const void *src, char *dst, socklen_t size) {
61         struct sockaddr_storage saddr;
62         memset(&saddr, 0, sizeof(saddr));
63
64         DWORD hostlen = size, sl;
65         if (af == AF_INET) {
66                 struct sockaddr_in *saddr4 = (struct sockaddr_in *)&saddr;
67                 memcpy(&saddr4->sin_addr, src, sizeof(saddr4->sin_addr));
68                 saddr4->sin_family = AF_INET;
69                 saddr4->sin_port = 0;
70                 sl = sizeof(struct sockaddr_in);
71         } else if (af == AF_INET6) {
72                 struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)&saddr;
73                 memcpy(&saddr6->sin6_addr, src, sizeof(saddr6->sin6_addr));
74                 saddr6->sin6_family = AF_INET6;
75                 saddr6->sin6_port = 0;
76                 sl = sizeof(struct sockaddr_in6);
77         } else {
78                 return NULL;
79         }
80         if (WSAAddressToString((struct sockaddr*)&saddr, sl, NULL, dst, &hostlen)) {
81                 return NULL;
82         }
83         return dst;
84 }
85
86 int nixio__mgw_inet_pton (int af, const char *src, void *dst) {
87         struct sockaddr_storage sa;
88         int sl = sizeof(sa);
89
90         if (!WSAStringToAddress((char*)src, af, NULL, (struct sockaddr*)&sa, &sl)) {
91                 if (af == AF_INET) {
92                         struct in_addr ina = ((struct sockaddr_in *)&sa)->sin_addr;
93                         memcpy(dst, &ina, sizeof(ina));
94                         return 1;
95                 } else if (af == AF_INET6) {
96                         struct in_addr6 ina6 = ((struct sockaddr_in6 *)&sa)->sin6_addr;
97                         memcpy(dst, &ina6, sizeof(ina6));
98                         return 1;
99                 } else {
100                         WSASetLastError(WSAEAFNOSUPPORT);
101                         return -1;
102                 }
103         } else {
104                 return -1;
105         }
106 }
107
108 int nixio__mgw_nanosleep(const struct timespec *req, struct timespec *rem) {
109         if (rem) {
110                 rem->tv_sec = 0;
111                 rem->tv_nsec = 0;
112         }
113         Sleep(req->tv_sec * 1000 + req->tv_nsec * 1000000);
114         return 0;
115 }
116
117 int nixio__mgw_poll(struct pollfd *fds, int nfds, int timeout) {
118         if (!fds || !nfds) {
119                 Sleep(timeout);
120                 return 0;
121         }
122
123         struct timeval tv;
124         int high = 0, rf = 0, wf = 0, ef = 0;
125         fd_set rfds, wfds, efds;
126         FD_ZERO(&rfds);
127         FD_ZERO(&wfds);
128         FD_ZERO(&efds);
129
130         tv.tv_sec = timeout / 1000;
131         tv.tv_usec = (timeout % 1000) * 1000;
132
133         for (int i = 0; i < nfds; i++) {
134                 if (fds->events & POLLIN) {
135                         FD_SET(fds->fd, &rfds);
136                         rf++;
137                 }
138                 if (fds->events & POLLOUT) {
139                         FD_SET(fds->fd, &wfds);
140                         wf++;
141                 }
142                 if (fds->events & POLLERR) {
143                         FD_SET(fds->fd, &efds);
144                         ef++;
145                 }
146                 if (fds->fd > high) {
147                         high = fds->fd;
148                 }
149         }
150
151         int stat = select(high + 1, (rf) ? &rfds : NULL,
152          (wf) ? &wfds : NULL, (ef) ? &efds : NULL, &tv);
153         if (stat < 1) {
154                 errno = WSAGetLastError();
155                 return stat;
156         }
157
158         high = 0;
159
160         for (int i = 0; i < nfds; i++) {
161                 fds->revents = 0;
162                 if ((fds->events & POLLIN) && FD_ISSET(fds->fd, &rfds)) {
163                         fds->revents |= POLLIN;
164                 }
165                 if ((fds->events & POLLOUT) && FD_ISSET(fds->fd, &wfds)) {
166                         fds->revents |= POLLOUT;
167                 }
168                 if ((fds->events & POLLERR) && FD_ISSET(fds->fd, &efds)) {
169                         fds->revents |= POLLERR;
170                 }
171                 if (fds->revents) {
172                         high++;
173                 }
174         }
175
176         return high;
177 }
178
179 int nixio__mgw_lockf(int fd, int cmd, off_t len) {
180         int stat;
181         if (cmd == F_LOCK) {
182                 do {
183                         stat = _locking(fd, _LK_LOCK, len);
184                 } while (stat == -1 && errno == EDEADLOCK);
185         } else if (cmd == F_TLOCK) {
186                 stat = _locking(fd, _LK_NBLCK, len);
187         } else if (cmd == F_ULOCK) {
188                 stat = _locking(fd, _LK_UNLCK, len);
189         } else {
190                 stat = -1;
191                 errno = EINVAL;
192         }
193         return stat;
194 }
195
196 char* nixio__mgw_realpath(const char *path, char *resolved) {
197         if (GetFullPathName(path, PATH_MAX, resolved, NULL)) {
198                 return resolved;
199         } else {
200                 errno = GetLastError();
201                 return NULL;
202         }
203 }
204
205 int nixio__mgw_link(const char *oldpath, const char *newpath) {
206         if (!CreateHardLink(newpath, oldpath, NULL)) {
207                 errno = GetLastError();
208                 return -1;
209         } else {
210                 return 0;
211         }
212 }
213
214 int nixio__mgw_utimes(const char *filename, const struct timeval times[2]) {
215         struct _utimbuf timebuffer;
216         timebuffer.actime = times[0].tv_sec;
217         timebuffer.modtime = times[1].tv_sec;
218
219         return _utime(filename, &timebuffer);
220 }