• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
u_socket_init()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
u_socket_stop()45  u_socket_stop()
46  {
47  #if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
48     WSACleanup();
49  #endif
50  }
51  
52  void
u_socket_close(int s)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  
u_socket_accept(int s)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
u_socket_send(int s,void * data,size_t size)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
u_socket_peek(int s,void * data,size_t size)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
u_socket_recv(int s,void * data,size_t size)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
u_socket_connect(const char * hostname,uint16_t port)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
u_socket_listen_on_port(uint16_t portnum)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
u_socket_block(int s,boolean block)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