• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • Examples
  • File List
  • Globals

libavformat/os_support.c

Go to the documentation of this file.
00001 /*
00002  * Various utilities for ffmpeg system
00003  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
00004  * copyright (c) 2002 Francois Revol
00005  *
00006  * This file is part of FFmpeg.
00007  *
00008  * FFmpeg is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * FFmpeg is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with FFmpeg; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00021  */
00022 
00023 /* needed by inet_aton() */
00024 #define _SVID_SOURCE
00025 
00026 #include "config.h"
00027 #include "avformat.h"
00028 #include "os_support.h"
00029 
00030 #if defined(_WIN32) && !defined(__MINGW32CE__)
00031 #include <windows.h>
00032 
00033 #undef open
00034 int ff_win32_open(const char *filename_utf8, int oflag, int pmode)
00035 {
00036     int fd;
00037     int num_chars;
00038     wchar_t *filename_w;
00039 
00040     /* convert UTF-8 to wide chars */
00041     num_chars = MultiByteToWideChar(CP_UTF8, 0, filename_utf8, -1, NULL, 0);
00042     if (num_chars <= 0)
00043         return -1;
00044     filename_w = av_mallocz(sizeof(wchar_t) * num_chars);
00045     MultiByteToWideChar(CP_UTF8, 0, filename_utf8, -1, filename_w, num_chars);
00046 
00047     fd = _wopen(filename_w, oflag, pmode);
00048     av_freep(&filename_w);
00049 
00050     /* filename maybe be in CP_ACP */
00051     if (fd == -1 && !(oflag & O_CREAT))
00052         return open(filename_utf8, oflag, pmode);
00053 
00054     return fd;
00055 }
00056 #endif
00057 
00058 #if CONFIG_NETWORK
00059 #include <fcntl.h>
00060 #include <unistd.h>
00061 #if !HAVE_POLL_H
00062 #include <sys/time.h>
00063 #if HAVE_WINSOCK2_H
00064 #include <winsock2.h>
00065 #elif HAVE_SYS_SELECT_H
00066 #include <sys/select.h>
00067 #endif
00068 #endif
00069 
00070 #include "network.h"
00071 
00072 #if !HAVE_INET_ATON
00073 #include <stdlib.h>
00074 #include <strings.h>
00075 
00076 int ff_inet_aton (const char * str, struct in_addr * add)
00077 {
00078     unsigned int add1 = 0, add2 = 0, add3 = 0, add4 = 0;
00079 
00080     if (sscanf(str, "%d.%d.%d.%d", &add1, &add2, &add3, &add4) != 4)
00081         return 0;
00082 
00083     if (!add1 || (add1|add2|add3|add4) > 255) return 0;
00084 
00085     add->s_addr = htonl((add1 << 24) + (add2 << 16) + (add3 << 8) + add4);
00086 
00087     return 1;
00088 }
00089 #else
00090 int ff_inet_aton (const char * str, struct in_addr * add)
00091 {
00092     return inet_aton(str, add);
00093 }
00094 #endif /* !HAVE_INET_ATON */
00095 
00096 #if !HAVE_GETADDRINFO
00097 int ff_getaddrinfo(const char *node, const char *service,
00098                 const struct addrinfo *hints, struct addrinfo **res)
00099 {
00100     struct hostent *h = NULL;
00101     struct addrinfo *ai;
00102     struct sockaddr_in *sin;
00103 
00104 #if HAVE_WINSOCK2_H
00105     int (WSAAPI *win_getaddrinfo)(const char *node, const char *service,
00106                                   const struct addrinfo *hints,
00107                                   struct addrinfo **res);
00108     HMODULE ws2mod = GetModuleHandle("ws2_32.dll");
00109     win_getaddrinfo = GetProcAddress(ws2mod, "getaddrinfo");
00110     if (win_getaddrinfo)
00111         return win_getaddrinfo(node, service, hints, res);
00112 #endif
00113 
00114     *res = NULL;
00115     sin = av_mallocz(sizeof(struct sockaddr_in));
00116     if (!sin)
00117         return EAI_FAIL;
00118     sin->sin_family = AF_INET;
00119 
00120     if (node) {
00121         if (!ff_inet_aton(node, &sin->sin_addr)) {
00122             if (hints && (hints->ai_flags & AI_NUMERICHOST)) {
00123                 av_free(sin);
00124                 return EAI_FAIL;
00125             }
00126             h = gethostbyname(node);
00127             if (!h) {
00128                 av_free(sin);
00129                 return EAI_FAIL;
00130             }
00131             memcpy(&sin->sin_addr, h->h_addr_list[0], sizeof(struct in_addr));
00132         }
00133     } else {
00134         if (hints && (hints->ai_flags & AI_PASSIVE)) {
00135             sin->sin_addr.s_addr = INADDR_ANY;
00136         } else
00137             sin->sin_addr.s_addr = INADDR_LOOPBACK;
00138     }
00139 
00140     /* Note: getaddrinfo allows service to be a string, which
00141      * should be looked up using getservbyname. */
00142     if (service)
00143         sin->sin_port = htons(atoi(service));
00144 
00145     ai = av_mallocz(sizeof(struct addrinfo));
00146     if (!ai) {
00147         av_free(sin);
00148         return EAI_FAIL;
00149     }
00150 
00151     *res = ai;
00152     ai->ai_family = AF_INET;
00153     ai->ai_socktype = hints ? hints->ai_socktype : 0;
00154     switch (ai->ai_socktype) {
00155     case SOCK_STREAM: ai->ai_protocol = IPPROTO_TCP; break;
00156     case SOCK_DGRAM:  ai->ai_protocol = IPPROTO_UDP; break;
00157     default:          ai->ai_protocol = 0;           break;
00158     }
00159 
00160     ai->ai_addr = (struct sockaddr *)sin;
00161     ai->ai_addrlen = sizeof(struct sockaddr_in);
00162     if (hints && (hints->ai_flags & AI_CANONNAME))
00163         ai->ai_canonname = h ? av_strdup(h->h_name) : NULL;
00164 
00165     ai->ai_next = NULL;
00166     return 0;
00167 }
00168 
00169 void ff_freeaddrinfo(struct addrinfo *res)
00170 {
00171 #if HAVE_WINSOCK2_H
00172     void (WSAAPI *win_freeaddrinfo)(struct addrinfo *res);
00173     HMODULE ws2mod = GetModuleHandle("ws2_32.dll");
00174     win_freeaddrinfo = (void (WSAAPI *)(struct addrinfo *res))
00175                        GetProcAddress(ws2mod, "freeaddrinfo");
00176     if (win_freeaddrinfo) {
00177         win_freeaddrinfo(res);
00178         return;
00179     }
00180 #endif
00181 
00182     av_free(res->ai_canonname);
00183     av_free(res->ai_addr);
00184     av_free(res);
00185 }
00186 
00187 int ff_getnameinfo(const struct sockaddr *sa, int salen,
00188                    char *host, int hostlen,
00189                    char *serv, int servlen, int flags)
00190 {
00191     const struct sockaddr_in *sin = (const struct sockaddr_in *)sa;
00192 
00193 #if HAVE_WINSOCK2_H
00194     int (WSAAPI *win_getnameinfo)(const struct sockaddr *sa, socklen_t salen,
00195                                   char *host, DWORD hostlen,
00196                                   char *serv, DWORD servlen, int flags);
00197     HMODULE ws2mod = GetModuleHandle("ws2_32.dll");
00198     win_getnameinfo = GetProcAddress(ws2mod, "getnameinfo");
00199     if (win_getnameinfo)
00200         return win_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
00201 #endif
00202 
00203     if (sa->sa_family != AF_INET)
00204         return EAI_FAMILY;
00205     if (!host && !serv)
00206         return EAI_NONAME;
00207 
00208     if (host && hostlen > 0) {
00209         struct hostent *ent = NULL;
00210         uint32_t a;
00211         if (!(flags & NI_NUMERICHOST))
00212             ent = gethostbyaddr((const char *)&sin->sin_addr,
00213                                 sizeof(sin->sin_addr), AF_INET);
00214 
00215         if (ent) {
00216             snprintf(host, hostlen, "%s", ent->h_name);
00217         } else if (flags & NI_NAMERQD) {
00218             return EAI_NONAME;
00219         } else {
00220             a = ntohl(sin->sin_addr.s_addr);
00221             snprintf(host, hostlen, "%d.%d.%d.%d",
00222                      ((a >> 24) & 0xff), ((a >> 16) & 0xff),
00223                      ((a >>  8) & 0xff), ( a        & 0xff));
00224         }
00225     }
00226 
00227     if (serv && servlen > 0) {
00228         struct servent *ent = NULL;
00229         if (!(flags & NI_NUMERICSERV))
00230             ent = getservbyport(sin->sin_port, flags & NI_DGRAM ? "udp" : "tcp");
00231 
00232         if (ent) {
00233             snprintf(serv, servlen, "%s", ent->s_name);
00234         } else
00235             snprintf(serv, servlen, "%d", ntohs(sin->sin_port));
00236     }
00237 
00238     return 0;
00239 }
00240 
00241 const char *ff_gai_strerror(int ecode)
00242 {
00243     switch(ecode) {
00244     case EAI_FAIL   : return "A non-recoverable error occurred";
00245     case EAI_FAMILY : return "The address family was not recognized or the address length was invalid for the specified family";
00246     case EAI_NONAME : return "The name does not resolve for the supplied parameters";
00247     }
00248 
00249     return "Unknown error";
00250 }
00251 #endif
00252 
00253 int ff_socket_nonblock(int socket, int enable)
00254 {
00255 #if HAVE_WINSOCK2_H
00256    return ioctlsocket(socket, FIONBIO, &enable);
00257 #else
00258    if (enable)
00259       return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) | O_NONBLOCK);
00260    else
00261       return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) & ~O_NONBLOCK);
00262 #endif
00263 }
00264 
00265 #if !HAVE_POLL_H
00266 int poll(struct pollfd *fds, nfds_t numfds, int timeout)
00267 {
00268     fd_set read_set;
00269     fd_set write_set;
00270     fd_set exception_set;
00271     nfds_t i;
00272     int n;
00273     int rc;
00274 
00275 #if HAVE_WINSOCK2_H
00276     if (numfds >= FD_SETSIZE) {
00277         errno = EINVAL;
00278         return -1;
00279     }
00280 #endif
00281 
00282     FD_ZERO(&read_set);
00283     FD_ZERO(&write_set);
00284     FD_ZERO(&exception_set);
00285 
00286     n = -1;
00287     for(i = 0; i < numfds; i++) {
00288         if (fds[i].fd < 0)
00289             continue;
00290 #if !HAVE_WINSOCK2_H
00291         if (fds[i].fd >= FD_SETSIZE) {
00292             errno = EINVAL;
00293             return -1;
00294         }
00295 #endif
00296 
00297         if (fds[i].events & POLLIN)  FD_SET(fds[i].fd, &read_set);
00298         if (fds[i].events & POLLOUT) FD_SET(fds[i].fd, &write_set);
00299         if (fds[i].events & POLLERR) FD_SET(fds[i].fd, &exception_set);
00300 
00301         if (fds[i].fd > n)
00302             n = fds[i].fd;
00303     };
00304 
00305     if (n == -1)
00306         /* Hey!? Nothing to poll, in fact!!! */
00307         return 0;
00308 
00309     if (timeout < 0)
00310         rc = select(n+1, &read_set, &write_set, &exception_set, NULL);
00311     else {
00312         struct timeval    tv;
00313 
00314         tv.tv_sec = timeout / 1000;
00315         tv.tv_usec = 1000 * (timeout % 1000);
00316         rc = select(n+1, &read_set, &write_set, &exception_set, &tv);
00317     };
00318 
00319     if (rc < 0)
00320         return rc;
00321 
00322     for(i = 0; i < numfds; i++) {
00323         fds[i].revents = 0;
00324 
00325         if (FD_ISSET(fds[i].fd, &read_set))      fds[i].revents |= POLLIN;
00326         if (FD_ISSET(fds[i].fd, &write_set))     fds[i].revents |= POLLOUT;
00327         if (FD_ISSET(fds[i].fd, &exception_set)) fds[i].revents |= POLLERR;
00328     };
00329 
00330     return rc;
00331 }
00332 #endif /* HAVE_POLL_H */
00333 #endif /* CONFIG_NETWORK */

Generated on Wed Apr 11 2012 07:31:36 for FFmpeg by  doxygen 1.7.1