diff options
Diffstat (limited to 'libs/luci-lib-nixio/src/mingw-compat.c')
-rw-r--r-- | libs/luci-lib-nixio/src/mingw-compat.c | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/libs/luci-lib-nixio/src/mingw-compat.c b/libs/luci-lib-nixio/src/mingw-compat.c new file mode 100644 index 000000000..02be504a1 --- /dev/null +++ b/libs/luci-lib-nixio/src/mingw-compat.c @@ -0,0 +1,220 @@ +/* + * nixio - Linux I/O library for lua + * + * Copyright (C) 2009 Steven Barth <steven@midlink.org> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "nixio.h" +#include <string.h> +#include <fcntl.h> +#include <errno.h> +#include <sys/locking.h> +#include <sys/time.h> +#include <sys/utime.h> + +void nixio_open__mingw(lua_State *L) { + _fmode = _O_BINARY; + + WSADATA wsa; + + if (WSAStartup(MAKEWORD(2, 2), &wsa)) { + luaL_error(L, "Unable to initialize Winsock"); + } + + lua_newtable(L); + + NIXIO_WSA_CONSTANT(WSAEACCES); + NIXIO_WSA_CONSTANT(WSAEINTR); + NIXIO_WSA_CONSTANT(WSAEINVAL); + NIXIO_WSA_CONSTANT(WSAEBADF); + NIXIO_WSA_CONSTANT(WSAEFAULT); + NIXIO_WSA_CONSTANT(WSAEMFILE); + NIXIO_WSA_CONSTANT(WSAENAMETOOLONG); + NIXIO_WSA_CONSTANT(WSAELOOP); + NIXIO_WSA_CONSTANT(WSAEAFNOSUPPORT); + NIXIO_WSA_CONSTANT(WSAENOBUFS); + NIXIO_WSA_CONSTANT(WSAEPROTONOSUPPORT); + NIXIO_WSA_CONSTANT(WSAENOPROTOOPT); + NIXIO_WSA_CONSTANT(WSAEADDRINUSE); + NIXIO_WSA_CONSTANT(WSAENETDOWN); + NIXIO_WSA_CONSTANT(WSAENETUNREACH); + NIXIO_WSA_CONSTANT(WSAECONNABORTED); + NIXIO_WSA_CONSTANT(WSAECONNRESET); + + lua_setfield(L, -2, "const_sock"); +} + +const char* nixio__mgw_inet_ntop +(int af, const void *src, char *dst, socklen_t size) { + struct sockaddr_storage saddr; + memset(&saddr, 0, sizeof(saddr)); + + DWORD hostlen = size, sl; + if (af == AF_INET) { + struct sockaddr_in *saddr4 = (struct sockaddr_in *)&saddr; + memcpy(&saddr4->sin_addr, src, sizeof(saddr4->sin_addr)); + saddr4->sin_family = AF_INET; + saddr4->sin_port = 0; + sl = sizeof(struct sockaddr_in); + } else if (af == AF_INET6) { + struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)&saddr; + memcpy(&saddr6->sin6_addr, src, sizeof(saddr6->sin6_addr)); + saddr6->sin6_family = AF_INET6; + saddr6->sin6_port = 0; + sl = sizeof(struct sockaddr_in6); + } else { + return NULL; + } + if (WSAAddressToString((struct sockaddr*)&saddr, sl, NULL, dst, &hostlen)) { + return NULL; + } + return dst; +} + +int nixio__mgw_inet_pton (int af, const char *src, void *dst) { + struct sockaddr_storage sa; + int sl = sizeof(sa); + + if (!WSAStringToAddress((char*)src, af, NULL, (struct sockaddr*)&sa, &sl)) { + if (af == AF_INET) { + struct in_addr ina = ((struct sockaddr_in *)&sa)->sin_addr; + memcpy(dst, &ina, sizeof(ina)); + return 1; + } else if (af == AF_INET6) { + struct in_addr6 ina6 = ((struct sockaddr_in6 *)&sa)->sin6_addr; + memcpy(dst, &ina6, sizeof(ina6)); + return 1; + } else { + WSASetLastError(WSAEAFNOSUPPORT); + return -1; + } + } else { + return -1; + } +} + +int nixio__mgw_nanosleep(const struct timespec *req, struct timespec *rem) { + if (rem) { + rem->tv_sec = 0; + rem->tv_nsec = 0; + } + Sleep(req->tv_sec * 1000 + req->tv_nsec * 1000000); + return 0; +} + +int nixio__mgw_poll(struct pollfd *fds, int nfds, int timeout) { + if (!fds || !nfds) { + Sleep(timeout); + return 0; + } + + struct timeval tv; + int high = 0, rf = 0, wf = 0, ef = 0; + fd_set rfds, wfds, efds; + FD_ZERO(&rfds); + FD_ZERO(&wfds); + FD_ZERO(&efds); + + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + + for (int i = 0; i < nfds; i++) { + if (fds->events & POLLIN) { + FD_SET(fds->fd, &rfds); + rf++; + } + if (fds->events & POLLOUT) { + FD_SET(fds->fd, &wfds); + wf++; + } + if (fds->events & POLLERR) { + FD_SET(fds->fd, &efds); + ef++; + } + if (fds->fd > high) { + high = fds->fd; + } + } + + int stat = select(high + 1, (rf) ? &rfds : NULL, + (wf) ? &wfds : NULL, (ef) ? &efds : NULL, &tv); + if (stat < 1) { + errno = WSAGetLastError(); + return stat; + } + + high = 0; + + for (int i = 0; i < nfds; i++) { + fds->revents = 0; + if ((fds->events & POLLIN) && FD_ISSET(fds->fd, &rfds)) { + fds->revents |= POLLIN; + } + if ((fds->events & POLLOUT) && FD_ISSET(fds->fd, &wfds)) { + fds->revents |= POLLOUT; + } + if ((fds->events & POLLERR) && FD_ISSET(fds->fd, &efds)) { + fds->revents |= POLLERR; + } + if (fds->revents) { + high++; + } + } + + return high; +} + +int nixio__mgw_lockf(int fd, int cmd, off_t len) { + int stat; + if (cmd == F_LOCK) { + do { + stat = _locking(fd, _LK_LOCK, len); + } while (stat == -1 && errno == EDEADLOCK); + } else if (cmd == F_TLOCK) { + stat = _locking(fd, _LK_NBLCK, len); + } else if (cmd == F_ULOCK) { + stat = _locking(fd, _LK_UNLCK, len); + } else { + stat = -1; + errno = EINVAL; + } + return stat; +} + +char* nixio__mgw_realpath(const char *path, char *resolved) { + if (GetFullPathName(path, PATH_MAX, resolved, NULL)) { + return resolved; + } else { + errno = GetLastError(); + return NULL; + } +} + +int nixio__mgw_link(const char *oldpath, const char *newpath) { + if (!CreateHardLink(newpath, oldpath, NULL)) { + errno = GetLastError(); + return -1; + } else { + return 0; + } +} + +int nixio__mgw_utimes(const char *filename, const struct timeval times[2]) { + struct _utimbuf timebuffer; + timebuffer.actime = times[0].tv_sec; + timebuffer.modtime = times[1].tv_sec; + + return _utime(filename, &timebuffer); +} |