⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 io.c

📁 uclinux 下的vlc播放器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * io.c: network I/O functions ***************************************************************************** * Copyright (C) 2004-2005 the VideoLAN team * $Id: io.c 17659 2006-11-11 16:50:15Z md $ * * Authors: Laurent Aimar <fenrir@videolan.org> *          Rémi Denis-Courmont <rem # videolan.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#include <stdlib.h>#include <vlc/vlc.h>#include <errno.h>#ifdef HAVE_FCNTL_H#   include <fcntl.h>#endif#ifdef HAVE_SYS_TIME_H#    include <sys/time.h>#endif#ifdef HAVE_UNISTD_H#   include <unistd.h>#endif#include "network.h"#ifndef INADDR_ANY#   define INADDR_ANY  0x00000000#endif#ifndef INADDR_NONE#   define INADDR_NONE 0xFFFFFFFF#endifint net_Socket( vlc_object_t *p_this, int i_family, int i_socktype,                int i_protocol ){    int fd, i_val;    fd = socket( i_family, i_socktype, i_protocol );    if( fd == -1 )    {#if defined(WIN32) || defined(UNDER_CE)        if( WSAGetLastError ( ) != WSAEAFNOSUPPORT )            msg_Warn( p_this, "cannot create socket (%i)",                      WSAGetLastError() );#else        if( errno != EAFNOSUPPORT )            msg_Warn( p_this, "cannot create socket (%s)",                      strerror( errno ) );#endif        return -1;    }#if defined( WIN32 ) || defined( UNDER_CE )    {        unsigned long i_dummy = 1;        if( ioctlsocket( fd, FIONBIO, &i_dummy ) != 0 )            msg_Err( p_this, "cannot set socket to non-blocking mode" );    }#else    if( fd >= FD_SETSIZE )    {        /* We don't want to overflow select() fd_set */        msg_Err( p_this, "cannot create socket (too many already in use)" );        net_Close( fd );        return -1;    }    fcntl( fd, F_SETFD, FD_CLOEXEC );    i_val = fcntl( fd, F_GETFL, 0 );    fcntl( fd, F_SETFL, ((i_val != -1) ? i_val : 0) | O_NONBLOCK );#endif    i_val = 1;    setsockopt( fd, SOL_SOCKET, SO_REUSEADDR, (void *)&i_val,                sizeof( i_val ) );#ifdef IPV6_V6ONLY    /*     * Accepts only IPv6 connections on IPv6 sockets     * (and open an IPv4 socket later as well if needed).     * Only Linux and FreeBSD can map IPv4 connections on IPv6 sockets,     * so this allows for more uniform handling across platforms. Besides,     * it makes sure that IPv4 addresses will be printed as w.x.y.z rather     * than ::ffff:w.x.y.z     */    if( i_family == AF_INET6 )        setsockopt( fd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&i_val,                    sizeof( i_val ) );#endif#if defined( WIN32 ) || defined( UNDER_CE )# ifndef IPV6_PROTECTION_LEVEL#  define IPV6_PROTECTION_LEVEL 23# endif    if( i_family == AF_INET6 )    {        i_val = 10 /*PROTECTION_LEVEL_UNRESTRICTED*/;        setsockopt( fd, IPPROTO_IPV6, IPV6_PROTECTION_LEVEL,                   (const char*)&i_val, sizeof( i_val ) );    }#endif    return fd;}/***************************************************************************** * __net_Close: ***************************************************************************** * Close a network handle *****************************************************************************/void net_Close( int fd ){#ifdef UNDER_CE    CloseHandle( (HANDLE)fd );#elif defined( WIN32 )    closesocket( fd );#else    close( fd );#endif}/***************************************************************************** * __net_Read: ***************************************************************************** * Read from a network socket * If b_retry is true, then we repeat until we have read the right amount of * data *****************************************************************************/int __net_Read( vlc_object_t *p_this, int fd, v_socket_t *p_vs,                uint8_t *p_data, int i_data, vlc_bool_t b_retry ){    struct timeval  timeout;    fd_set          fds_r, fds_e;    int             i_recv;    int             i_total = 0;    int             i_ret;    vlc_bool_t      b_die = p_this->b_die;    while( i_data > 0 )    {        do        {            if( p_this->b_die != b_die )            {                return 0;            }            /* Initialize file descriptor set */            FD_ZERO( &fds_r );            FD_SET( fd, &fds_r );            FD_ZERO( &fds_e );            FD_SET( fd, &fds_e );            /* We'll wait 0.5 second if nothing happens */            timeout.tv_sec = 0;            timeout.tv_usec = 500000;        } while( (i_ret = select(fd + 1, &fds_r, NULL, &fds_e, &timeout)) == 0                 || ( i_ret < 0 && errno == EINTR ) );        if( i_ret < 0 )        {#if defined(WIN32) || defined(UNDER_CE)            msg_Err( p_this, "network select error (%d)", WSAGetLastError() );#else            msg_Err( p_this, "network select error (%s)", strerror(errno) );#endif            return i_total > 0 ? i_total : -1;        }        if( ( i_recv = (p_vs != NULL)              ? p_vs->pf_recv( p_vs->p_sys, p_data, i_data )              : recv( fd, p_data, i_data, 0 ) ) < 0 )        {#if defined(WIN32) || defined(UNDER_CE)            if( WSAGetLastError() == WSAEWOULDBLOCK )            {                /* only happens with p_vs (SSL) - not really an error */            }            else            /* For udp only */            /* On win32 recv() will fail if the datagram doesn't fit inside             * the passed buffer, even though the buffer will be filled with             * the first part of the datagram. */            if( WSAGetLastError() == WSAEMSGSIZE )            {                msg_Err( p_this, "recv() failed. "                         "Increase the mtu size (--mtu option)" );                i_total += i_data;            }            else if( WSAGetLastError() == WSAEINTR ) continue;            else msg_Err( p_this, "recv failed (%i)", WSAGetLastError() );#else            /* EAGAIN only happens with p_vs (TLS) and it's not an error */            if( errno != EAGAIN )                msg_Err( p_this, "recv failed (%s)", strerror(errno) );#endif            return i_total > 0 ? i_total : -1;        }        else if( i_recv == 0 )        {            /* Connection closed */            b_retry = VLC_FALSE;        }        p_data += i_recv;        i_data -= i_recv;        i_total+= i_recv;        if( !b_retry )        {            break;        }    }    return i_total;}/***************************************************************************** * __net_ReadNonBlock: ***************************************************************************** * Read from a network socket, non blocking mode (with timeout) *****************************************************************************/int __net_ReadNonBlock( vlc_object_t *p_this, int fd, v_socket_t *p_vs,                        uint8_t *p_data, int i_data, mtime_t i_wait){    struct timeval  timeout;    fd_set          fds_r, fds_e;    int             i_recv;    int             i_ret;    /* Initialize file descriptor set */    FD_ZERO( &fds_r );    FD_SET( fd, &fds_r );    FD_ZERO( &fds_e );    FD_SET( fd, &fds_e );    timeout.tv_sec = 0;    timeout.tv_usec = i_wait;    i_ret = select(fd + 1, &fds_r, NULL, &fds_e, &timeout);    if( i_ret < 0 && errno == EINTR )    {        return 0;    }    else if( i_ret < 0 )    {#if defined(WIN32) || defined(UNDER_CE)        msg_Err( p_this, "network select error (%d)", WSAGetLastError() );#else        msg_Err( p_this, "network select error (%s)", strerror(errno) );#endif        return -1;    }    else if( i_ret == 0)    {        return 0;    }    else    {#if !defined(UNDER_CE)        if( fd == 0/*STDIN_FILENO*/ ) i_recv = read( fd, p_data, i_data ); else#endif        if( ( i_recv = (p_vs != NULL)              ? p_vs->pf_recv( p_vs->p_sys, p_data, i_data )              : recv( fd, p_data, i_data, 0 ) ) < 0 )        {#if defined(WIN32) || defined(UNDER_CE)            /* For udp only */            /* On win32 recv() will fail if the datagram doesn't fit inside             * the passed buffer, even though the buffer will be filled with             * the first part of the datagram. */            if( WSAGetLastError() == WSAEMSGSIZE )            {                msg_Err( p_this, "recv() failed. "                         "Increase the mtu size (--mtu option)" );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -