ffmpeg / libavformat / os_support.c @ 9ac2085d
History | View | Annotate | Download (8.5 KB)
1 | f71869a4 | Fabrice Bellard | /*
|
---|---|---|---|
2 | * Various utilities for ffmpeg system
|
||
3 | * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
|
||
4 | 54eb77c0 | Diego Biurrun | * copyright (c) 2002 Francois Revol
|
5 | f71869a4 | Fabrice Bellard | *
|
6 | b78e7197 | Diego Biurrun | * This file is part of FFmpeg.
|
7 | *
|
||
8 | * FFmpeg is free software; you can redistribute it and/or
|
||
9 | f71869a4 | Fabrice Bellard | * modify it under the terms of the GNU Lesser General Public
|
10 | * License as published by the Free Software Foundation; either
|
||
11 | b78e7197 | Diego Biurrun | * version 2.1 of the License, or (at your option) any later version.
|
12 | f71869a4 | Fabrice Bellard | *
|
13 | b78e7197 | Diego Biurrun | * FFmpeg is distributed in the hope that it will be useful,
|
14 | f71869a4 | Fabrice Bellard | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
16 | * Lesser General Public License for more details.
|
||
17 | *
|
||
18 | * You should have received a copy of the GNU Lesser General Public
|
||
19 | b78e7197 | Diego Biurrun | * License along with FFmpeg; if not, write to the Free Software
|
20 | 5509bffa | Diego Biurrun | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
21 | f71869a4 | Fabrice Bellard | */
|
22 | 7246177d | Aurelien Jacobs | |
23 | /* needed by inet_aton() */
|
||
24 | #define _SVID_SOURCE
|
||
25 | 38c3b6e7 | David Conrad | #define _DARWIN_C_SOURCE
|
26 | 7246177d | Aurelien Jacobs | |
27 | 17c22f57 | Steven M. Schultz | #include "config.h" |
28 | f71869a4 | Fabrice Bellard | #include "avformat.h" |
29 | 087b3272 | Luca Abeni | #include "os_support.h" |
30 | 36c07acd | François Revol | |
31 | b250f9c6 | Aurelien Jacobs | #if CONFIG_NETWORK
|
32 | 7fddac93 | Måns Rullgård | #include <fcntl.h> |
33 | #include <unistd.h> |
||
34 | b250f9c6 | Aurelien Jacobs | #if !HAVE_POLL_H
|
35 | 7fddac93 | Måns Rullgård | #include <sys/time.h> |
36 | b250f9c6 | Aurelien Jacobs | #if HAVE_WINSOCK2_H
|
37 | 36c07acd | François Revol | #include <winsock2.h> |
38 | b250f9c6 | Aurelien Jacobs | #elif HAVE_SYS_SELECT_H
|
39 | b0c858d8 | François Revol | #include <sys/select.h> |
40 | #endif
|
||
41 | 36c07acd | François Revol | #endif
|
42 | f71869a4 | Fabrice Bellard | |
43 | 383eda23 | Alex Beregszaszi | #include "network.h" |
44 | |||
45 | b250f9c6 | Aurelien Jacobs | #if !HAVE_INET_ATON
|
46 | eaa53b95 | Diego Biurrun | #include <stdlib.h> |
47 | #include <strings.h> |
||
48 | |||
49 | ac11d562 | David Conrad | int ff_inet_aton (const char * str, struct in_addr * add) |
50 | 54eb77c0 | Diego Biurrun | { |
51 | unsigned int add1 = 0, add2 = 0, add3 = 0, add4 = 0; |
||
52 | |||
53 | d72e7d0f | Benoit Fouet | if (sscanf(str, "%d.%d.%d.%d", &add1, &add2, &add3, &add4) != 4) |
54 | return 0; |
||
55 | 54eb77c0 | Diego Biurrun | |
56 | 104d0418 | Joakim Plate | if (!add1 || (add1|add2|add3|add4) > 255) return 0; |
57 | |||
58 | b827f4eb | Martin Storsjö | add->s_addr = htonl((add1 << 24) + (add2 << 16) + (add3 << 8) + add4); |
59 | 54eb77c0 | Diego Biurrun | |
60 | return 1; |
||
61 | } |
||
62 | ac11d562 | David Conrad | #else
|
63 | int ff_inet_aton (const char * str, struct in_addr * add) |
||
64 | { |
||
65 | return inet_aton(str, add);
|
||
66 | } |
||
67 | b250f9c6 | Aurelien Jacobs | #endif /* !HAVE_INET_ATON */ |
68 | 383eda23 | Alex Beregszaszi | |
69 | fa053ca7 | Martin Storsjö | #if !HAVE_GETADDRINFO
|
70 | int ff_getaddrinfo(const char *node, const char *service, |
||
71 | const struct addrinfo *hints, struct addrinfo **res) |
||
72 | { |
||
73 | struct hostent *h = NULL; |
||
74 | struct addrinfo *ai;
|
||
75 | struct sockaddr_in *sin;
|
||
76 | |||
77 | 6023d84a | Martin Storsjö | #if HAVE_WINSOCK2_H
|
78 | int (WSAAPI *win_getaddrinfo)(const char *node, const char *service, |
||
79 | const struct addrinfo *hints, |
||
80 | struct addrinfo **res);
|
||
81 | HMODULE ws2mod = GetModuleHandle("ws2_32.dll");
|
||
82 | win_getaddrinfo = GetProcAddress(ws2mod, "getaddrinfo");
|
||
83 | if (win_getaddrinfo)
|
||
84 | return win_getaddrinfo(node, service, hints, res);
|
||
85 | #endif
|
||
86 | |||
87 | a34fc5e2 | Reimar Döffinger | *res = NULL;
|
88 | fa053ca7 | Martin Storsjö | sin = av_mallocz(sizeof(struct sockaddr_in)); |
89 | if (!sin)
|
||
90 | return EAI_FAIL;
|
||
91 | sin->sin_family = AF_INET; |
||
92 | |||
93 | if (node) {
|
||
94 | ac11d562 | David Conrad | if (!ff_inet_aton(node, &sin->sin_addr)) {
|
95 | fa053ca7 | Martin Storsjö | if (hints && (hints->ai_flags & AI_NUMERICHOST)) {
|
96 | av_free(sin); |
||
97 | return EAI_FAIL;
|
||
98 | } |
||
99 | h = gethostbyname(node); |
||
100 | if (!h) {
|
||
101 | av_free(sin); |
||
102 | return EAI_FAIL;
|
||
103 | } |
||
104 | memcpy(&sin->sin_addr, h->h_addr_list[0], sizeof(struct in_addr)); |
||
105 | } |
||
106 | } else {
|
||
107 | if (hints && (hints->ai_flags & AI_PASSIVE)) {
|
||
108 | sin->sin_addr.s_addr = INADDR_ANY; |
||
109 | } else
|
||
110 | sin->sin_addr.s_addr = INADDR_LOOPBACK; |
||
111 | } |
||
112 | |||
113 | /* Note: getaddrinfo allows service to be a string, which
|
||
114 | * should be looked up using getservbyname. */
|
||
115 | if (service)
|
||
116 | sin->sin_port = htons(atoi(service)); |
||
117 | |||
118 | ai = av_mallocz(sizeof(struct addrinfo)); |
||
119 | if (!ai) {
|
||
120 | av_free(sin); |
||
121 | return EAI_FAIL;
|
||
122 | } |
||
123 | |||
124 | *res = ai; |
||
125 | ai->ai_family = AF_INET; |
||
126 | ai->ai_socktype = hints ? hints->ai_socktype : 0;
|
||
127 | switch (ai->ai_socktype) {
|
||
128 | case SOCK_STREAM: ai->ai_protocol = IPPROTO_TCP; break; |
||
129 | case SOCK_DGRAM: ai->ai_protocol = IPPROTO_UDP; break; |
||
130 | default: ai->ai_protocol = 0; break; |
||
131 | } |
||
132 | |||
133 | ai->ai_addr = (struct sockaddr *)sin;
|
||
134 | ai->ai_addrlen = sizeof(struct sockaddr_in); |
||
135 | if (hints && (hints->ai_flags & AI_CANONNAME))
|
||
136 | ai->ai_canonname = h ? av_strdup(h->h_name) : NULL;
|
||
137 | |||
138 | ai->ai_next = NULL;
|
||
139 | return 0; |
||
140 | } |
||
141 | |||
142 | void ff_freeaddrinfo(struct addrinfo *res) |
||
143 | { |
||
144 | 6023d84a | Martin Storsjö | #if HAVE_WINSOCK2_H
|
145 | void (WSAAPI *win_freeaddrinfo)(struct addrinfo *res); |
||
146 | HMODULE ws2mod = GetModuleHandle("ws2_32.dll");
|
||
147 | win_freeaddrinfo = (void (WSAAPI *)(struct addrinfo *res)) |
||
148 | GetProcAddress(ws2mod, "freeaddrinfo");
|
||
149 | if (win_freeaddrinfo) {
|
||
150 | win_freeaddrinfo(res); |
||
151 | return;
|
||
152 | } |
||
153 | #endif
|
||
154 | |||
155 | fa053ca7 | Martin Storsjö | av_free(res->ai_canonname); |
156 | av_free(res->ai_addr); |
||
157 | av_free(res); |
||
158 | } |
||
159 | 5d629b72 | Martin Storsjö | |
160 | int ff_getnameinfo(const struct sockaddr *sa, int salen, |
||
161 | char *host, int hostlen, |
||
162 | char *serv, int servlen, int flags) |
||
163 | { |
||
164 | const struct sockaddr_in *sin = (const struct sockaddr_in *)sa; |
||
165 | |||
166 | 6023d84a | Martin Storsjö | #if HAVE_WINSOCK2_H
|
167 | int (WSAAPI *win_getnameinfo)(const struct sockaddr *sa, socklen_t salen, |
||
168 | char *host, DWORD hostlen,
|
||
169 | char *serv, DWORD servlen, int flags); |
||
170 | HMODULE ws2mod = GetModuleHandle("ws2_32.dll");
|
||
171 | win_getnameinfo = GetProcAddress(ws2mod, "getnameinfo");
|
||
172 | if (win_getnameinfo)
|
||
173 | return win_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
|
||
174 | #endif
|
||
175 | |||
176 | 5d629b72 | Martin Storsjö | if (sa->sa_family != AF_INET)
|
177 | return EAI_FAMILY;
|
||
178 | if (!host && !serv)
|
||
179 | return EAI_NONAME;
|
||
180 | |||
181 | if (host && hostlen > 0) { |
||
182 | struct hostent *ent = NULL; |
||
183 | uint32_t a; |
||
184 | if (!(flags & NI_NUMERICHOST))
|
||
185 | ent = gethostbyaddr((const char *)&sin->sin_addr, |
||
186 | sizeof(sin->sin_addr), AF_INET);
|
||
187 | |||
188 | if (ent) {
|
||
189 | snprintf(host, hostlen, "%s", ent->h_name);
|
||
190 | } else if (flags & NI_NAMERQD) { |
||
191 | return EAI_NONAME;
|
||
192 | } else {
|
||
193 | a = ntohl(sin->sin_addr.s_addr); |
||
194 | snprintf(host, hostlen, "%d.%d.%d.%d",
|
||
195 | ((a >> 24) & 0xff), ((a >> 16) & 0xff), |
||
196 | ((a >> 8) & 0xff), ( a & 0xff)); |
||
197 | } |
||
198 | } |
||
199 | |||
200 | if (serv && servlen > 0) { |
||
201 | struct servent *ent = NULL; |
||
202 | if (!(flags & NI_NUMERICSERV))
|
||
203 | ent = getservbyport(sin->sin_port, flags & NI_DGRAM ? "udp" : "tcp"); |
||
204 | |||
205 | if (ent) {
|
||
206 | snprintf(serv, servlen, "%s", ent->s_name);
|
||
207 | } else
|
||
208 | snprintf(serv, servlen, "%d", ntohs(sin->sin_port));
|
||
209 | } |
||
210 | |||
211 | return 0; |
||
212 | } |
||
213 | 04a2b04b | Ronald S. Bultje | |
214 | const char *ff_gai_strerror(int ecode) |
||
215 | { |
||
216 | switch(ecode) {
|
||
217 | case EAI_FAIL : return "A non-recoverable error occurred"; |
||
218 | case EAI_FAMILY : return "The address family was not recognized or the address length was invalid for the specified family"; |
||
219 | case EAI_NONAME : return "The name does not resolve for the supplied parameters"; |
||
220 | } |
||
221 | |||
222 | return "Unknown error"; |
||
223 | } |
||
224 | fa053ca7 | Martin Storsjö | #endif
|
225 | |||
226 | ba472aaf | Alex Beregszaszi | int ff_socket_nonblock(int socket, int enable) |
227 | { |
||
228 | b250f9c6 | Aurelien Jacobs | #if HAVE_WINSOCK2_H
|
229 | 5676d140 | Alex Beregszaszi | return ioctlsocket(socket, FIONBIO, &enable);
|
230 | #else
|
||
231 | ba472aaf | Alex Beregszaszi | if (enable)
|
232 | return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) | O_NONBLOCK);
|
||
233 | else
|
||
234 | return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) & ~O_NONBLOCK);
|
||
235 | 5676d140 | Alex Beregszaszi | #endif
|
236 | ba472aaf | Alex Beregszaszi | } |
237 | b0c858d8 | François Revol | |
238 | b250f9c6 | Aurelien Jacobs | #if !HAVE_POLL_H
|
239 | b0c858d8 | François Revol | int poll(struct pollfd *fds, nfds_t numfds, int timeout) |
240 | { |
||
241 | fd_set read_set; |
||
242 | fd_set write_set; |
||
243 | fd_set exception_set; |
||
244 | nfds_t i; |
||
245 | int n;
|
||
246 | int rc;
|
||
247 | |||
248 | b250f9c6 | Aurelien Jacobs | #if HAVE_WINSOCK2_H
|
249 | 7235183d | Alex Beregszaszi | if (numfds >= FD_SETSIZE) {
|
250 | errno = EINVAL; |
||
251 | return -1; |
||
252 | } |
||
253 | 3e2e29fb | Alex Beregszaszi | #endif
|
254 | 7235183d | Alex Beregszaszi | |
255 | b0c858d8 | François Revol | FD_ZERO(&read_set); |
256 | FD_ZERO(&write_set); |
||
257 | FD_ZERO(&exception_set); |
||
258 | |||
259 | n = -1;
|
||
260 | for(i = 0; i < numfds; i++) { |
||
261 | if (fds[i].fd < 0) |
||
262 | continue;
|
||
263 | b250f9c6 | Aurelien Jacobs | #if !HAVE_WINSOCK2_H
|
264 | 3e2e29fb | Alex Beregszaszi | if (fds[i].fd >= FD_SETSIZE) {
|
265 | errno = EINVAL; |
||
266 | return -1; |
||
267 | } |
||
268 | #endif
|
||
269 | b0c858d8 | François Revol | |
270 | if (fds[i].events & POLLIN) FD_SET(fds[i].fd, &read_set);
|
||
271 | if (fds[i].events & POLLOUT) FD_SET(fds[i].fd, &write_set);
|
||
272 | if (fds[i].events & POLLERR) FD_SET(fds[i].fd, &exception_set);
|
||
273 | |||
274 | if (fds[i].fd > n)
|
||
275 | n = fds[i].fd; |
||
276 | }; |
||
277 | |||
278 | if (n == -1) |
||
279 | /* Hey!? Nothing to poll, in fact!!! */
|
||
280 | return 0; |
||
281 | |||
282 | if (timeout < 0) |
||
283 | rc = select(n+1, &read_set, &write_set, &exception_set, NULL); |
||
284 | else {
|
||
285 | struct timeval tv;
|
||
286 | |||
287 | tv.tv_sec = timeout / 1000;
|
||
288 | tv.tv_usec = 1000 * (timeout % 1000); |
||
289 | rc = select(n+1, &read_set, &write_set, &exception_set, &tv);
|
||
290 | }; |
||
291 | |||
292 | if (rc < 0) |
||
293 | return rc;
|
||
294 | |||
295 | 9ac2085d | Max Shakhmetov | for(i = 0; i < numfds; i++) { |
296 | b0c858d8 | François Revol | fds[i].revents = 0;
|
297 | |||
298 | if (FD_ISSET(fds[i].fd, &read_set)) fds[i].revents |= POLLIN;
|
||
299 | if (FD_ISSET(fds[i].fd, &write_set)) fds[i].revents |= POLLOUT;
|
||
300 | if (FD_ISSET(fds[i].fd, &exception_set)) fds[i].revents |= POLLERR;
|
||
301 | }; |
||
302 | |||
303 | return rc;
|
||
304 | } |
||
305 | f8cda19e | Luca Abeni | #endif /* HAVE_POLL_H */ |
306 | 362d8f7d | Mans Rullgard | #endif /* CONFIG_NETWORK */ |