1 | // Copyright 2016 The SwiftShader Authors. All Rights Reserved. |
2 | // |
3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | // you may not use this file except in compliance with the License. |
5 | // You may obtain a copy of the License at |
6 | // |
7 | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | // |
9 | // Unless required by applicable law or agreed to in writing, software |
10 | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | // See the License for the specific language governing permissions and |
13 | // limitations under the License. |
14 | |
15 | #include "Socket.hpp" |
16 | |
17 | #if defined(_WIN32) |
18 | #include <ws2tcpip.h> |
19 | #else |
20 | #include <unistd.h> |
21 | #include <netdb.h> |
22 | #include <netinet/in.h> |
23 | #include <sys/select.h> |
24 | #endif |
25 | |
26 | namespace sw |
27 | { |
28 | Socket::Socket(SOCKET socket) : socket(socket) |
29 | { |
30 | } |
31 | |
32 | Socket::Socket(const char *address, const char *port) |
33 | { |
34 | #if defined(_WIN32) |
35 | socket = INVALID_SOCKET; |
36 | #else |
37 | socket = -1; |
38 | #endif |
39 | |
40 | addrinfo hints = {}; |
41 | hints.ai_family = AF_INET; |
42 | hints.ai_socktype = SOCK_STREAM; |
43 | hints.ai_protocol = IPPROTO_TCP; |
44 | hints.ai_flags = AI_PASSIVE; |
45 | |
46 | addrinfo *info = 0; |
47 | getaddrinfo(address, port, &hints, &info); |
48 | |
49 | if(info) |
50 | { |
51 | socket = ::socket(info->ai_family, info->ai_socktype, info->ai_protocol); |
52 | bind(socket, info->ai_addr, (int)info->ai_addrlen); |
53 | } |
54 | } |
55 | |
56 | Socket::~Socket() |
57 | { |
58 | #if defined(_WIN32) |
59 | closesocket(socket); |
60 | #else |
61 | close(socket); |
62 | #endif |
63 | } |
64 | |
65 | void Socket::listen(int backlog) |
66 | { |
67 | ::listen(socket, backlog); |
68 | } |
69 | |
70 | bool Socket::select(int us) |
71 | { |
72 | fd_set sockets; |
73 | FD_ZERO(&sockets); |
74 | FD_SET(socket, &sockets); |
75 | |
76 | timeval timeout = {us / 1000000, us % 1000000}; |
77 | |
78 | return ::select(FD_SETSIZE, &sockets, 0, 0, &timeout) >= 1; |
79 | } |
80 | |
81 | Socket *Socket::accept() |
82 | { |
83 | return new Socket(::accept(socket, 0, 0)); |
84 | } |
85 | |
86 | int Socket::receive(char *buffer, int length) |
87 | { |
88 | return recv(socket, buffer, length, 0); |
89 | } |
90 | |
91 | void Socket::send(const char *buffer, int length) |
92 | { |
93 | ::send(socket, buffer, length, 0); |
94 | } |
95 | |
96 | void Socket::startup() |
97 | { |
98 | #if defined(_WIN32) |
99 | WSADATA winsockData; |
100 | WSAStartup(MAKEWORD(2, 2), &winsockData); |
101 | #endif |
102 | } |
103 | |
104 | void Socket::cleanup() |
105 | { |
106 | #if defined(_WIN32) |
107 | WSACleanup(); |
108 | #endif |
109 | } |
110 | } |
111 | |