• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • 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 #define _DARWIN_C_SOURCE
00026 
00027 #include "config.h"
00028 #include "avformat.h"
00029 #include <unistd.h>
00030 #include <fcntl.h>
00031 #include <sys/time.h>
00032 #include "os_support.h"
00033 
00034 #if CONFIG_NETWORK
00035 #if !HAVE_POLL_H
00036 #if HAVE_WINSOCK2_H
00037 #include <winsock2.h>
00038 #elif HAVE_SYS_SELECT_H
00039 #include <sys/select.h>
00040 #endif
00041 #endif
00042 
00043 #include "network.h"
00044 
00045 #if !HAVE_INET_ATON
00046 #include <stdlib.h>
00047 #include <strings.h>
00048 
00049 int ff_inet_aton (const char * str, struct in_addr * add)
00050 {
00051     unsigned int add1 = 0, add2 = 0, add3 = 0, add4 = 0;
00052 
00053     if (sscanf(str, "%d.%d.%d.%d", &add1, &add2, &add3, &add4) != 4)
00054         return 0;
00055 
00056     if (!add1 || (add1|add2|add3|add4) > 255) return 0;
00057 
00058     add->s_addr = htonl((add1 << 24) + (add2 << 16) + (add3 << 8) + add4);
00059 
00060     return 1;
00061 }
00062 #else
00063 int ff_inet_aton (const char * str, struct in_addr * add)
00064 {
00065     return inet_aton(str, add);
00066 }
00067 #endif /* !HAVE_INET_ATON */
00068 
00069 #if !HAVE_GETADDRINFO
00070 int ff_getaddrinfo(const char *node, const char *service,
00071                 const struct addrinfo *hints, struct addrinfo **res)
00072 {
00073     struct hostent *h = NULL;
00074     struct addrinfo *ai;
00075     struct sockaddr_in *sin;
00076 
00077 #if HAVE_WINSOCK2_H
00078     int (WSAAPI *win_getaddrinfo)(const char *node, const char *service,
00079                                   const struct addrinfo *hints,
00080                                   struct addrinfo **res);
00081     HMODULE ws2mod = GetModuleHandle("ws2_32.dll");
00082     win_getaddrinfo = GetProcAddress(ws2mod, "getaddrinfo");
00083     if (win_getaddrinfo)
00084         return win_getaddrinfo(node, service, hints, res);
00085 #endif
00086 
00087     *res = NULL;
00088     sin = av_mallocz(sizeof(struct sockaddr_in));
00089     if (!sin)
00090         return EAI_FAIL;
00091     sin->sin_family = AF_INET;
00092 
00093     if (node) {
00094         if (!ff_inet_aton(node, &sin->sin_addr)) {
00095             if (hints && (hints->ai_flags & AI_NUMERICHOST)) {
00096                 av_free(sin);
00097                 return EAI_FAIL;
00098             }
00099             h = gethostbyname(node);
00100             if (!h) {
00101                 av_free(sin);
00102                 return EAI_FAIL;
00103             }
00104             memcpy(&sin->sin_addr, h->h_addr_list[0], sizeof(struct in_addr));
00105         }
00106     } else {
00107         if (hints && (hints->ai_flags & AI_PASSIVE)) {
00108             sin->sin_addr.s_addr = INADDR_ANY;
00109         } else
00110             sin->sin_addr.s_addr = INADDR_LOOPBACK;
00111     }
00112 
00113     /* Note: getaddrinfo allows service to be a string, which
00114      * should be looked up using getservbyname. */
00115     if (service)
00116         sin->sin_port = htons(atoi(service));
00117 
00118     ai = av_mallocz(sizeof(struct addrinfo));
00119     if (!ai) {
00120         av_free(sin);
00121         return EAI_FAIL;
00122     }
00123 
00124     *res = ai;
00125     ai->ai_family = AF_INET;
00126     ai->ai_socktype = hints ? hints->ai_socktype : 0;
00127     switch (ai->ai_socktype) {
00128     case SOCK_STREAM: ai->ai_protocol = IPPROTO_TCP; break;
00129     case SOCK_DGRAM:  ai->ai_protocol = IPPROTO_UDP; break;
00130     default:          ai->ai_protocol = 0;           break;
00131     }
00132 
00133     ai->ai_addr = (struct sockaddr *)sin;
00134     ai->ai_addrlen = sizeof(struct sockaddr_in);
00135     if (hints && (hints->ai_flags & AI_CANONNAME))
00136         ai->ai_canonname = h ? av_strdup(h->h_name) : NULL;
00137 
00138     ai->ai_next = NULL;
00139     return 0;
00140 }
00141 
00142 void ff_freeaddrinfo(struct addrinfo *res)
00143 {
00144 #if HAVE_WINSOCK2_H
00145     void (WSAAPI *win_freeaddrinfo)(struct addrinfo *res);
00146     HMODULE ws2mod = GetModuleHandle("ws2_32.dll");
00147     win_freeaddrinfo = (void (WSAAPI *)(struct addrinfo *res))
00148                        GetProcAddress(ws2mod, "freeaddrinfo");
00149     if (win_freeaddrinfo) {
00150         win_freeaddrinfo(res);
00151         return;
00152     }
00153 #endif
00154 
00155     av_free(res->ai_canonname);
00156     av_free(res->ai_addr);
00157     av_free(res);
00158 }
00159 
00160 int ff_getnameinfo(const struct sockaddr *sa, int salen,
00161                    char *host, int hostlen,
00162                    char *serv, int servlen, int flags)
00163 {
00164     const struct sockaddr_in *sin = (const struct sockaddr_in *)sa;
00165 
00166 #if HAVE_WINSOCK2_H
00167     int (WSAAPI *win_getnameinfo)(const struct sockaddr *sa, socklen_t salen,
00168                                   char *host, DWORD hostlen,
00169                                   char *serv, DWORD servlen, int flags);
00170     HMODULE ws2mod = GetModuleHandle("ws2_32.dll");
00171     win_getnameinfo = GetProcAddress(ws2mod, "getnameinfo");
00172     if (win_getnameinfo)
00173         return win_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
00174 #endif
00175 
00176     if (sa->sa_family != AF_INET)
00177         return EAI_FAMILY;
00178     if (!host && !serv)
00179         return EAI_NONAME;
00180 
00181     if (host && hostlen > 0) {
00182         struct hostent *ent = NULL;
00183         uint32_t a;
00184         if (!(flags & NI_NUMERICHOST))
00185             ent = gethostbyaddr((const char *)&sin->sin_addr,
00186                                 sizeof(sin->sin_addr), AF_INET);
00187 
00188         if (ent) {
00189             snprintf(host, hostlen, "%s", ent->h_name);
00190         } else if (flags & NI_NAMERQD) {
00191             return EAI_NONAME;
00192         } else {
00193             a = ntohl(sin->sin_addr.s_addr);
00194             snprintf(host, hostlen, "%d.%d.%d.%d",
00195                      ((a >> 24) & 0xff), ((a >> 16) & 0xff),
00196                      ((a >>  8) & 0xff), ( a        & 0xff));
00197         }
00198     }
00199 
00200     if (serv && servlen > 0) {
00201         struct servent *ent = NULL;
00202         if (!(flags & NI_NUMERICSERV))
00203             ent = getservbyport(sin->sin_port, flags & NI_DGRAM ? "udp" : "tcp");
00204 
00205         if (ent) {
00206             snprintf(serv, servlen, "%s", ent->s_name);
00207         } else
00208             snprintf(serv, servlen, "%d", ntohs(sin->sin_port));
00209     }
00210 
00211     return 0;
00212 }
00213 
00214 const char *ff_gai_strerror(int ecode)
00215 {
00216     switch(ecode) {
00217     case EAI_FAIL   : return "A non-recoverable error occurred";
00218     case EAI_FAMILY : return "The address family was not recognized or the address length was invalid for the specified family";
00219     case EAI_NONAME : return "The name does not resolve for the supplied parameters";
00220     }
00221 
00222     return "Unknown error";
00223 }
00224 #endif
00225 
00226 int ff_socket_nonblock(int socket, int enable)
00227 {
00228 #if HAVE_WINSOCK2_H
00229    return ioctlsocket(socket, FIONBIO, &enable);
00230 #else
00231    if (enable)
00232       return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) | O_NONBLOCK);
00233    else
00234       return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) & ~O_NONBLOCK);
00235 #endif
00236 }
00237 #endif /* CONFIG_NETWORK */
00238 
00239 #if CONFIG_FFSERVER
00240 #if !HAVE_POLL_H
00241 int poll(struct pollfd *fds, nfds_t numfds, int timeout)
00242 {
00243     fd_set read_set;
00244     fd_set write_set;
00245     fd_set exception_set;
00246     nfds_t i;
00247     int n;
00248     int rc;
00249 
00250 #if HAVE_WINSOCK2_H
00251     if (numfds >= FD_SETSIZE) {
00252         errno = EINVAL;
00253         return -1;
00254     }
00255 #endif
00256 
00257     FD_ZERO(&read_set);
00258     FD_ZERO(&write_set);
00259     FD_ZERO(&exception_set);
00260 
00261     n = -1;
00262     for(i = 0; i < numfds; i++) {
00263         if (fds[i].fd < 0)
00264             continue;
00265 #if !HAVE_WINSOCK2_H
00266         if (fds[i].fd >= FD_SETSIZE) {
00267             errno = EINVAL;
00268             return -1;
00269         }
00270 #endif
00271 
00272         if (fds[i].events & POLLIN)  FD_SET(fds[i].fd, &read_set);
00273         if (fds[i].events & POLLOUT) FD_SET(fds[i].fd, &write_set);
00274         if (fds[i].events & POLLERR) FD_SET(fds[i].fd, &exception_set);
00275 
00276         if (fds[i].fd > n)
00277             n = fds[i].fd;
00278     };
00279 
00280     if (n == -1)
00281         /* Hey!? Nothing to poll, in fact!!! */
00282         return 0;
00283 
00284     if (timeout < 0)
00285         rc = select(n+1, &read_set, &write_set, &exception_set, NULL);
00286     else {
00287         struct timeval    tv;
00288 
00289         tv.tv_sec = timeout / 1000;
00290         tv.tv_usec = 1000 * (timeout % 1000);
00291         rc = select(n+1, &read_set, &write_set, &exception_set, &tv);
00292     };
00293 
00294     if (rc < 0)
00295         return rc;
00296 
00297     for(i = 0; i < (nfds_t) n; i++) {
00298         fds[i].revents = 0;
00299 
00300         if (FD_ISSET(fds[i].fd, &read_set))      fds[i].revents |= POLLIN;
00301         if (FD_ISSET(fds[i].fd, &write_set))     fds[i].revents |= POLLOUT;
00302         if (FD_ISSET(fds[i].fd, &exception_set)) fds[i].revents |= POLLERR;
00303     };
00304 
00305     return rc;
00306 }
00307 #endif /* HAVE_POLL_H */
00308 #endif /* CONFIG_FFSERVER */
00309 

Generated on Fri Sep 16 2011 17:17:50 for FFmpeg by  doxygen 1.7.1