X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fos_support.c;h=76187082836a5abb0d07b11efbcd98aa00a7d7f7;hb=66adb7ce1bc1cc5e3f1c4b1cd9f20ac68086a486;hp=58215ec19865cc52463d8db4cf91093f199f2d50;hpb=6023d84a2b7aa6d5f02de91541c514c36e553de0;p=ffmpeg diff --git a/libavformat/os_support.c b/libavformat/os_support.c index 58215ec1986..76187082836 100644 --- a/libavformat/os_support.c +++ b/libavformat/os_support.c @@ -1,22 +1,22 @@ /* - * Various utilities for ffmpeg system + * various OS-feature replacement utilities * Copyright (c) 2000, 2001, 2002 Fabrice Bellard * copyright (c) 2002 Francois Revol * - * This file is part of FFmpeg. + * This file is part of Libav. * - * FFmpeg is free software; you can redistribute it and/or + * Libav is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * FFmpeg is distributed in the hope that it will be useful, + * Libav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software + * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -25,13 +25,44 @@ #include "config.h" #include "avformat.h" -#include -#include -#include #include "os_support.h" +#if defined(_WIN32) && !defined(__MINGW32CE__) +#undef open +#include +#include +#include + +int ff_win32_open(const char *filename_utf8, int oflag, int pmode) +{ + int fd; + int num_chars; + wchar_t *filename_w; + + /* convert UTF-8 to wide chars */ + num_chars = MultiByteToWideChar(CP_UTF8, 0, filename_utf8, -1, NULL, 0); + if (num_chars <= 0) + return -1; + filename_w = av_mallocz(sizeof(wchar_t) * num_chars); + MultiByteToWideChar(CP_UTF8, 0, filename_utf8, -1, filename_w, num_chars); + + fd = _wopen(filename_w, oflag, pmode); + av_freep(&filename_w); + + /* filename maybe be in CP_ACP */ + if (fd == -1 && !(oflag & O_CREAT)) + return open(filename_utf8, oflag, pmode); + + return fd; +} +#endif + #if CONFIG_NETWORK +#include #if !HAVE_POLL_H +#if HAVE_SYS_TIME_H +#include +#endif #if HAVE_WINSOCK2_H #include #elif HAVE_SYS_SELECT_H @@ -43,26 +74,31 @@ #if !HAVE_INET_ATON #include -#include -int inet_aton (const char * str, struct in_addr * add) +int ff_inet_aton(const char *str, struct in_addr *add) { unsigned int add1 = 0, add2 = 0, add3 = 0, add4 = 0; if (sscanf(str, "%d.%d.%d.%d", &add1, &add2, &add3, &add4) != 4) return 0; - if (!add1 || (add1|add2|add3|add4) > 255) return 0; + if (!add1 || (add1 | add2 | add3 | add4) > 255) + return 0; add->s_addr = htonl((add1 << 24) + (add2 << 16) + (add3 << 8) + add4); return 1; } +#else +int ff_inet_aton(const char *str, struct in_addr *add) +{ + return inet_aton(str, add); +} #endif /* !HAVE_INET_ATON */ #if !HAVE_GETADDRINFO int ff_getaddrinfo(const char *node, const char *service, - const struct addrinfo *hints, struct addrinfo **res) + const struct addrinfo *hints, struct addrinfo **res) { struct hostent *h = NULL; struct addrinfo *ai; @@ -78,13 +114,14 @@ int ff_getaddrinfo(const char *node, const char *service, return win_getaddrinfo(node, service, hints, res); #endif - sin = av_mallocz(sizeof(struct sockaddr_in)); + *res = NULL; + sin = av_mallocz(sizeof(struct sockaddr_in)); if (!sin) return EAI_FAIL; sin->sin_family = AF_INET; if (node) { - if (!inet_aton(node, &sin->sin_addr)) { + if (!ff_inet_aton(node, &sin->sin_addr)) { if (hints && (hints->ai_flags & AI_NUMERICHOST)) { av_free(sin); return EAI_FAIL; @@ -97,9 +134,9 @@ int ff_getaddrinfo(const char *node, const char *service, memcpy(&sin->sin_addr, h->h_addr_list[0], sizeof(struct in_addr)); } } else { - if (hints && (hints->ai_flags & AI_PASSIVE)) { + if (hints && (hints->ai_flags & AI_PASSIVE)) sin->sin_addr.s_addr = INADDR_ANY; - } else + else sin->sin_addr.s_addr = INADDR_LOOPBACK; } @@ -114,16 +151,22 @@ int ff_getaddrinfo(const char *node, const char *service, return EAI_FAIL; } - *res = ai; - ai->ai_family = AF_INET; + *res = ai; + ai->ai_family = AF_INET; ai->ai_socktype = hints ? hints->ai_socktype : 0; switch (ai->ai_socktype) { - case SOCK_STREAM: ai->ai_protocol = IPPROTO_TCP; break; - case SOCK_DGRAM: ai->ai_protocol = IPPROTO_UDP; break; - default: ai->ai_protocol = 0; break; + case SOCK_STREAM: + ai->ai_protocol = IPPROTO_TCP; + break; + case SOCK_DGRAM: + ai->ai_protocol = IPPROTO_UDP; + break; + default: + ai->ai_protocol = 0; + break; } - ai->ai_addr = (struct sockaddr *)sin; + ai->ai_addr = (struct sockaddr *)sin; ai->ai_addrlen = sizeof(struct sockaddr_in); if (hints && (hints->ai_flags & AI_CANONNAME)) ai->ai_canonname = h ? av_strdup(h->h_name) : NULL; @@ -186,7 +229,7 @@ int ff_getnameinfo(const struct sockaddr *sa, int salen, a = ntohl(sin->sin_addr.s_addr); snprintf(host, hostlen, "%d.%d.%d.%d", ((a >> 24) & 0xff), ((a >> 16) & 0xff), - ((a >> 8) & 0xff), ( a & 0xff)); + ((a >> 8) & 0xff), (a & 0xff)); } } @@ -195,67 +238,62 @@ int ff_getnameinfo(const struct sockaddr *sa, int salen, if (!(flags & NI_NUMERICSERV)) ent = getservbyport(sin->sin_port, flags & NI_DGRAM ? "udp" : "tcp"); - if (ent) { + if (ent) snprintf(serv, servlen, "%s", ent->s_name); - } else + else snprintf(serv, servlen, "%d", ntohs(sin->sin_port)); } return 0; } -#endif +#endif /* !HAVE_GETADDRINFO */ -/* resolve host with also IP address parsing */ -int resolve_host(struct in_addr *sin_addr, const char *hostname) +#if !HAVE_GETADDRINFO || HAVE_WINSOCK2_H +const char *ff_gai_strerror(int ecode) { - - if (!inet_aton(hostname, sin_addr)) { -#if HAVE_GETADDRINFO - struct addrinfo *ai, *cur; - struct addrinfo hints; - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_INET; - if (getaddrinfo(hostname, NULL, &hints, &ai)) - return -1; - /* getaddrinfo returns a linked list of addrinfo structs. - * Even if we set ai_family = AF_INET above, make sure - * that the returned one actually is of the correct type. */ - for (cur = ai; cur; cur = cur->ai_next) { - if (cur->ai_family == AF_INET) { - *sin_addr = ((struct sockaddr_in *)cur->ai_addr)->sin_addr; - freeaddrinfo(ai); - return 0; - } - } - freeaddrinfo(ai); - return -1; -#else - struct hostent *hp; - hp = gethostbyname(hostname); - if (!hp) - return -1; - memcpy(sin_addr, hp->h_addr_list[0], sizeof(struct in_addr)); + switch (ecode) { + case EAI_AGAIN: + return "Temporary failure in name resolution"; + case EAI_BADFLAGS: + return "Invalid flags for ai_flags"; + case EAI_FAIL: + return "A non-recoverable error occurred"; + case EAI_FAMILY: + return "The address family was not recognized or the address " + "length was invalid for the specified family"; + case EAI_MEMORY: + return "Memory allocation failure"; +#if EAI_NODATA != EAI_NONAME + case EAI_NODATA: + return "No address associated with hostname"; #endif + case EAI_NONAME: + return "The name does not resolve for the supplied parameters"; + case EAI_SERVICE: + return "servname not supported for ai_socktype"; + case EAI_SOCKTYPE: + return "ai_socktype not supported"; } - return 0; + + return "Unknown error"; } +#endif /* !HAVE_GETADDRINFO || HAVE_WINSOCK2_H */ int ff_socket_nonblock(int socket, int enable) { #if HAVE_WINSOCK2_H - return ioctlsocket(socket, FIONBIO, &enable); + u_long param = enable; + return ioctlsocket(socket, FIONBIO, ¶m); #else - if (enable) - return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) | O_NONBLOCK); - else - return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) & ~O_NONBLOCK); + if (enable) + return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) | O_NONBLOCK); + else + return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) & ~O_NONBLOCK); #endif } -#endif /* CONFIG_NETWORK */ -#if CONFIG_FFSERVER #if !HAVE_POLL_H -int poll(struct pollfd *fds, nfds_t numfds, int timeout) +int ff_poll(struct pollfd *fds, nfds_t numfds, int timeout) { fd_set read_set; fd_set write_set; @@ -275,8 +313,8 @@ int poll(struct pollfd *fds, nfds_t numfds, int timeout) FD_ZERO(&write_set); FD_ZERO(&exception_set); - n = -1; - for(i = 0; i < numfds; i++) { + n = 0; + for (i = 0; i < numfds; i++) { if (fds[i].fd < 0) continue; #if !HAVE_WINSOCK2_H @@ -286,41 +324,45 @@ int poll(struct pollfd *fds, nfds_t numfds, int timeout) } #endif - if (fds[i].events & POLLIN) FD_SET(fds[i].fd, &read_set); - if (fds[i].events & POLLOUT) FD_SET(fds[i].fd, &write_set); - if (fds[i].events & POLLERR) FD_SET(fds[i].fd, &exception_set); + if (fds[i].events & POLLIN) + FD_SET(fds[i].fd, &read_set); + if (fds[i].events & POLLOUT) + FD_SET(fds[i].fd, &write_set); + if (fds[i].events & POLLERR) + FD_SET(fds[i].fd, &exception_set); - if (fds[i].fd > n) - n = fds[i].fd; - }; + if (fds[i].fd >= n) + n = fds[i].fd + 1; + } - if (n == -1) + if (n == 0) /* Hey!? Nothing to poll, in fact!!! */ return 0; - if (timeout < 0) - rc = select(n+1, &read_set, &write_set, &exception_set, NULL); - else { - struct timeval tv; - - tv.tv_sec = timeout / 1000; + if (timeout < 0) { + rc = select(n, &read_set, &write_set, &exception_set, NULL); + } else { + struct timeval tv; + tv.tv_sec = timeout / 1000; tv.tv_usec = 1000 * (timeout % 1000); - rc = select(n+1, &read_set, &write_set, &exception_set, &tv); - }; + rc = select(n, &read_set, &write_set, &exception_set, &tv); + } if (rc < 0) return rc; - for(i = 0; i < (nfds_t) n; i++) { + for (i = 0; i < numfds; i++) { fds[i].revents = 0; - if (FD_ISSET(fds[i].fd, &read_set)) fds[i].revents |= POLLIN; - if (FD_ISSET(fds[i].fd, &write_set)) fds[i].revents |= POLLOUT; - if (FD_ISSET(fds[i].fd, &exception_set)) fds[i].revents |= POLLERR; - }; + if (FD_ISSET(fds[i].fd, &read_set)) + fds[i].revents |= POLLIN; + if (FD_ISSET(fds[i].fd, &write_set)) + fds[i].revents |= POLLOUT; + if (FD_ISSET(fds[i].fd, &exception_set)) + fds[i].revents |= POLLERR; + } return rc; } #endif /* HAVE_POLL_H */ -#endif /* CONFIG_FFSERVER */ - +#endif /* CONFIG_NETWORK */