1 2 #include "pipe/p_compiler.h" 3 #include "util/u_network.h" 4 #include "util/u_debug.h" 5 6 #if defined(PIPE_SUBSYSTEM_WINDOWS_USER) 7 # include <winsock2.h> 8 # include <windows.h> 9 #elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) || \ 10 defined(PIPE_OS_APPLE) || defined(PIPE_OS_CYGWIN) || defined(PIPE_OS_SOLARIS) 11 # include <sys/socket.h> 12 # include <netinet/in.h> 13 # include <unistd.h> 14 # include <fcntl.h> 15 # include <netdb.h> 16 #else 17 # warning "No socket implementation" 18 #endif 19 20 boolean 21 u_socket_init() 22 { 23 #if defined(PIPE_SUBSYSTEM_WINDOWS_USER) 24 WORD wVersionRequested; 25 WSADATA wsaData; 26 int err; 27 28 /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */ 29 wVersionRequested = MAKEWORD(1, 1); 30 31 err = WSAStartup(wVersionRequested, &wsaData); 32 if (err != 0) { 33 debug_printf("WSAStartup failed with error: %d\n", err); 34 return FALSE; 35 } 36 return TRUE; 37 #elif defined(PIPE_HAVE_SOCKETS) 38 return TRUE; 39 #else 40 return FALSE; 41 #endif 42 } 43 44 void 45 u_socket_stop() 46 { 47 #if defined(PIPE_SUBSYSTEM_WINDOWS_USER) 48 WSACleanup(); 49 #endif 50 } 51 52 void 53 u_socket_close(int s) 54 { 55 if (s < 0) 56 return; 57 58 #if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) \ 59 || defined(PIPE_OS_APPLE) || defined(PIPE_OS_SOLARIS) 60 shutdown(s, SHUT_RDWR); 61 close(s); 62 #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) 63 shutdown(s, SD_BOTH); 64 closesocket(s); 65 #else 66 assert(0); 67 #endif 68 } 69 70 int u_socket_accept(int s) 71 { 72 #if defined(PIPE_HAVE_SOCKETS) 73 return accept(s, NULL, NULL); 74 #else 75 return -1; 76 #endif 77 } 78 79 int 80 u_socket_send(int s, void *data, size_t size) 81 { 82 #if defined(PIPE_HAVE_SOCKETS) 83 return send(s, data, size, 0); 84 #else 85 return -1; 86 #endif 87 } 88 89 int 90 u_socket_peek(int s, void *data, size_t size) 91 { 92 #if defined(PIPE_HAVE_SOCKETS) 93 return recv(s, data, size, MSG_PEEK); 94 #else 95 return -1; 96 #endif 97 } 98 99 int 100 u_socket_recv(int s, void *data, size_t size) 101 { 102 #if defined(PIPE_HAVE_SOCKETS) 103 return recv(s, data, size, 0); 104 #else 105 return -1; 106 #endif 107 } 108 109 int 110 u_socket_connect(const char *hostname, uint16_t port) 111 { 112 #if defined(PIPE_HAVE_SOCKETS) 113 int s; 114 struct sockaddr_in sa; 115 struct hostent *host = NULL; 116 117 memset(&sa, 0, sizeof(struct sockaddr_in)); 118 host = gethostbyname(hostname); 119 if (!host) 120 return -1; 121 122 memcpy((char *)&sa.sin_addr,host->h_addr_list[0],host->h_length); 123 sa.sin_family= host->h_addrtype; 124 sa.sin_port = htons(port); 125 126 s = socket(host->h_addrtype, SOCK_STREAM, IPPROTO_TCP); 127 if (s < 0) 128 return -1; 129 130 if (connect(s, (struct sockaddr *)&sa, sizeof(sa))) { 131 u_socket_close(s); 132 return -1; 133 } 134 135 return s; 136 #else 137 assert(0); 138 return -1; 139 #endif 140 } 141 142 int 143 u_socket_listen_on_port(uint16_t portnum) 144 { 145 #if defined(PIPE_HAVE_SOCKETS) 146 int s; 147 struct sockaddr_in sa; 148 memset(&sa, 0, sizeof(struct sockaddr_in)); 149 150 sa.sin_family = AF_INET; 151 sa.sin_port = htons(portnum); 152 153 s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 154 if (s < 0) 155 return -1; 156 157 if (bind(s, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) == -1) { 158 u_socket_close(s); 159 return -1; 160 } 161 162 listen(s, 0); 163 164 return s; 165 #else 166 assert(0); 167 return -1; 168 #endif 169 } 170 171 void 172 u_socket_block(int s, boolean block) 173 { 174 #if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU) \ 175 || defined(PIPE_OS_APPLE) || defined(PIPE_OS_SOLARIS) 176 int old = fcntl(s, F_GETFL, 0); 177 if (old == -1) 178 return; 179 180 /* TODO obey block */ 181 if (block) 182 fcntl(s, F_SETFL, old & ~O_NONBLOCK); 183 else 184 fcntl(s, F_SETFL, old | O_NONBLOCK); 185 #elif defined(PIPE_SUBSYSTEM_WINDOWS_USER) 186 u_long iMode = block ? 0 : 1; 187 ioctlsocket(s, FIONBIO, &iMode); 188 #else 189 assert(0); 190 #endif 191 } 192