socket.cpp

Go to the documentation of this file.
00001  /* POSIX emulation layer for Windows.
00002  *
00003  * Copyright (C) 2008-2013 Anope Team <team@anope.org>
00004  *
00005  * Please read COPYING and README for further details.
00006  */
00007 
00008 #define WIN32_NO_OVERRIDE
00009 #include "services.h"
00010 
00011 inline static bool is_socket(int fd)
00012 {
00013         int optval;
00014         socklen_t optlen = sizeof(optval);
00015         return getsockopt(fd, SOL_SOCKET, SO_TYPE, reinterpret_cast<char *>(&optval), &optlen) == 0;
00016 }
00017 
00018 int read(int fd, char *buf, size_t count)
00019 {
00020         if (is_socket(fd))
00021                 return recv(fd, buf, count, 0);
00022         else
00023                 return _read(fd, buf, count);
00024 }
00025 
00026 int write(int fd, const char *buf, size_t count)
00027 {
00028         if (is_socket(fd))
00029                 return send(fd, buf, count, 0);
00030         else
00031                 return _write(fd, buf, count);
00032 }
00033 
00034 int windows_close(int fd)
00035 {
00036         if (is_socket(fd))
00037                 return closesocket(fd);
00038         else
00039                 return close(fd);
00040 }
00041 
00042 int windows_accept(int fd, struct sockaddr *addr, int *addrlen)
00043 {
00044         int i = accept(fd, addr, addrlen);
00045         if (i == INVALID_SOCKET)
00046                 return -1;
00047         return i;
00048 }
00049 
00056 int windows_inet_pton(int af, const char *src, void *dst)
00057 {
00058         int address_length;
00059         sockaddr_storage sa;
00060         sockaddr_in *sin = reinterpret_cast<sockaddr_in *>(&sa);
00061         sockaddr_in6 *sin6 = reinterpret_cast<sockaddr_in6 *>(&sa);
00062 
00063         switch (af)
00064         {
00065                 case AF_INET:
00066                         address_length = sizeof(sockaddr_in);
00067                         break;
00068                 case AF_INET6:
00069                         address_length = sizeof(sockaddr_in6);
00070                         break;
00071                 default:
00072                         return -1;
00073         }
00074 
00075         if (!WSAStringToAddress(static_cast<LPSTR>(const_cast<char *>(src)), af, NULL, reinterpret_cast<LPSOCKADDR>(&sa), &address_length))
00076         {
00077                 switch (af)
00078                 {
00079                         case AF_INET:
00080                                 memcpy(dst, &sin->sin_addr, sizeof(in_addr));
00081                                 break;
00082                         case AF_INET6:
00083                                 memcpy(dst, &sin6->sin6_addr, sizeof(in6_addr));
00084                                 break;
00085                 }
00086                 return 1;
00087         }
00088         
00089         return 0;
00090 }
00091 
00099 const char *windows_inet_ntop(int af, const void *src, char *dst, size_t size)
00100 {
00101         int address_length;
00102         DWORD string_length = size;
00103         sockaddr_storage sa;
00104         sockaddr_in *sin = reinterpret_cast<sockaddr_in *>(&sa);
00105         sockaddr_in6 *sin6 = reinterpret_cast<sockaddr_in6 *>(&sa);
00106 
00107         memset(&sa, 0, sizeof(sa));
00108 
00109         switch (af)
00110         {
00111                 case AF_INET:
00112                         address_length = sizeof(sockaddr_in);
00113                         sin->sin_family = af;
00114                         memcpy(&sin->sin_addr, src, sizeof(in_addr));
00115                         break;
00116                 case AF_INET6:
00117                         address_length = sizeof(sockaddr_in6);
00118                         sin6->sin6_family = af;
00119                         memcpy(&sin6->sin6_addr, src, sizeof(in6_addr));
00120                         break;
00121                 default:
00122                         return NULL;
00123         }
00124 
00125         if (!WSAAddressToString(reinterpret_cast<LPSOCKADDR>(&sa), address_length, NULL, dst, &string_length))
00126                 return dst;
00127 
00128         return NULL;
00129 }
00130 
00131 int fcntl(int fd, int cmd, int arg)
00132 {
00133         if (cmd == F_GETFL)
00134         {
00135                 return 0;
00136         }
00137         else if (cmd == F_SETFL)
00138         {
00139                 if (arg & O_NONBLOCK)
00140                 {
00141                         unsigned long opt = 1;
00142                         return ioctlsocket(fd, FIONBIO, &opt);
00143                 }
00144                 else
00145                 {
00146                         unsigned long opt = 0;
00147                         return ioctlsocket(fd, FIONBIO, &opt);
00148                 }
00149         }
00150 
00151         return -1;
00152 }