mingw-compat.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  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. #include "nixio.h"
  19. #include <string.h>
  20. #include <fcntl.h>
  21. #include <errno.h>
  22. #include <sys/locking.h>
  23. #include <sys/time.h>
  24. #include <sys/utime.h>
  25. void nixio_open__mingw(lua_State *L) {
  26. _fmode = _O_BINARY;
  27. WSADATA wsa;
  28. if (WSAStartup(MAKEWORD(2, 2), &wsa)) {
  29. luaL_error(L, "Unable to initialize Winsock");
  30. }
  31. lua_newtable(L);
  32. NIXIO_WSA_CONSTANT(WSAEACCES);
  33. NIXIO_WSA_CONSTANT(WSAEINTR);
  34. NIXIO_WSA_CONSTANT(WSAEINVAL);
  35. NIXIO_WSA_CONSTANT(WSAEBADF);
  36. NIXIO_WSA_CONSTANT(WSAEFAULT);
  37. NIXIO_WSA_CONSTANT(WSAEMFILE);
  38. NIXIO_WSA_CONSTANT(WSAENAMETOOLONG);
  39. NIXIO_WSA_CONSTANT(WSAELOOP);
  40. NIXIO_WSA_CONSTANT(WSAEAFNOSUPPORT);
  41. NIXIO_WSA_CONSTANT(WSAENOBUFS);
  42. NIXIO_WSA_CONSTANT(WSAEPROTONOSUPPORT);
  43. NIXIO_WSA_CONSTANT(WSAENOPROTOOPT);
  44. NIXIO_WSA_CONSTANT(WSAEADDRINUSE);
  45. NIXIO_WSA_CONSTANT(WSAENETDOWN);
  46. NIXIO_WSA_CONSTANT(WSAENETUNREACH);
  47. NIXIO_WSA_CONSTANT(WSAECONNABORTED);
  48. NIXIO_WSA_CONSTANT(WSAECONNRESET);
  49. lua_setfield(L, -2, "const_sock");
  50. }
  51. const char* nixio__mgw_inet_ntop
  52. (int af, const void *src, char *dst, socklen_t size) {
  53. struct sockaddr_storage saddr;
  54. memset(&saddr, 0, sizeof(saddr));
  55. DWORD hostlen = size, sl;
  56. if (af == AF_INET) {
  57. struct sockaddr_in *saddr4 = (struct sockaddr_in *)&saddr;
  58. memcpy(&saddr4->sin_addr, src, sizeof(saddr4->sin_addr));
  59. saddr4->sin_family = AF_INET;
  60. saddr4->sin_port = 0;
  61. sl = sizeof(struct sockaddr_in);
  62. } else if (af == AF_INET6) {
  63. struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)&saddr;
  64. memcpy(&saddr6->sin6_addr, src, sizeof(saddr6->sin6_addr));
  65. saddr6->sin6_family = AF_INET6;
  66. saddr6->sin6_port = 0;
  67. sl = sizeof(struct sockaddr_in6);
  68. } else {
  69. return NULL;
  70. }
  71. if (WSAAddressToString((struct sockaddr*)&saddr, sl, NULL, dst, &hostlen)) {
  72. return NULL;
  73. }
  74. return dst;
  75. }
  76. int nixio__mgw_inet_pton (int af, const char *src, void *dst) {
  77. struct sockaddr_storage sa;
  78. int sl = sizeof(sa);
  79. if (!WSAStringToAddress((char*)src, af, NULL, (struct sockaddr*)&sa, &sl)) {
  80. if (af == AF_INET) {
  81. struct in_addr ina = ((struct sockaddr_in *)&sa)->sin_addr;
  82. memcpy(dst, &ina, sizeof(ina));
  83. return 1;
  84. } else if (af == AF_INET6) {
  85. struct in_addr6 ina6 = ((struct sockaddr_in6 *)&sa)->sin6_addr;
  86. memcpy(dst, &ina6, sizeof(ina6));
  87. return 1;
  88. } else {
  89. WSASetLastError(WSAEAFNOSUPPORT);
  90. return -1;
  91. }
  92. } else {
  93. return -1;
  94. }
  95. }
  96. int nixio__mgw_nanosleep(const struct timespec *req, struct timespec *rem) {
  97. if (rem) {
  98. rem->tv_sec = 0;
  99. rem->tv_nsec = 0;
  100. }
  101. Sleep(req->tv_sec * 1000 + req->tv_nsec * 1000000);
  102. return 0;
  103. }
  104. int nixio__mgw_poll(struct pollfd *fds, int nfds, int timeout) {
  105. if (!fds || !nfds) {
  106. Sleep(timeout);
  107. return 0;
  108. }
  109. struct timeval tv;
  110. int high = 0, rf = 0, wf = 0, ef = 0;
  111. fd_set rfds, wfds, efds;
  112. FD_ZERO(&rfds);
  113. FD_ZERO(&wfds);
  114. FD_ZERO(&efds);
  115. tv.tv_sec = timeout / 1000;
  116. tv.tv_usec = (timeout % 1000) * 1000;
  117. for (int i = 0; i < nfds; i++) {
  118. if (fds->events & POLLIN) {
  119. FD_SET(fds->fd, &rfds);
  120. rf++;
  121. }
  122. if (fds->events & POLLOUT) {
  123. FD_SET(fds->fd, &wfds);
  124. wf++;
  125. }
  126. if (fds->events & POLLERR) {
  127. FD_SET(fds->fd, &efds);
  128. ef++;
  129. }
  130. if (fds->fd > high) {
  131. high = fds->fd;
  132. }
  133. }
  134. int stat = select(high + 1, (rf) ? &rfds : NULL,
  135. (wf) ? &wfds : NULL, (ef) ? &efds : NULL, &tv);
  136. if (stat < 1) {
  137. errno = WSAGetLastError();
  138. return stat;
  139. }
  140. high = 0;
  141. for (int i = 0; i < nfds; i++) {
  142. fds->revents = 0;
  143. if ((fds->events & POLLIN) && FD_ISSET(fds->fd, &rfds)) {
  144. fds->revents |= POLLIN;
  145. }
  146. if ((fds->events & POLLOUT) && FD_ISSET(fds->fd, &wfds)) {
  147. fds->revents |= POLLOUT;
  148. }
  149. if ((fds->events & POLLERR) && FD_ISSET(fds->fd, &efds)) {
  150. fds->revents |= POLLERR;
  151. }
  152. if (fds->revents) {
  153. high++;
  154. }
  155. }
  156. return high;
  157. }
  158. int nixio__mgw_lockf(int fd, int cmd, off_t len) {
  159. int stat;
  160. if (cmd == F_LOCK) {
  161. do {
  162. stat = _locking(fd, _LK_LOCK, len);
  163. } while (stat == -1 && errno == EDEADLOCK);
  164. } else if (cmd == F_TLOCK) {
  165. stat = _locking(fd, _LK_NBLCK, len);
  166. } else if (cmd == F_ULOCK) {
  167. stat = _locking(fd, _LK_UNLCK, len);
  168. } else {
  169. stat = -1;
  170. errno = EINVAL;
  171. }
  172. return stat;
  173. }
  174. char* nixio__mgw_realpath(const char *path, char *resolved) {
  175. if (GetFullPathName(path, PATH_MAX, resolved, NULL)) {
  176. return resolved;
  177. } else {
  178. errno = GetLastError();
  179. return NULL;
  180. }
  181. }
  182. int nixio__mgw_link(const char *oldpath, const char *newpath) {
  183. if (!CreateHardLink(newpath, oldpath, NULL)) {
  184. errno = GetLastError();
  185. return -1;
  186. } else {
  187. return 0;
  188. }
  189. }
  190. int nixio__mgw_utimes(const char *filename, const struct timeval times[2]) {
  191. struct _utimbuf timebuffer;
  192. timebuffer.actime = times[0].tv_sec;
  193. timebuffer.modtime = times[1].tv_sec;
  194. return _utime(filename, &timebuffer);
  195. }