LCOV - code coverage report
Current view: top level - libavformat - os_support.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 4 0.0 %
Date: 2018-05-20 11:54:08 Functions: 0 1 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_GETADDRINFO
      47             : #if !HAVE_INET_ATON
      48             : #include <stdlib.h>
      49             : 
      50             : static int inet_aton(const char *str, struct in_addr *add)
      51             : {
      52             :     unsigned int add1 = 0, add2 = 0, add3 = 0, add4 = 0;
      53             : 
      54             :     if (sscanf(str, "%d.%d.%d.%d", &add1, &add2, &add3, &add4) != 4)
      55             :         return 0;
      56             : 
      57             :     if (!add1 || (add1 | add2 | add3 | add4) > 255)
      58             :         return 0;
      59             : 
      60             :     add->s_addr = htonl((add1 << 24) + (add2 << 16) + (add3 << 8) + add4);
      61             : 
      62             :     return 1;
      63             : }
      64             : #endif /* !HAVE_INET_ATON */
      65             : 
      66             : int ff_getaddrinfo(const char *node, const char *service,
      67             :                    const struct addrinfo *hints, struct addrinfo **res)
      68             : {
      69             :     struct hostent *h = NULL;
      70             :     struct addrinfo *ai;
      71             :     struct sockaddr_in *sin;
      72             : 
      73             :     *res = NULL;
      74             :     sin  = av_mallocz(sizeof(struct sockaddr_in));
      75             :     if (!sin)
      76             :         return EAI_FAIL;
      77             :     sin->sin_family = AF_INET;
      78             : 
      79             :     if (node) {
      80             :         if (!inet_aton(node, &sin->sin_addr)) {
      81             :             if (hints && (hints->ai_flags & AI_NUMERICHOST)) {
      82             :                 av_free(sin);
      83             :                 return EAI_FAIL;
      84             :             }
      85             :             h = gethostbyname(node);
      86             :             if (!h) {
      87             :                 av_free(sin);
      88             :                 return EAI_FAIL;
      89             :             }
      90             :             memcpy(&sin->sin_addr, h->h_addr_list[0], sizeof(struct in_addr));
      91             :         }
      92             :     } else {
      93             :         if (hints && (hints->ai_flags & AI_PASSIVE))
      94             :             sin->sin_addr.s_addr = INADDR_ANY;
      95             :         else
      96             :             sin->sin_addr.s_addr = INADDR_LOOPBACK;
      97             :     }
      98             : 
      99             :     /* Note: getaddrinfo allows service to be a string, which
     100             :      * should be looked up using getservbyname. */
     101             :     if (service)
     102             :         sin->sin_port = htons(atoi(service));
     103             : 
     104             :     ai = av_mallocz(sizeof(struct addrinfo));
     105             :     if (!ai) {
     106             :         av_free(sin);
     107             :         return EAI_FAIL;
     108             :     }
     109             : 
     110             :     *res            = ai;
     111             :     ai->ai_family   = AF_INET;
     112             :     ai->ai_socktype = hints ? hints->ai_socktype : 0;
     113             :     switch (ai->ai_socktype) {
     114             :     case SOCK_STREAM:
     115             :         ai->ai_protocol = IPPROTO_TCP;
     116             :         break;
     117             :     case SOCK_DGRAM:
     118             :         ai->ai_protocol = IPPROTO_UDP;
     119             :         break;
     120             :     default:
     121             :         ai->ai_protocol = 0;
     122             :         break;
     123             :     }
     124             : 
     125             :     ai->ai_addr    = (struct sockaddr *)sin;
     126             :     ai->ai_addrlen = sizeof(struct sockaddr_in);
     127             :     if (hints && (hints->ai_flags & AI_CANONNAME))
     128             :         ai->ai_canonname = h ? av_strdup(h->h_name) : NULL;
     129             : 
     130             :     ai->ai_next = NULL;
     131             :     return 0;
     132             : }
     133             : 
     134             : void ff_freeaddrinfo(struct addrinfo *res)
     135             : {
     136             :     av_freep(&res->ai_canonname);
     137             :     av_freep(&res->ai_addr);
     138             :     av_freep(&res);
     139             : }
     140             : 
     141             : int ff_getnameinfo(const struct sockaddr *sa, int salen,
     142             :                    char *host, int hostlen,
     143             :                    char *serv, int servlen, int flags)
     144             : {
     145             :     const struct sockaddr_in *sin = (const struct sockaddr_in *)sa;
     146             : 
     147             :     if (sa->sa_family != AF_INET)
     148             :         return EAI_FAMILY;
     149             :     if (!host && !serv)
     150             :         return EAI_NONAME;
     151             : 
     152             :     if (host && hostlen > 0) {
     153             :         struct hostent *ent = NULL;
     154             :         uint32_t a;
     155             :         if (!(flags & NI_NUMERICHOST))
     156             :             ent = gethostbyaddr((const char *)&sin->sin_addr,
     157             :                                 sizeof(sin->sin_addr), AF_INET);
     158             : 
     159             :         if (ent) {
     160             :             snprintf(host, hostlen, "%s", ent->h_name);
     161             :         } else if (flags & NI_NAMERQD) {
     162             :             return EAI_NONAME;
     163             :         } else {
     164             :             a = ntohl(sin->sin_addr.s_addr);
     165             :             snprintf(host, hostlen, "%d.%d.%d.%d",
     166             :                      ((a >> 24) & 0xff), ((a >> 16) & 0xff),
     167             :                      ((a >>  8) & 0xff),  (a        & 0xff));
     168             :         }
     169             :     }
     170             : 
     171             :     if (serv && servlen > 0) {
     172             :         if (!(flags & NI_NUMERICSERV))
     173             :             return EAI_FAIL;
     174             :         snprintf(serv, servlen, "%d", ntohs(sin->sin_port));
     175             :     }
     176             : 
     177             :     return 0;
     178             : }
     179             : #endif /* !HAVE_GETADDRINFO */
     180             : 
     181             : #if !HAVE_GETADDRINFO || HAVE_WINSOCK2_H
     182             : const char *ff_gai_strerror(int ecode)
     183             : {
     184             :     switch (ecode) {
     185             :     case EAI_AGAIN:
     186             :         return "Temporary failure in name resolution";
     187             :     case EAI_BADFLAGS:
     188             :         return "Invalid flags for ai_flags";
     189             :     case EAI_FAIL:
     190             :         return "A non-recoverable error occurred";
     191             :     case EAI_FAMILY:
     192             :         return "The address family was not recognized or the address "
     193             :                "length was invalid for the specified family";
     194             :     case EAI_MEMORY:
     195             :         return "Memory allocation failure";
     196             : #if EAI_NODATA != EAI_NONAME
     197             :     case EAI_NODATA:
     198             :         return "No address associated with hostname";
     199             : #endif /* EAI_NODATA != EAI_NONAME */
     200             :     case EAI_NONAME:
     201             :         return "The name does not resolve for the supplied parameters";
     202             :     case EAI_SERVICE:
     203             :         return "servname not supported for ai_socktype";
     204             :     case EAI_SOCKTYPE:
     205             :         return "ai_socktype not supported";
     206             :     }
     207             : 
     208             :     return "Unknown error";
     209             : }
     210             : #endif /* !HAVE_GETADDRINFO || HAVE_WINSOCK2_H */
     211             : 
     212           0 : int ff_socket_nonblock(int socket, int enable)
     213             : {
     214             : #if HAVE_WINSOCK2_H
     215             :     u_long param = enable;
     216             :     return ioctlsocket(socket, FIONBIO, &param);
     217             : #else
     218           0 :     if (enable)
     219           0 :         return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) | O_NONBLOCK);
     220             :     else
     221           0 :         return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) & ~O_NONBLOCK);
     222             : #endif /* HAVE_WINSOCK2_H */
     223             : }
     224             : 
     225             : #if !HAVE_POLL_H
     226             : int ff_poll(struct pollfd *fds, nfds_t numfds, int timeout)
     227             : {
     228             :     fd_set read_set;
     229             :     fd_set write_set;
     230             :     fd_set exception_set;
     231             :     nfds_t i;
     232             :     int n;
     233             :     int rc;
     234             : 
     235             : #if HAVE_WINSOCK2_H
     236             :     if (numfds >= FD_SETSIZE) {
     237             :         errno = EINVAL;
     238             :         return -1;
     239             :     }
     240             : #endif /* HAVE_WINSOCK2_H */
     241             : 
     242             :     FD_ZERO(&read_set);
     243             :     FD_ZERO(&write_set);
     244             :     FD_ZERO(&exception_set);
     245             : 
     246             :     n = 0;
     247             :     for (i = 0; i < numfds; i++) {
     248             :         if (fds[i].fd < 0)
     249             :             continue;
     250             : #if !HAVE_WINSOCK2_H
     251             :         if (fds[i].fd >= FD_SETSIZE) {
     252             :             errno = EINVAL;
     253             :             return -1;
     254             :         }
     255             : #endif /* !HAVE_WINSOCK2_H */
     256             : 
     257             :         if (fds[i].events & POLLIN)
     258             :             FD_SET(fds[i].fd, &read_set);
     259             :         if (fds[i].events & POLLOUT)
     260             :             FD_SET(fds[i].fd, &write_set);
     261             :         if (fds[i].events & POLLERR)
     262             :             FD_SET(fds[i].fd, &exception_set);
     263             : 
     264             :         if (fds[i].fd >= n)
     265             :             n = fds[i].fd + 1;
     266             :     }
     267             : 
     268             :     if (n == 0)
     269             :         /* Hey!? Nothing to poll, in fact!!! */
     270             :         return 0;
     271             : 
     272             :     if (timeout < 0) {
     273             :         rc = select(n, &read_set, &write_set, &exception_set, NULL);
     274             :     } else {
     275             :         struct timeval tv;
     276             :         tv.tv_sec  = timeout / 1000;
     277             :         tv.tv_usec = 1000 * (timeout % 1000);
     278             :         rc         = select(n, &read_set, &write_set, &exception_set, &tv);
     279             :     }
     280             : 
     281             :     if (rc < 0)
     282             :         return rc;
     283             : 
     284             :     for (i = 0; i < numfds; i++) {
     285             :         fds[i].revents = 0;
     286             : 
     287             :         if (FD_ISSET(fds[i].fd, &read_set))
     288             :             fds[i].revents |= POLLIN;
     289             :         if (FD_ISSET(fds[i].fd, &write_set))
     290             :             fds[i].revents |= POLLOUT;
     291             :         if (FD_ISSET(fds[i].fd, &exception_set))
     292             :             fds[i].revents |= POLLERR;
     293             :     }
     294             : 
     295             :     return rc;
     296             : }
     297             : #endif /* !HAVE_POLL_H */
     298             : 
     299             : #endif /* CONFIG_NETWORK */

Generated by: LCOV version 1.13