LCOV - code coverage report
Current view: top level - libavformat - os_support.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 6 0.0 %
Date: 2017-12-14 01:15:32 Functions: 0 2 0.0 %

          Line data    Source code
       1             : /*
       2             :  * various OS-feature replacement utilities
       3             :  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
       4             :  * copyright (c) 2002 Francois Revol
       5             :  *
       6             :  * This file is part of FFmpeg.
       7             :  *
       8             :  * FFmpeg is free software; you can redistribute it and/or
       9             :  * modify it under the terms of the GNU Lesser General Public
      10             :  * License as published by the Free Software Foundation; either
      11             :  * version 2.1 of the License, or (at your option) any later version.
      12             :  *
      13             :  * FFmpeg is distributed in the hope that it will be useful,
      14             :  * 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             :  * License along with FFmpeg; if not, write to the Free Software
      20             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      21             :  */
      22             : 
      23             : /* needed by inet_aton() */
      24             : #define _DEFAULT_SOURCE
      25             : #define _SVID_SOURCE
      26             : 
      27             : #include "config.h"
      28             : #include "avformat.h"
      29             : #include "os_support.h"
      30             : 
      31             : #if CONFIG_NETWORK
      32             : #include <fcntl.h>
      33             : #if !HAVE_POLL_H
      34             : #if HAVE_SYS_TIME_H
      35             : #include <sys/time.h>
      36             : #endif /* HAVE_SYS_TIME_H */
      37             : #if HAVE_WINSOCK2_H
      38             : #include <winsock2.h>
      39             : #elif HAVE_SYS_SELECT_H
      40             : #include <sys/select.h>
      41             : #endif /* HAVE_WINSOCK2_H */
      42             : #endif /* !HAVE_POLL_H */
      43             : 
      44             : #include "network.h"
      45             : 
      46             : #if !HAVE_INET_ATON
      47             : #include <stdlib.h>
      48             : 
      49             : int ff_inet_aton(const char *str, struct in_addr *add)
      50             : {
      51             :     unsigned int add1 = 0, add2 = 0, add3 = 0, add4 = 0;
      52             : 
      53             :     if (sscanf(str, "%d.%d.%d.%d", &add1, &add2, &add3, &add4) != 4)
      54             :         return 0;
      55             : 
      56             :     if (!add1 || (add1 | add2 | add3 | add4) > 255)
      57             :         return 0;
      58             : 
      59             :     add->s_addr = htonl((add1 << 24) + (add2 << 16) + (add3 << 8) + add4);
      60             : 
      61             :     return 1;
      62             : }
      63             : #else
      64           0 : int ff_inet_aton(const char *str, struct in_addr *add)
      65             : {
      66           0 :     return inet_aton(str, add);
      67             : }
      68             : #endif /* !HAVE_INET_ATON */
      69             : 
      70             : #if !HAVE_GETADDRINFO
      71             : int ff_getaddrinfo(const char *node, const char *service,
      72             :                    const struct addrinfo *hints, struct addrinfo **res)
      73             : {
      74             :     struct hostent *h = NULL;
      75             :     struct addrinfo *ai;
      76             :     struct sockaddr_in *sin;
      77             : 
      78             :     *res = NULL;
      79             :     sin  = av_mallocz(sizeof(struct sockaddr_in));
      80             :     if (!sin)
      81             :         return EAI_FAIL;
      82             :     sin->sin_family = AF_INET;
      83             : 
      84             :     if (node) {
      85             :         if (!ff_inet_aton(node, &sin->sin_addr)) {
      86             :             if (hints && (hints->ai_flags & AI_NUMERICHOST)) {
      87             :                 av_free(sin);
      88             :                 return EAI_FAIL;
      89             :             }
      90             :             h = gethostbyname(node);
      91             :             if (!h) {
      92             :                 av_free(sin);
      93             :                 return EAI_FAIL;
      94             :             }
      95             :             memcpy(&sin->sin_addr, h->h_addr_list[0], sizeof(struct in_addr));
      96             :         }
      97             :     } else {
      98             :         if (hints && (hints->ai_flags & AI_PASSIVE))
      99             :             sin->sin_addr.s_addr = INADDR_ANY;
     100             :         else
     101             :             sin->sin_addr.s_addr = INADDR_LOOPBACK;
     102             :     }
     103             : 
     104             :     /* Note: getaddrinfo allows service to be a string, which
     105             :      * should be looked up using getservbyname. */
     106             :     if (service)
     107             :         sin->sin_port = htons(atoi(service));
     108             : 
     109             :     ai = av_mallocz(sizeof(struct addrinfo));
     110             :     if (!ai) {
     111             :         av_free(sin);
     112             :         return EAI_FAIL;
     113             :     }
     114             : 
     115             :     *res            = ai;
     116             :     ai->ai_family   = AF_INET;
     117             :     ai->ai_socktype = hints ? hints->ai_socktype : 0;
     118             :     switch (ai->ai_socktype) {
     119             :     case SOCK_STREAM:
     120             :         ai->ai_protocol = IPPROTO_TCP;
     121             :         break;
     122             :     case SOCK_DGRAM:
     123             :         ai->ai_protocol = IPPROTO_UDP;
     124             :         break;
     125             :     default:
     126             :         ai->ai_protocol = 0;
     127             :         break;
     128             :     }
     129             : 
     130             :     ai->ai_addr    = (struct sockaddr *)sin;
     131             :     ai->ai_addrlen = sizeof(struct sockaddr_in);
     132             :     if (hints && (hints->ai_flags & AI_CANONNAME))
     133             :         ai->ai_canonname = h ? av_strdup(h->h_name) : NULL;
     134             : 
     135             :     ai->ai_next = NULL;
     136             :     return 0;
     137             : }
     138             : 
     139             : void ff_freeaddrinfo(struct addrinfo *res)
     140             : {
     141             :     av_freep(&res->ai_canonname);
     142             :     av_freep(&res->ai_addr);
     143             :     av_freep(&res);
     144             : }
     145             : 
     146             : int ff_getnameinfo(const struct sockaddr *sa, int salen,
     147             :                    char *host, int hostlen,
     148             :                    char *serv, int servlen, int flags)
     149             : {
     150             :     const struct sockaddr_in *sin = (const struct sockaddr_in *)sa;
     151             : 
     152             :     if (sa->sa_family != AF_INET)
     153             :         return EAI_FAMILY;
     154             :     if (!host && !serv)
     155             :         return EAI_NONAME;
     156             : 
     157             :     if (host && hostlen > 0) {
     158             :         struct hostent *ent = NULL;
     159             :         uint32_t a;
     160             :         if (!(flags & NI_NUMERICHOST))
     161             :             ent = gethostbyaddr((const char *)&sin->sin_addr,
     162             :                                 sizeof(sin->sin_addr), AF_INET);
     163             : 
     164             :         if (ent) {
     165             :             snprintf(host, hostlen, "%s", ent->h_name);
     166             :         } else if (flags & NI_NAMERQD) {
     167             :             return EAI_NONAME;
     168             :         } else {
     169             :             a = ntohl(sin->sin_addr.s_addr);
     170             :             snprintf(host, hostlen, "%d.%d.%d.%d",
     171             :                      ((a >> 24) & 0xff), ((a >> 16) & 0xff),
     172             :                      ((a >>  8) & 0xff),  (a        & 0xff));
     173             :         }
     174             :     }
     175             : 
     176             :     if (serv && servlen > 0) {
     177             :         if (!(flags & NI_NUMERICSERV))
     178             :             return EAI_FAIL;
     179             :         snprintf(serv, servlen, "%d", ntohs(sin->sin_port));
     180             :     }
     181             : 
     182             :     return 0;
     183             : }
     184             : #endif /* !HAVE_GETADDRINFO */
     185             : 
     186             : #if !HAVE_GETADDRINFO || HAVE_WINSOCK2_H
     187             : const char *ff_gai_strerror(int ecode)
     188             : {
     189             :     switch (ecode) {
     190             :     case EAI_AGAIN:
     191             :         return "Temporary failure in name resolution";
     192             :     case EAI_BADFLAGS:
     193             :         return "Invalid flags for ai_flags";
     194             :     case EAI_FAIL:
     195             :         return "A non-recoverable error occurred";
     196             :     case EAI_FAMILY:
     197             :         return "The address family was not recognized or the address "
     198             :                "length was invalid for the specified family";
     199             :     case EAI_MEMORY:
     200             :         return "Memory allocation failure";
     201             : #if EAI_NODATA != EAI_NONAME
     202             :     case EAI_NODATA:
     203             :         return "No address associated with hostname";
     204             : #endif /* EAI_NODATA != EAI_NONAME */
     205             :     case EAI_NONAME:
     206             :         return "The name does not resolve for the supplied parameters";
     207             :     case EAI_SERVICE:
     208             :         return "servname not supported for ai_socktype";
     209             :     case EAI_SOCKTYPE:
     210             :         return "ai_socktype not supported";
     211             :     }
     212             : 
     213             :     return "Unknown error";
     214             : }
     215             : #endif /* !HAVE_GETADDRINFO || HAVE_WINSOCK2_H */
     216             : 
     217           0 : int ff_socket_nonblock(int socket, int enable)
     218             : {
     219             : #if HAVE_WINSOCK2_H
     220             :     u_long param = enable;
     221             :     return ioctlsocket(socket, FIONBIO, &param);
     222             : #else
     223           0 :     if (enable)
     224           0 :         return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) | O_NONBLOCK);
     225             :     else
     226           0 :         return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) & ~O_NONBLOCK);
     227             : #endif /* HAVE_WINSOCK2_H */
     228             : }
     229             : 
     230             : #if !HAVE_POLL_H
     231             : int ff_poll(struct pollfd *fds, nfds_t numfds, int timeout)
     232             : {
     233             :     fd_set read_set;
     234             :     fd_set write_set;
     235             :     fd_set exception_set;
     236             :     nfds_t i;
     237             :     int n;
     238             :     int rc;
     239             : 
     240             : #if HAVE_WINSOCK2_H
     241             :     if (numfds >= FD_SETSIZE) {
     242             :         errno = EINVAL;
     243             :         return -1;
     244             :     }
     245             : #endif /* HAVE_WINSOCK2_H */
     246             : 
     247             :     FD_ZERO(&read_set);
     248             :     FD_ZERO(&write_set);
     249             :     FD_ZERO(&exception_set);
     250             : 
     251             :     n = 0;
     252             :     for (i = 0; i < numfds; i++) {
     253             :         if (fds[i].fd < 0)
     254             :             continue;
     255             : #if !HAVE_WINSOCK2_H
     256             :         if (fds[i].fd >= FD_SETSIZE) {
     257             :             errno = EINVAL;
     258             :             return -1;
     259             :         }
     260             : #endif /* !HAVE_WINSOCK2_H */
     261             : 
     262             :         if (fds[i].events & POLLIN)
     263             :             FD_SET(fds[i].fd, &read_set);
     264             :         if (fds[i].events & POLLOUT)
     265             :             FD_SET(fds[i].fd, &write_set);
     266             :         if (fds[i].events & POLLERR)
     267             :             FD_SET(fds[i].fd, &exception_set);
     268             : 
     269             :         if (fds[i].fd >= n)
     270             :             n = fds[i].fd + 1;
     271             :     }
     272             : 
     273             :     if (n == 0)
     274             :         /* Hey!? Nothing to poll, in fact!!! */
     275             :         return 0;
     276             : 
     277             :     if (timeout < 0) {
     278             :         rc = select(n, &read_set, &write_set, &exception_set, NULL);
     279             :     } else {
     280             :         struct timeval tv;
     281             :         tv.tv_sec  = timeout / 1000;
     282             :         tv.tv_usec = 1000 * (timeout % 1000);
     283             :         rc         = select(n, &read_set, &write_set, &exception_set, &tv);
     284             :     }
     285             : 
     286             :     if (rc < 0)
     287             :         return rc;
     288             : 
     289             :     for (i = 0; i < numfds; i++) {
     290             :         fds[i].revents = 0;
     291             : 
     292             :         if (FD_ISSET(fds[i].fd, &read_set))
     293             :             fds[i].revents |= POLLIN;
     294             :         if (FD_ISSET(fds[i].fd, &write_set))
     295             :             fds[i].revents |= POLLOUT;
     296             :         if (FD_ISSET(fds[i].fd, &exception_set))
     297             :             fds[i].revents |= POLLERR;
     298             :     }
     299             : 
     300             :     return rc;
     301             : }
     302             : #endif /* !HAVE_POLL_H */
     303             : 
     304             : #endif /* CONFIG_NETWORK */

Generated by: LCOV version 1.13