annotate ffmpeg/libavformat/os_support.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents f445c3017523
children
rev   line source
yading@11 1 /*
yading@11 2 * various OS-feature replacement utilities
yading@11 3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
yading@11 4 * copyright (c) 2002 Francois Revol
yading@11 5 *
yading@11 6 * This file is part of FFmpeg.
yading@11 7 *
yading@11 8 * FFmpeg is free software; you can redistribute it and/or
yading@11 9 * modify it under the terms of the GNU Lesser General Public
yading@11 10 * License as published by the Free Software Foundation; either
yading@11 11 * version 2.1 of the License, or (at your option) any later version.
yading@11 12 *
yading@11 13 * FFmpeg is distributed in the hope that it will be useful,
yading@11 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@11 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@11 16 * Lesser General Public License for more details.
yading@11 17 *
yading@11 18 * You should have received a copy of the GNU Lesser General Public
yading@11 19 * License along with FFmpeg; if not, write to the Free Software
yading@11 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@11 21 */
yading@11 22
yading@11 23 /* needed by inet_aton() */
yading@11 24 #define _SVID_SOURCE
yading@11 25
yading@11 26 #include "config.h"
yading@11 27 #include "avformat.h"
yading@11 28 #include "os_support.h"
yading@11 29
yading@11 30 #if defined(_WIN32) && !defined(__MINGW32CE__)
yading@11 31 #undef open
yading@11 32 #undef lseek
yading@11 33 #undef stat
yading@11 34 #undef fstat
yading@11 35 #include <fcntl.h>
yading@11 36 #include <io.h>
yading@11 37 #include <windows.h>
yading@11 38 #include <share.h>
yading@11 39 #include <errno.h>
yading@11 40
yading@11 41 int ff_win32_open(const char *filename_utf8, int oflag, int pmode)
yading@11 42 {
yading@11 43 int fd;
yading@11 44 int num_chars;
yading@11 45 wchar_t *filename_w;
yading@11 46
yading@11 47 /* convert UTF-8 to wide chars */
yading@11 48 num_chars = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, filename_utf8, -1, NULL, 0);
yading@11 49 if (num_chars <= 0)
yading@11 50 goto fallback;
yading@11 51 filename_w = av_mallocz(sizeof(wchar_t) * num_chars);
yading@11 52 if (!filename_w) {
yading@11 53 errno = ENOMEM;
yading@11 54 return -1;
yading@11 55 }
yading@11 56 MultiByteToWideChar(CP_UTF8, 0, filename_utf8, -1, filename_w, num_chars);
yading@11 57
yading@11 58 fd = _wsopen(filename_w, oflag, SH_DENYNO, pmode);
yading@11 59 av_freep(&filename_w);
yading@11 60
yading@11 61 if (fd != -1 || (oflag & O_CREAT))
yading@11 62 return fd;
yading@11 63
yading@11 64 fallback:
yading@11 65 /* filename may be be in CP_ACP */
yading@11 66 return _sopen(filename_utf8, oflag, SH_DENYNO, pmode);
yading@11 67 }
yading@11 68 #endif
yading@11 69
yading@11 70 #if CONFIG_NETWORK
yading@11 71 #include <fcntl.h>
yading@11 72 #if !HAVE_POLL_H
yading@11 73 #if HAVE_SYS_TIME_H
yading@11 74 #include <sys/time.h>
yading@11 75 #endif
yading@11 76 #if HAVE_WINSOCK2_H
yading@11 77 #include <winsock2.h>
yading@11 78 #elif HAVE_SYS_SELECT_H
yading@11 79 #include <sys/select.h>
yading@11 80 #endif
yading@11 81 #endif
yading@11 82
yading@11 83 #include "network.h"
yading@11 84
yading@11 85 #if !HAVE_INET_ATON
yading@11 86 #include <stdlib.h>
yading@11 87
yading@11 88 int ff_inet_aton(const char *str, struct in_addr *add)
yading@11 89 {
yading@11 90 unsigned int add1 = 0, add2 = 0, add3 = 0, add4 = 0;
yading@11 91
yading@11 92 if (sscanf(str, "%d.%d.%d.%d", &add1, &add2, &add3, &add4) != 4)
yading@11 93 return 0;
yading@11 94
yading@11 95 if (!add1 || (add1 | add2 | add3 | add4) > 255)
yading@11 96 return 0;
yading@11 97
yading@11 98 add->s_addr = htonl((add1 << 24) + (add2 << 16) + (add3 << 8) + add4);
yading@11 99
yading@11 100 return 1;
yading@11 101 }
yading@11 102 #else
yading@11 103 int ff_inet_aton(const char *str, struct in_addr *add)
yading@11 104 {
yading@11 105 return inet_aton(str, add);
yading@11 106 }
yading@11 107 #endif /* !HAVE_INET_ATON */
yading@11 108
yading@11 109 #if !HAVE_GETADDRINFO
yading@11 110 int ff_getaddrinfo(const char *node, const char *service,
yading@11 111 const struct addrinfo *hints, struct addrinfo **res)
yading@11 112 {
yading@11 113 struct hostent *h = NULL;
yading@11 114 struct addrinfo *ai;
yading@11 115 struct sockaddr_in *sin;
yading@11 116
yading@11 117 #if HAVE_WINSOCK2_H
yading@11 118 int (WSAAPI *win_getaddrinfo)(const char *node, const char *service,
yading@11 119 const struct addrinfo *hints,
yading@11 120 struct addrinfo **res);
yading@11 121 HMODULE ws2mod = GetModuleHandle("ws2_32.dll");
yading@11 122 win_getaddrinfo = GetProcAddress(ws2mod, "getaddrinfo");
yading@11 123 if (win_getaddrinfo)
yading@11 124 return win_getaddrinfo(node, service, hints, res);
yading@11 125 #endif
yading@11 126
yading@11 127 *res = NULL;
yading@11 128 sin = av_mallocz(sizeof(struct sockaddr_in));
yading@11 129 if (!sin)
yading@11 130 return EAI_FAIL;
yading@11 131 sin->sin_family = AF_INET;
yading@11 132
yading@11 133 if (node) {
yading@11 134 if (!ff_inet_aton(node, &sin->sin_addr)) {
yading@11 135 if (hints && (hints->ai_flags & AI_NUMERICHOST)) {
yading@11 136 av_free(sin);
yading@11 137 return EAI_FAIL;
yading@11 138 }
yading@11 139 h = gethostbyname(node);
yading@11 140 if (!h) {
yading@11 141 av_free(sin);
yading@11 142 return EAI_FAIL;
yading@11 143 }
yading@11 144 memcpy(&sin->sin_addr, h->h_addr_list[0], sizeof(struct in_addr));
yading@11 145 }
yading@11 146 } else {
yading@11 147 if (hints && (hints->ai_flags & AI_PASSIVE))
yading@11 148 sin->sin_addr.s_addr = INADDR_ANY;
yading@11 149 else
yading@11 150 sin->sin_addr.s_addr = INADDR_LOOPBACK;
yading@11 151 }
yading@11 152
yading@11 153 /* Note: getaddrinfo allows service to be a string, which
yading@11 154 * should be looked up using getservbyname. */
yading@11 155 if (service)
yading@11 156 sin->sin_port = htons(atoi(service));
yading@11 157
yading@11 158 ai = av_mallocz(sizeof(struct addrinfo));
yading@11 159 if (!ai) {
yading@11 160 av_free(sin);
yading@11 161 return EAI_FAIL;
yading@11 162 }
yading@11 163
yading@11 164 *res = ai;
yading@11 165 ai->ai_family = AF_INET;
yading@11 166 ai->ai_socktype = hints ? hints->ai_socktype : 0;
yading@11 167 switch (ai->ai_socktype) {
yading@11 168 case SOCK_STREAM:
yading@11 169 ai->ai_protocol = IPPROTO_TCP;
yading@11 170 break;
yading@11 171 case SOCK_DGRAM:
yading@11 172 ai->ai_protocol = IPPROTO_UDP;
yading@11 173 break;
yading@11 174 default:
yading@11 175 ai->ai_protocol = 0;
yading@11 176 break;
yading@11 177 }
yading@11 178
yading@11 179 ai->ai_addr = (struct sockaddr *)sin;
yading@11 180 ai->ai_addrlen = sizeof(struct sockaddr_in);
yading@11 181 if (hints && (hints->ai_flags & AI_CANONNAME))
yading@11 182 ai->ai_canonname = h ? av_strdup(h->h_name) : NULL;
yading@11 183
yading@11 184 ai->ai_next = NULL;
yading@11 185 return 0;
yading@11 186 }
yading@11 187
yading@11 188 void ff_freeaddrinfo(struct addrinfo *res)
yading@11 189 {
yading@11 190 #if HAVE_WINSOCK2_H
yading@11 191 void (WSAAPI *win_freeaddrinfo)(struct addrinfo *res);
yading@11 192 HMODULE ws2mod = GetModuleHandle("ws2_32.dll");
yading@11 193 win_freeaddrinfo = (void (WSAAPI *)(struct addrinfo *res))
yading@11 194 GetProcAddress(ws2mod, "freeaddrinfo");
yading@11 195 if (win_freeaddrinfo) {
yading@11 196 win_freeaddrinfo(res);
yading@11 197 return;
yading@11 198 }
yading@11 199 #endif
yading@11 200
yading@11 201 av_free(res->ai_canonname);
yading@11 202 av_free(res->ai_addr);
yading@11 203 av_free(res);
yading@11 204 }
yading@11 205
yading@11 206 int ff_getnameinfo(const struct sockaddr *sa, int salen,
yading@11 207 char *host, int hostlen,
yading@11 208 char *serv, int servlen, int flags)
yading@11 209 {
yading@11 210 const struct sockaddr_in *sin = (const struct sockaddr_in *)sa;
yading@11 211
yading@11 212 #if HAVE_WINSOCK2_H
yading@11 213 int (WSAAPI *win_getnameinfo)(const struct sockaddr *sa, socklen_t salen,
yading@11 214 char *host, DWORD hostlen,
yading@11 215 char *serv, DWORD servlen, int flags);
yading@11 216 HMODULE ws2mod = GetModuleHandle("ws2_32.dll");
yading@11 217 win_getnameinfo = GetProcAddress(ws2mod, "getnameinfo");
yading@11 218 if (win_getnameinfo)
yading@11 219 return win_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
yading@11 220 #endif
yading@11 221
yading@11 222 if (sa->sa_family != AF_INET)
yading@11 223 return EAI_FAMILY;
yading@11 224 if (!host && !serv)
yading@11 225 return EAI_NONAME;
yading@11 226
yading@11 227 if (host && hostlen > 0) {
yading@11 228 struct hostent *ent = NULL;
yading@11 229 uint32_t a;
yading@11 230 if (!(flags & NI_NUMERICHOST))
yading@11 231 ent = gethostbyaddr((const char *)&sin->sin_addr,
yading@11 232 sizeof(sin->sin_addr), AF_INET);
yading@11 233
yading@11 234 if (ent) {
yading@11 235 snprintf(host, hostlen, "%s", ent->h_name);
yading@11 236 } else if (flags & NI_NAMERQD) {
yading@11 237 return EAI_NONAME;
yading@11 238 } else {
yading@11 239 a = ntohl(sin->sin_addr.s_addr);
yading@11 240 snprintf(host, hostlen, "%d.%d.%d.%d",
yading@11 241 ((a >> 24) & 0xff), ((a >> 16) & 0xff),
yading@11 242 ((a >> 8) & 0xff), (a & 0xff));
yading@11 243 }
yading@11 244 }
yading@11 245
yading@11 246 if (serv && servlen > 0) {
yading@11 247 struct servent *ent = NULL;
yading@11 248 #if HAVE_GETSERVBYPORT
yading@11 249 if (!(flags & NI_NUMERICSERV))
yading@11 250 ent = getservbyport(sin->sin_port, flags & NI_DGRAM ? "udp" : "tcp");
yading@11 251 #endif
yading@11 252
yading@11 253 if (ent)
yading@11 254 snprintf(serv, servlen, "%s", ent->s_name);
yading@11 255 else
yading@11 256 snprintf(serv, servlen, "%d", ntohs(sin->sin_port));
yading@11 257 }
yading@11 258
yading@11 259 return 0;
yading@11 260 }
yading@11 261 #endif /* !HAVE_GETADDRINFO */
yading@11 262
yading@11 263 #if !HAVE_GETADDRINFO || HAVE_WINSOCK2_H
yading@11 264 const char *ff_gai_strerror(int ecode)
yading@11 265 {
yading@11 266 switch (ecode) {
yading@11 267 case EAI_AGAIN:
yading@11 268 return "Temporary failure in name resolution";
yading@11 269 case EAI_BADFLAGS:
yading@11 270 return "Invalid flags for ai_flags";
yading@11 271 case EAI_FAIL:
yading@11 272 return "A non-recoverable error occurred";
yading@11 273 case EAI_FAMILY:
yading@11 274 return "The address family was not recognized or the address "
yading@11 275 "length was invalid for the specified family";
yading@11 276 case EAI_MEMORY:
yading@11 277 return "Memory allocation failure";
yading@11 278 #if EAI_NODATA != EAI_NONAME
yading@11 279 case EAI_NODATA:
yading@11 280 return "No address associated with hostname";
yading@11 281 #endif
yading@11 282 case EAI_NONAME:
yading@11 283 return "The name does not resolve for the supplied parameters";
yading@11 284 case EAI_SERVICE:
yading@11 285 return "servname not supported for ai_socktype";
yading@11 286 case EAI_SOCKTYPE:
yading@11 287 return "ai_socktype not supported";
yading@11 288 }
yading@11 289
yading@11 290 return "Unknown error";
yading@11 291 }
yading@11 292 #endif /* !HAVE_GETADDRINFO || HAVE_WINSOCK2_H */
yading@11 293
yading@11 294 int ff_socket_nonblock(int socket, int enable)
yading@11 295 {
yading@11 296 #if HAVE_WINSOCK2_H
yading@11 297 u_long param = enable;
yading@11 298 return ioctlsocket(socket, FIONBIO, &param);
yading@11 299 #else
yading@11 300 if (enable)
yading@11 301 return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) | O_NONBLOCK);
yading@11 302 else
yading@11 303 return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) & ~O_NONBLOCK);
yading@11 304 #endif
yading@11 305 }
yading@11 306
yading@11 307 #if !HAVE_POLL_H
yading@11 308 int ff_poll(struct pollfd *fds, nfds_t numfds, int timeout)
yading@11 309 {
yading@11 310 fd_set read_set;
yading@11 311 fd_set write_set;
yading@11 312 fd_set exception_set;
yading@11 313 nfds_t i;
yading@11 314 int n;
yading@11 315 int rc;
yading@11 316
yading@11 317 #if HAVE_WINSOCK2_H
yading@11 318 if (numfds >= FD_SETSIZE) {
yading@11 319 errno = EINVAL;
yading@11 320 return -1;
yading@11 321 }
yading@11 322 #endif
yading@11 323
yading@11 324 FD_ZERO(&read_set);
yading@11 325 FD_ZERO(&write_set);
yading@11 326 FD_ZERO(&exception_set);
yading@11 327
yading@11 328 n = 0;
yading@11 329 for (i = 0; i < numfds; i++) {
yading@11 330 if (fds[i].fd < 0)
yading@11 331 continue;
yading@11 332 #if !HAVE_WINSOCK2_H
yading@11 333 if (fds[i].fd >= FD_SETSIZE) {
yading@11 334 errno = EINVAL;
yading@11 335 return -1;
yading@11 336 }
yading@11 337 #endif
yading@11 338
yading@11 339 if (fds[i].events & POLLIN)
yading@11 340 FD_SET(fds[i].fd, &read_set);
yading@11 341 if (fds[i].events & POLLOUT)
yading@11 342 FD_SET(fds[i].fd, &write_set);
yading@11 343 if (fds[i].events & POLLERR)
yading@11 344 FD_SET(fds[i].fd, &exception_set);
yading@11 345
yading@11 346 if (fds[i].fd >= n)
yading@11 347 n = fds[i].fd + 1;
yading@11 348 }
yading@11 349
yading@11 350 if (n == 0)
yading@11 351 /* Hey!? Nothing to poll, in fact!!! */
yading@11 352 return 0;
yading@11 353
yading@11 354 if (timeout < 0) {
yading@11 355 rc = select(n, &read_set, &write_set, &exception_set, NULL);
yading@11 356 } else {
yading@11 357 struct timeval tv;
yading@11 358 tv.tv_sec = timeout / 1000;
yading@11 359 tv.tv_usec = 1000 * (timeout % 1000);
yading@11 360 rc = select(n, &read_set, &write_set, &exception_set, &tv);
yading@11 361 }
yading@11 362
yading@11 363 if (rc < 0)
yading@11 364 return rc;
yading@11 365
yading@11 366 for (i = 0; i < numfds; i++) {
yading@11 367 fds[i].revents = 0;
yading@11 368
yading@11 369 if (FD_ISSET(fds[i].fd, &read_set))
yading@11 370 fds[i].revents |= POLLIN;
yading@11 371 if (FD_ISSET(fds[i].fd, &write_set))
yading@11 372 fds[i].revents |= POLLOUT;
yading@11 373 if (FD_ISSET(fds[i].fd, &exception_set))
yading@11 374 fds[i].revents |= POLLERR;
yading@11 375 }
yading@11 376
yading@11 377 return rc;
yading@11 378 }
yading@11 379 #endif /* HAVE_POLL_H */
yading@11 380 #endif /* CONFIG_NETWORK */