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
26namespace 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