~ubuntu-branches/ubuntu/saucy/emscripten/saucy-proposed

« back to all changes in this revision

Viewing changes to tests/enet/unix.c

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/** 
 
2
 @file  unix.c
 
3
 @brief ENet Unix system specific functions
 
4
*/
 
5
#ifndef WIN32
 
6
 
 
7
#include <sys/types.h>
 
8
#include <sys/socket.h>
 
9
#include <sys/ioctl.h>
 
10
#include <sys/time.h>
 
11
#include <arpa/inet.h>
 
12
#include <netdb.h>
 
13
#include <unistd.h>
 
14
#include <string.h>
 
15
#include <errno.h>
 
16
#include <time.h>
 
17
 
 
18
#define ENET_BUILDING_LIB 1
 
19
#include "enet/enet.h"
 
20
 
 
21
#ifdef HAS_FCNTL
 
22
#include <fcntl.h>
 
23
#endif
 
24
 
 
25
#ifdef __APPLE__
 
26
#undef HAS_POLL
 
27
#endif
 
28
 
 
29
#ifdef HAS_POLL
 
30
#include <sys/poll.h>
 
31
#endif
 
32
 
 
33
#ifndef HAS_SOCKLEN_T
 
34
typedef int socklen_t;
 
35
#endif
 
36
 
 
37
#ifndef MSG_NOSIGNAL
 
38
#define MSG_NOSIGNAL 0
 
39
#endif
 
40
 
 
41
static enet_uint32 timeBase = 0;
 
42
 
 
43
int
 
44
enet_initialize (void)
 
45
{
 
46
    return 0;
 
47
}
 
48
 
 
49
void
 
50
enet_deinitialize (void)
 
51
{
 
52
}
 
53
 
 
54
enet_uint32
 
55
enet_time_get (void)
 
56
{
 
57
    struct timeval timeVal;
 
58
 
 
59
    gettimeofday (& timeVal, NULL);
 
60
 
 
61
    return timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - timeBase;
 
62
}
 
63
 
 
64
void
 
65
enet_time_set (enet_uint32 newTimeBase)
 
66
{
 
67
    struct timeval timeVal;
 
68
 
 
69
    gettimeofday (& timeVal, NULL);
 
70
    
 
71
    timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase;
 
72
}
 
73
 
 
74
int
 
75
enet_address_set_host (ENetAddress * address, const char * name)
 
76
{
 
77
    struct hostent * hostEntry = NULL;
 
78
#ifdef HAS_GETHOSTBYNAME_R
 
79
    struct hostent hostData;
 
80
    char buffer [2048];
 
81
    int errnum;
 
82
 
 
83
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
 
84
    gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
 
85
#else
 
86
    hostEntry = gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & errnum);
 
87
#endif
 
88
#else
 
89
    hostEntry = gethostbyname (name);
 
90
#endif
 
91
 
 
92
    if (hostEntry == NULL ||
 
93
        hostEntry -> h_addrtype != AF_INET)
 
94
    {
 
95
#ifdef HAS_INET_PTON
 
96
        if (! inet_pton (AF_INET, name, & address -> host))
 
97
#else
 
98
        if (! inet_aton (name, (struct in_addr *) & address -> host))
 
99
#endif
 
100
            return -1;
 
101
        return 0;
 
102
    }
 
103
 
 
104
    address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
 
105
 
 
106
    return 0;
 
107
}
 
108
 
 
109
int
 
110
enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
 
111
{
 
112
#ifdef HAS_INET_NTOP
 
113
    if (inet_ntop (AF_INET, & address -> host, name, nameLength) == NULL)
 
114
#else
 
115
    char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
 
116
    if (addr != NULL)
 
117
        strncpy (name, addr, nameLength);
 
118
    else
 
119
#endif
 
120
        return -1;
 
121
    return 0;
 
122
}
 
123
 
 
124
int
 
125
enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
 
126
{
 
127
    struct in_addr in;
 
128
    struct hostent * hostEntry = NULL;
 
129
#ifdef HAS_GETHOSTBYADDR_R
 
130
    struct hostent hostData;
 
131
    char buffer [2048];
 
132
    int errnum;
 
133
 
 
134
    in.s_addr = address -> host;
 
135
 
 
136
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
 
137
    gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
 
138
#else
 
139
    hostEntry = gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & errnum);
 
140
#endif
 
141
#else
 
142
    in.s_addr = address -> host;
 
143
 
 
144
    hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
 
145
#endif
 
146
 
 
147
    if (hostEntry == NULL)
 
148
      return enet_address_get_host_ip (address, name, nameLength);
 
149
 
 
150
    strncpy (name, hostEntry -> h_name, nameLength);
 
151
 
 
152
    return 0;
 
153
}
 
154
 
 
155
int
 
156
enet_socket_bind (ENetSocket socket, const ENetAddress * address)
 
157
{
 
158
    struct sockaddr_in sin;
 
159
 
 
160
    memset (& sin, 0, sizeof (struct sockaddr_in));
 
161
 
 
162
    sin.sin_family = AF_INET;
 
163
 
 
164
    if (address != NULL)
 
165
    {
 
166
       sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
 
167
       sin.sin_addr.s_addr = address -> host;
 
168
    }
 
169
    else
 
170
    {
 
171
       sin.sin_port = 0;
 
172
       sin.sin_addr.s_addr = INADDR_ANY;
 
173
    }
 
174
 
 
175
    return bind (socket,
 
176
                 (struct sockaddr *) & sin,
 
177
                 sizeof (struct sockaddr_in)); 
 
178
}
 
179
 
 
180
int 
 
181
enet_socket_listen (ENetSocket socket, int backlog)
 
182
{
 
183
    return listen (socket, backlog < 0 ? SOMAXCONN : backlog);
 
184
}
 
185
 
 
186
ENetSocket
 
187
enet_socket_create (ENetSocketType type)
 
188
{
 
189
    return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
 
190
}
 
191
 
 
192
int
 
193
enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
 
194
{
 
195
    int result = -1;
 
196
    switch (option)
 
197
    {
 
198
        case ENET_SOCKOPT_NONBLOCK:
 
199
#ifdef HAS_FCNTL
 
200
            result = fcntl (socket, F_SETFL, O_NONBLOCK | fcntl (socket, F_GETFL));
 
201
#else
 
202
            result = ioctl (socket, FIONBIO, & value);
 
203
#endif
 
204
            break;
 
205
 
 
206
        case ENET_SOCKOPT_BROADCAST:
 
207
            result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
 
208
            break;
 
209
 
 
210
        case ENET_SOCKOPT_REUSEADDR:
 
211
            result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
 
212
            break;
 
213
 
 
214
        case ENET_SOCKOPT_RCVBUF:
 
215
            result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int));
 
216
            break;
 
217
 
 
218
        case ENET_SOCKOPT_SNDBUF:
 
219
            result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
 
220
            break;
 
221
 
 
222
        case ENET_SOCKOPT_RCVTIMEO:
 
223
            result = setsockopt (socket, SOL_SOCKET, SO_RCVTIMEO, (char *) & value, sizeof (int));
 
224
            break;
 
225
 
 
226
        case ENET_SOCKOPT_SNDTIMEO:
 
227
            result = setsockopt (socket, SOL_SOCKET, SO_SNDTIMEO, (char *) & value, sizeof (int));
 
228
            break;
 
229
 
 
230
        default:
 
231
            break;
 
232
    }
 
233
    return result == -1 ? -1 : 0;
 
234
}
 
235
 
 
236
int
 
237
enet_socket_connect (ENetSocket socket, const ENetAddress * address)
 
238
{
 
239
    struct sockaddr_in sin;
 
240
 
 
241
    memset (& sin, 0, sizeof (struct sockaddr_in));
 
242
 
 
243
    sin.sin_family = AF_INET;
 
244
    sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
 
245
    sin.sin_addr.s_addr = address -> host;
 
246
 
 
247
    return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
 
248
}
 
249
 
 
250
ENetSocket
 
251
enet_socket_accept (ENetSocket socket, ENetAddress * address)
 
252
{
 
253
    int result;
 
254
    struct sockaddr_in sin;
 
255
    socklen_t sinLength = sizeof (struct sockaddr_in);
 
256
 
 
257
    result = accept (socket, 
 
258
                     address != NULL ? (struct sockaddr *) & sin : NULL, 
 
259
                     address != NULL ? & sinLength : NULL);
 
260
    
 
261
    if (result == -1)
 
262
      return ENET_SOCKET_NULL;
 
263
 
 
264
    if (address != NULL)
 
265
    {
 
266
        address -> host = (enet_uint32) sin.sin_addr.s_addr;
 
267
        address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
 
268
    }
 
269
 
 
270
    return result;
 
271
 
272
    
 
273
void
 
274
enet_socket_destroy (ENetSocket socket)
 
275
{
 
276
    close (socket);
 
277
}
 
278
 
 
279
int
 
280
enet_socket_send (ENetSocket socket,
 
281
                  const ENetAddress * address,
 
282
                  const ENetBuffer * buffers,
 
283
                  size_t bufferCount)
 
284
{
 
285
    struct msghdr msgHdr;
 
286
    struct sockaddr_in sin;
 
287
    int sentLength;
 
288
 
 
289
    memset (& msgHdr, 0, sizeof (struct msghdr));
 
290
 
 
291
    if (address != NULL)
 
292
    {
 
293
        memset (& sin, 0, sizeof (struct sockaddr_in));
 
294
 
 
295
        sin.sin_family = AF_INET;
 
296
        sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
 
297
        sin.sin_addr.s_addr = address -> host;
 
298
 
 
299
        msgHdr.msg_name = & sin;
 
300
        msgHdr.msg_namelen = sizeof (struct sockaddr_in);
 
301
    }
 
302
 
 
303
    msgHdr.msg_iov = (struct iovec *) buffers;
 
304
    msgHdr.msg_iovlen = bufferCount;
 
305
 
 
306
    sentLength = sendmsg (socket, & msgHdr, MSG_NOSIGNAL);
 
307
    
 
308
    if (sentLength == -1)
 
309
    {
 
310
       if (errno == EWOULDBLOCK)
 
311
         return 0;
 
312
 
 
313
       return -1;
 
314
    }
 
315
 
 
316
    return sentLength;
 
317
}
 
318
 
 
319
int
 
320
enet_socket_receive (ENetSocket socket,
 
321
                     ENetAddress * address,
 
322
                     ENetBuffer * buffers,
 
323
                     size_t bufferCount)
 
324
{
 
325
    struct msghdr msgHdr;
 
326
    struct sockaddr_in sin;
 
327
    int recvLength;
 
328
 
 
329
    memset (& msgHdr, 0, sizeof (struct msghdr));
 
330
 
 
331
    if (address != NULL)
 
332
    {
 
333
        msgHdr.msg_name = & sin;
 
334
        msgHdr.msg_namelen = sizeof (struct sockaddr_in);
 
335
    }
 
336
 
 
337
    msgHdr.msg_iov = (struct iovec *) buffers;
 
338
    msgHdr.msg_iovlen = bufferCount;
 
339
 
 
340
    recvLength = recvmsg (socket, & msgHdr, MSG_NOSIGNAL);
 
341
 
 
342
    if (recvLength == -1)
 
343
    {
 
344
       if (errno == EWOULDBLOCK)
 
345
         return 0;
 
346
 
 
347
       return -1;
 
348
    }
 
349
 
 
350
#ifdef HAS_MSGHDR_FLAGS
 
351
    if (msgHdr.msg_flags & MSG_TRUNC)
 
352
      return -1;
 
353
#endif
 
354
 
 
355
    if (address != NULL)
 
356
    {
 
357
        address -> host = (enet_uint32) sin.sin_addr.s_addr;
 
358
        address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
 
359
    }
 
360
 
 
361
    return recvLength;
 
362
}
 
363
 
 
364
int
 
365
enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout)
 
366
{
 
367
    struct timeval timeVal;
 
368
 
 
369
    timeVal.tv_sec = timeout / 1000;
 
370
    timeVal.tv_usec = (timeout % 1000) * 1000;
 
371
 
 
372
    return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal);
 
373
}
 
374
 
 
375
int
 
376
enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
 
377
{
 
378
#ifdef HAS_POLL
 
379
    struct pollfd pollSocket;
 
380
    int pollCount;
 
381
    
 
382
    pollSocket.fd = socket;
 
383
    pollSocket.events = 0;
 
384
 
 
385
    if (* condition & ENET_SOCKET_WAIT_SEND)
 
386
      pollSocket.events |= POLLOUT;
 
387
 
 
388
    if (* condition & ENET_SOCKET_WAIT_RECEIVE)
 
389
      pollSocket.events |= POLLIN;
 
390
 
 
391
    pollCount = poll (& pollSocket, 1, timeout);
 
392
 
 
393
    if (pollCount < 0)
 
394
      return -1;
 
395
 
 
396
    * condition = ENET_SOCKET_WAIT_NONE;
 
397
 
 
398
    if (pollCount == 0)
 
399
      return 0;
 
400
 
 
401
    if (pollSocket.revents & POLLOUT)
 
402
      * condition |= ENET_SOCKET_WAIT_SEND;
 
403
    
 
404
    if (pollSocket.revents & POLLIN)
 
405
      * condition |= ENET_SOCKET_WAIT_RECEIVE;
 
406
 
 
407
    return 0;
 
408
#else
 
409
    fd_set readSet, writeSet;
 
410
    struct timeval timeVal;
 
411
    int selectCount;
 
412
 
 
413
    timeVal.tv_sec = timeout / 1000;
 
414
    timeVal.tv_usec = (timeout % 1000) * 1000;
 
415
 
 
416
    FD_ZERO (& readSet);
 
417
    FD_ZERO (& writeSet);
 
418
 
 
419
    if (* condition & ENET_SOCKET_WAIT_SEND)
 
420
      FD_SET (socket, & writeSet);
 
421
 
 
422
    if (* condition & ENET_SOCKET_WAIT_RECEIVE)
 
423
      FD_SET (socket, & readSet);
 
424
 
 
425
    selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
 
426
 
 
427
    if (selectCount < 0)
 
428
      return -1;
 
429
 
 
430
    * condition = ENET_SOCKET_WAIT_NONE;
 
431
 
 
432
    if (selectCount == 0)
 
433
      return 0;
 
434
 
 
435
    if (FD_ISSET (socket, & writeSet))
 
436
      * condition |= ENET_SOCKET_WAIT_SEND;
 
437
 
 
438
    if (FD_ISSET (socket, & readSet))
 
439
      * condition |= ENET_SOCKET_WAIT_RECEIVE;
 
440
 
 
441
    return 0;
 
442
#endif
 
443
}
 
444
 
 
445
#endif
 
446