1: /* $Id: receivedata.c,v 1.1.1.2 2013/07/22 00:36:10 misho Exp $ */
2: /* Project : miniupnp
3: * Website : http://miniupnp.free.fr/
4: * Author : Thomas Bernard
5: * Copyright (c) 2011-2012 Thomas Bernard
6: * This software is subject to the conditions detailed in the
7: * LICENCE file provided in this distribution. */
8:
9: #include <stdio.h>
10: #ifdef _WIN32
11: #include <winsock2.h>
12: #include <ws2tcpip.h>
13: #else
14: #include <unistd.h>
15: #if defined(__amigaos__) && !defined(__amigaos4__)
16: #define socklen_t int
17: #else /* #if defined(__amigaos__) && !defined(__amigaos4__) */
18: #include <sys/select.h>
19: #endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */
20: #include <sys/socket.h>
21: #include <netinet/in.h>
22: #if !defined(__amigaos__) && !defined(__amigaos4__)
23: #include <poll.h>
24: #endif
25: #include <errno.h>
26: #define MINIUPNPC_IGNORE_EINTR
27: #endif
28:
29: #ifdef _WIN32
30: #define PRINT_SOCKET_ERROR(x) printf("Socket error: %s, %d\n", x, WSAGetLastError());
31: #else
32: #define PRINT_SOCKET_ERROR(x) perror(x)
33: #endif
34:
35: #include "receivedata.h"
36:
37: int
38: receivedata(int socket,
39: char * data, int length,
40: int timeout, unsigned int * scope_id)
41: {
42: #if MINIUPNPC_GET_SRC_ADDR
43: struct sockaddr_storage src_addr;
44: socklen_t src_addr_len = sizeof(src_addr);
45: #endif
46: int n;
47: #if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__)
48: /* using poll */
49: struct pollfd fds[1]; /* for the poll */
50: #ifdef MINIUPNPC_IGNORE_EINTR
51: do {
52: #endif
53: fds[0].fd = socket;
54: fds[0].events = POLLIN;
55: n = poll(fds, 1, timeout);
56: #ifdef MINIUPNPC_IGNORE_EINTR
57: } while(n < 0 && errno == EINTR);
58: #endif
59: if(n < 0) {
60: PRINT_SOCKET_ERROR("poll");
61: return -1;
62: } else if(n == 0) {
63: /* timeout */
64: return 0;
65: }
66: #else /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */
67: /* using select under _WIN32 and amigaos */
68: fd_set socketSet;
69: TIMEVAL timeval;
70: FD_ZERO(&socketSet);
71: FD_SET(socket, &socketSet);
72: timeval.tv_sec = timeout / 1000;
73: timeval.tv_usec = (timeout % 1000) * 1000;
74: n = select(FD_SETSIZE, &socketSet, NULL, NULL, &timeval);
75: if(n < 0) {
76: PRINT_SOCKET_ERROR("select");
77: return -1;
78: } else if(n == 0) {
79: return 0;
80: }
81: #endif
82: #if MINIUPNPC_GET_SRC_ADDR
83: n = recvfrom(socket, data, length, 0,
84: (struct sockaddr *)&src_addr, &src_addr_len);
85: #else
86: n = recv(socket, data, length, 0);
87: #endif
88: if(n<0) {
89: PRINT_SOCKET_ERROR("recv");
90: }
91: #if MINIUPNPC_GET_SRC_ADDR
92: if (src_addr.ss_family == AF_INET6) {
93: const struct sockaddr_in6 * src_addr6 = (struct sockaddr_in6 *)&src_addr;
94: #ifdef DEBUG
95: printf("scope_id=%u\n", src_addr6->sin6_scope_id);
96: #endif
97: if(scope_id)
98: *scope_id = src_addr6->sin6_scope_id;
99: }
100: #endif
101: return n;
102: }
103:
104:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>