Anope IRC Services  Version 2.0
socket.cpp
Go to the documentation of this file.
1  /* POSIX emulation layer for Windows.
2  *
3  * Copyright (C) 2008-2014 Anope Team <team@anope.org>
4  *
5  * Please read COPYING and README for further details.
6  */
7 
8 #define WIN32_NO_OVERRIDE
9 #include "services.h"
10 
11 inline static bool is_socket(int fd)
12 {
13  int optval;
14  socklen_t optlen = sizeof(optval);
15  return getsockopt(fd, SOL_SOCKET, SO_TYPE, reinterpret_cast<char *>(&optval), &optlen) == 0;
16 }
17 
18 int read(int fd, char *buf, size_t count)
19 {
20  if (is_socket(fd))
21  return recv(fd, buf, count, 0);
22  else
23  return _read(fd, buf, count);
24 }
25 
26 int write(int fd, const char *buf, size_t count)
27 {
28  if (is_socket(fd))
29  return send(fd, buf, count, 0);
30  else
31  return _write(fd, buf, count);
32 }
33 
34 int windows_close(int fd)
35 {
36  if (is_socket(fd))
37  return closesocket(fd);
38  else
39  return close(fd);
40 }
41 
42 int windows_accept(int fd, struct sockaddr *addr, int *addrlen)
43 {
44  int i = accept(fd, addr, addrlen);
45  if (i == INVALID_SOCKET)
46  return -1;
47  return i;
48 }
49 
56 int windows_inet_pton(int af, const char *src, void *dst)
57 {
58  int address_length;
59  sockaddr_storage sa;
60  sockaddr_in *sin = reinterpret_cast<sockaddr_in *>(&sa);
61  sockaddr_in6 *sin6 = reinterpret_cast<sockaddr_in6 *>(&sa);
62 
63  switch (af)
64  {
65  case AF_INET:
66  address_length = sizeof(sockaddr_in);
67  break;
68  case AF_INET6:
69  address_length = sizeof(sockaddr_in6);
70  break;
71  default:
72  return -1;
73  }
74 
75  if (!WSAStringToAddress(static_cast<LPSTR>(const_cast<char *>(src)), af, NULL, reinterpret_cast<LPSOCKADDR>(&sa), &address_length))
76  {
77  switch (af)
78  {
79  case AF_INET:
80  memcpy(dst, &sin->sin_addr, sizeof(in_addr));
81  break;
82  case AF_INET6:
83  memcpy(dst, &sin6->sin6_addr, sizeof(in6_addr));
84  break;
85  }
86  return 1;
87  }
88 
89  return 0;
90 }
91 
99 const char *windows_inet_ntop(int af, const void *src, char *dst, size_t size)
100 {
101  int address_length;
102  DWORD string_length = size;
103  sockaddr_storage sa;
104  sockaddr_in *sin = reinterpret_cast<sockaddr_in *>(&sa);
105  sockaddr_in6 *sin6 = reinterpret_cast<sockaddr_in6 *>(&sa);
106 
107  memset(&sa, 0, sizeof(sa));
108 
109  switch (af)
110  {
111  case AF_INET:
112  address_length = sizeof(sockaddr_in);
113  sin->sin_family = af;
114  memcpy(&sin->sin_addr, src, sizeof(in_addr));
115  break;
116  case AF_INET6:
117  address_length = sizeof(sockaddr_in6);
118  sin6->sin6_family = af;
119  memcpy(&sin6->sin6_addr, src, sizeof(in6_addr));
120  break;
121  default:
122  return NULL;
123  }
124 
125  if (!WSAAddressToString(reinterpret_cast<LPSOCKADDR>(&sa), address_length, NULL, dst, &string_length))
126  return dst;
127 
128  return NULL;
129 }
130 
131 int fcntl(int fd, int cmd, int arg)
132 {
133  if (cmd == F_GETFL)
134  {
135  return 0;
136  }
137  else if (cmd == F_SETFL)
138  {
139  if (arg & O_NONBLOCK)
140  {
141  unsigned long opt = 1;
142  return ioctlsocket(fd, FIONBIO, &opt);
143  }
144  else
145  {
146  unsigned long opt = 0;
147  return ioctlsocket(fd, FIONBIO, &opt);
148  }
149  }
150 
151  return -1;
152 }
#define F_GETFL
Definition: socket.h:14
const char * windows_inet_ntop(int af, const void *src, char *dst, size_t size)
Definition: socket.cpp:99
int fcntl(int fd, int cmd, int arg)
Definition: socket.cpp:131
static bool is_socket(int fd)
Definition: socket.cpp:11
int read(int fd, char *buf, size_t count)
Definition: socket.cpp:18
int windows_accept(int fd, struct sockaddr *addr, int *addrlen)
Definition: socket.cpp:42
int write(int fd, const char *buf, size_t count)
Definition: socket.cpp:26
#define F_SETFL
Definition: socket.h:15
int windows_close(int fd)
Definition: socket.cpp:34
#define accept
Definition: socket.h:28
#define O_NONBLOCK
Definition: socket.h:17
int windows_inet_pton(int af, const char *src, void *dst)
Definition: socket.cpp:56