file.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:7k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * file.c
  3.  *****************************************************************************
  4.  * Copyright (C) 2001, 2002 the VideoLAN team
  5.  * $Id: 7639a0be8119b6193dcea0e5cfe7c6e821e499b8 $
  6.  *
  7.  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  8.  *          Eric Petit <titer@videolan.org>
  9.  *
  10.  * This program is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU General Public License as published by
  12.  * the Free Software Foundation; either version 2 of the License, or
  13.  * (at your option) any later version.
  14.  *
  15.  * This program is distributed in the hope that it will be useful,
  16.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  * GNU General Public License for more details.
  19.  *
  20.  * You should have received a copy of the GNU General Public License
  21.  * along with this program; if not, write to the Free Software
  22.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  23.  *****************************************************************************/
  24. /*****************************************************************************
  25.  * Preamble
  26.  *****************************************************************************/
  27. #ifdef HAVE_CONFIG_H
  28. # include "config.h"
  29. #endif
  30. #include <sys/types.h>
  31. #include <sys/stat.h>
  32. #include <time.h>
  33. #include <fcntl.h>
  34. #include <errno.h>
  35. #include <vlc_common.h>
  36. #include <vlc_plugin.h>
  37. #include <vlc_sout.h>
  38. #include <vlc_block.h>
  39. #include <vlc_charset.h>
  40. #include "vlc_strings.h"
  41. #if defined( WIN32 ) && !defined( UNDER_CE )
  42. #   include <io.h>
  43. #   define lseek _lseeki64
  44. #else
  45. #   include <unistd.h>
  46. #endif
  47. #ifndef O_LARGEFILE
  48. #   define O_LARGEFILE 0
  49. #endif
  50. /*****************************************************************************
  51.  * Module descriptor
  52.  *****************************************************************************/
  53. static int  Open ( vlc_object_t * );
  54. static void Close( vlc_object_t * );
  55. #define SOUT_CFG_PREFIX "sout-file-"
  56. #define APPEND_TEXT N_("Append to file")
  57. #define APPEND_LONGTEXT N_( "Append to file if it exists instead " 
  58.                             "of replacing it.")
  59. vlc_module_begin ()
  60.     set_description( N_("File stream output") )
  61.     set_shortname( N_("File" ))
  62.     set_capability( "sout access", 50 )
  63.     set_category( CAT_SOUT )
  64.     set_subcategory( SUBCAT_SOUT_ACO )
  65.     add_shortcut( "file" )
  66.     add_shortcut( "stream" )
  67.     add_bool( SOUT_CFG_PREFIX "append", 0, NULL, APPEND_TEXT,APPEND_LONGTEXT,
  68.               true )
  69.     set_callbacks( Open, Close )
  70. vlc_module_end ()
  71. /*****************************************************************************
  72.  * Exported prototypes
  73.  *****************************************************************************/
  74. static const char *const ppsz_sout_options[] = {
  75.     "append", NULL
  76. };
  77. static ssize_t Write( sout_access_out_t *, block_t * );
  78. static int Seek ( sout_access_out_t *, off_t  );
  79. static ssize_t Read ( sout_access_out_t *, block_t * );
  80. static int Control( sout_access_out_t *, int, va_list );
  81. struct sout_access_out_sys_t
  82. {
  83.     int i_handle;
  84. };
  85. /*****************************************************************************
  86.  * Open: open the file
  87.  *****************************************************************************/
  88. static int Open( vlc_object_t *p_this )
  89. {
  90.     sout_access_out_t   *p_access = (sout_access_out_t*)p_this;
  91.     int                 fd;
  92.     config_ChainParse( p_access, SOUT_CFG_PREFIX, ppsz_sout_options, p_access->p_cfg );
  93.     if( !p_access->psz_path )
  94.     {
  95.         msg_Err( p_access, "no file name specified" );
  96.         return VLC_EGENERIC;
  97.     }
  98.     bool append = var_GetBool( p_access, SOUT_CFG_PREFIX "append" );
  99.     if( !strcmp( p_access->psz_path, "-" ) )
  100.     {
  101. #ifndef UNDER_CE
  102. #ifdef WIN32
  103.         setmode (fileno (stdout), O_BINARY);
  104. #endif
  105.         fd = dup (fileno (stdout));
  106.         msg_Dbg( p_access, "using stdout" );
  107. #else
  108. #warning stdout is not supported on Windows Mobile, but may be used on Windows CE
  109.         fd = -1;
  110. #endif
  111.     }
  112.     else
  113.     {
  114.         char *psz_tmp = str_format( p_access, p_access->psz_path );
  115.         path_sanitize( psz_tmp );
  116.         fd = utf8_open( psz_tmp, O_RDWR | O_CREAT | O_LARGEFILE |
  117.                         (append ? 0 : O_TRUNC), 0666 );
  118.         free( psz_tmp );
  119.     }
  120.     if (fd == -1)
  121.     {
  122.         msg_Err( p_access, "cannot open `%s' (%m)", p_access->psz_path );
  123.         return VLC_EGENERIC;
  124.     }
  125.     p_access->pf_write = Write;
  126.     p_access->pf_read  = Read;
  127.     p_access->pf_seek  = Seek;
  128.     p_access->pf_control = Control;
  129.     p_access->p_sys    = (void *)(intptr_t)fd;
  130.     msg_Dbg( p_access, "file access output opened (%s)", p_access->psz_path );
  131.     if (append)
  132.         lseek (fd, 0, SEEK_END);
  133.     return VLC_SUCCESS;
  134. }
  135. /*****************************************************************************
  136.  * Close: close the target
  137.  *****************************************************************************/
  138. static void Close( vlc_object_t * p_this )
  139. {
  140.     sout_access_out_t *p_access = (sout_access_out_t*)p_this;
  141.     close( (intptr_t)p_access->p_sys );
  142.     msg_Dbg( p_access, "file access output closed" );
  143. }
  144. static int Control( sout_access_out_t *p_access, int i_query, va_list args )
  145. {
  146.     switch( i_query )
  147.     {
  148.         case ACCESS_OUT_CONTROLS_PACE:
  149.         {
  150.             bool *pb = va_arg( args, bool * );
  151.             *pb = strcmp( p_access->psz_access, "stream" );
  152.             break;
  153.         }
  154.         default:
  155.             return VLC_EGENERIC;
  156.     }
  157.     return VLC_SUCCESS;
  158. }
  159. /*****************************************************************************
  160.  * Read: standard read on a file descriptor.
  161.  *****************************************************************************/
  162. static ssize_t Read( sout_access_out_t *p_access, block_t *p_buffer )
  163. {
  164.     ssize_t val;
  165.     do
  166.         val = read( (intptr_t)p_access->p_sys, p_buffer->p_buffer,
  167.                     p_buffer->i_buffer );
  168.     while (val == -1 && errno == EINTR);
  169.     return val;
  170. }
  171. /*****************************************************************************
  172.  * Write: standard write on a file descriptor.
  173.  *****************************************************************************/
  174. static ssize_t Write( sout_access_out_t *p_access, block_t *p_buffer )
  175. {
  176.     size_t i_write = 0;
  177.     while( p_buffer )
  178.     {
  179.         ssize_t val = write ((intptr_t)p_access->p_sys,
  180.                              p_buffer->p_buffer, p_buffer->i_buffer);
  181.         if (val == -1)
  182.         {
  183.             if (errno == EINTR)
  184.                 continue;
  185.             block_ChainRelease (p_buffer);
  186.             return -1;
  187.         }
  188.         if ((size_t)val >= p_buffer->i_buffer)
  189.         {
  190.             block_t *p_next = p_buffer->p_next;
  191.             block_Release (p_buffer);
  192.             p_buffer = p_next;
  193.         }
  194.         else
  195.         {
  196.             p_buffer->p_buffer += val;
  197.             p_buffer->i_buffer -= val;
  198.         }
  199.         i_write += val;
  200.     }
  201.     return i_write;
  202. }
  203. /*****************************************************************************
  204.  * Seek: seek to a specific location in a file
  205.  *****************************************************************************/
  206. static int Seek( sout_access_out_t *p_access, off_t i_pos )
  207. {
  208.     return lseek( (intptr_t)p_access->p_sys, i_pos, SEEK_SET );
  209. }