aboutsummaryrefslogtreecommitdiff
path: root/win32/net.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--win32/net.c146
1 files changed, 146 insertions, 0 deletions
diff --git a/win32/net.c b/win32/net.c
new file mode 100644
index 000000000..33dc837fa
--- /dev/null
+++ b/win32/net.c
@@ -0,0 +1,146 @@
1#include "libbb.h"
2
3int inet_aton(const char *cp, struct in_addr *inp)
4{
5 unsigned long val = inet_addr(cp);
6
7 if (val == INADDR_NONE)
8 return 0;
9 inp->S_un.S_addr = val;
10 return 1;
11}
12
13void init_winsock(void)
14{
15 WSADATA wsa;
16 static int initialized = 0;
17
18 if (initialized)
19 return;
20
21 if (WSAStartup(MAKEWORD(2,2), &wsa))
22 bb_error_msg_and_die("WSAStartup failed, error %d", WSAGetLastError());
23
24 atexit((void(*)(void)) WSACleanup);
25 initialized = 1;
26}
27
28#undef gethostname
29int mingw_gethostname(char *name, int namelen)
30{
31 init_winsock();
32 return gethostname(name, namelen);
33}
34
35#undef gethostbyaddr
36struct hostent *mingw_gethostbyaddr(const void *addr, socklen_t len, int type)
37{
38 init_winsock();
39 return gethostbyaddr(addr, len, type);
40}
41
42#undef getaddrinfo
43int mingw_getaddrinfo(const char *node, const char *service,
44 const struct addrinfo *hints, struct addrinfo **res)
45{
46 init_winsock();
47 return getaddrinfo(node, service, hints, res);
48}
49
50int mingw_socket(int domain, int type, int protocol)
51{
52 int sockfd;
53 SOCKET s;
54
55 init_winsock();
56 s = WSASocket(domain, type, protocol, NULL, 0, 0);
57 if (s == INVALID_SOCKET) {
58 /*
59 * WSAGetLastError() values are regular BSD error codes
60 * biased by WSABASEERR.
61 * However, strerror() does not know about networking
62 * specific errors, which are values beginning at 38 or so.
63 * Therefore, we choose to leave the biased error code
64 * in errno so that _if_ someone looks up the code somewhere,
65 * then it is at least the number that are usually listed.
66 */
67 errno = WSAGetLastError();
68 return -1;
69 }
70 /* convert into a file descriptor */
71 if ((sockfd = _open_osfhandle((intptr_t)s, O_RDWR|O_BINARY)) < 0) {
72 closesocket(s);
73 bb_error_msg("unable to make a socket file descriptor: %s",
74 strerror(errno));
75 return -1;
76 }
77 return sockfd;
78}
79
80#undef connect
81int mingw_connect(int sockfd, const struct sockaddr *sa, size_t sz)
82{
83 SOCKET s = (SOCKET)_get_osfhandle(sockfd);
84 return connect(s, sa, sz);
85}
86
87#undef bind
88int mingw_bind(int sockfd, struct sockaddr *sa, size_t sz)
89{
90 SOCKET s = (SOCKET)_get_osfhandle(sockfd);
91 return bind(s, sa, sz);
92}
93
94#undef setsockopt
95int mingw_setsockopt(int sockfd, int lvl, int optname, void *optval, int optlen)
96{
97 SOCKET s = (SOCKET)_get_osfhandle(sockfd);
98 return setsockopt(s, lvl, optname, (const char*)optval, optlen);
99}
100
101#undef shutdown
102int mingw_shutdown(int sockfd, int how)
103{
104 SOCKET s = (SOCKET)_get_osfhandle(sockfd);
105 return shutdown(s, how);
106}
107
108#undef listen
109int mingw_listen(int sockfd, int backlog)
110{
111 SOCKET s = (SOCKET)_get_osfhandle(sockfd);
112 return listen(s, backlog);
113}
114
115#undef accept
116int mingw_accept(int sockfd1, struct sockaddr *sa, socklen_t *sz)
117{
118 int sockfd2;
119
120 SOCKET s1 = (SOCKET)_get_osfhandle(sockfd1);
121 SOCKET s2 = accept(s1, sa, sz);
122
123 /* convert into a file descriptor */
124 if ((sockfd2 = _open_osfhandle((intptr_t)s2, O_RDWR|O_BINARY)) < 0) {
125 int err = errno;
126 closesocket(s2);
127 bb_error_msg("unable to make a socket file descriptor: %s",
128 strerror(err));
129 return -1;
130 }
131 return sockfd2;
132}
133
134#undef getpeername
135int mingw_getpeername(int fd, struct sockaddr *sa, socklen_t *sz)
136{
137 SOCKET sock;
138
139 init_winsock();
140 sock = (SOCKET)_get_osfhandle(fd);
141 if (sock == INVALID_SOCKET) {
142 errno = EBADF;
143 return -1;
144 }
145 return getpeername(sock, sa, sz);
146}