X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Faccess%2Ffile.c;h=bcdf0a732f51e4e905acfa11fc4ba4f695445eee;hb=552e595131c5f1d66eba8e3c22c2b1c509be5153;hp=e8dca7ad2430af81fd8c221f061579b7ae3993a0;hpb=bb24808cf580d17948910676038f36293ac1be61;p=vlc diff --git a/modules/access/file.c b/modules/access/file.c index e8dca7ad24..bcdf0a732f 100644 --- a/modules/access/file.c +++ b/modules/access/file.c @@ -27,11 +27,10 @@ * Preamble *****************************************************************************/ #include -#include -#include +#include +#include +#include -#include -#include #include #ifdef HAVE_SYS_TYPES_H # include @@ -51,8 +50,6 @@ #endif #if defined( WIN32 ) && !defined( UNDER_CE ) -/* fstat() support for large files on win32 */ -# define fstat(a,b) _fstati64(a,b) # ifdef lseek # undef lseek # endif @@ -69,7 +66,7 @@ # define lseek fseek #endif -#include "charset.h" +#include /***************************************************************************** * Module descriptor @@ -92,7 +89,7 @@ vlc_module_begin(); set_category( CAT_INPUT ); set_subcategory( SUBCAT_INPUT_ACCESS ); add_integer( "file-caching", DEFAULT_PTS_DELAY / 1000, NULL, CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE ); - add_string( "file-cat", NULL, NULL, CAT_TEXT, CAT_LONGTEXT, VLC_TRUE ); + add_obsolete_string( "file-cat" ); set_capability( "access2", 50 ); add_shortcut( "file" ); add_shortcut( "stream" ); @@ -108,20 +105,14 @@ static int Seek( access_t *, int64_t ); static int Read( access_t *, uint8_t *, int ); static int Control( access_t *, int, va_list ); -static int OpenFile( access_t *, const char * ); +static int open_file( access_t *, const char * ); struct access_sys_t { unsigned int i_nb_reads; vlc_bool_t b_kfir; - /* Files list */ - unsigned filec; - int *filev; - int64_t *sizev; - - /* Current file */ - unsigned filep; + int fd; /* */ vlc_bool_t b_seekable; @@ -135,7 +126,6 @@ static int Open( vlc_object_t *p_this ) { access_t *p_access = (access_t*)p_this; access_sys_t *p_sys; - char *catlist; vlc_bool_t b_stdin = !strcmp (p_access->psz_path, "-"); @@ -145,8 +135,7 @@ static int Open( vlc_object_t *p_this ) STANDARD_READ_ACCESS_INIT; p_sys->i_nb_reads = 0; p_sys->b_kfir = VLC_FALSE; - p_sys->filec = 1; - p_sys->filep = 0; + int fd = p_sys->fd = -1; if (!strcasecmp (p_access->psz_access, "stream")) { @@ -165,109 +154,54 @@ static int Open( vlc_object_t *p_this ) p_sys->b_pace_control = VLC_TRUE; } - /* Count number of files */ - catlist = var_CreateGetString (p_access, "file-cat"); - if (catlist == NULL) - { - free (p_sys); - return VLC_ENOMEM; - } - - if (*catlist) - { - for (const char *ptr = catlist; ptr != NULL; p_sys->filec++) - { - ptr = strchr (ptr, ','); - if (ptr != NULL) - ptr++; - } - } + /* Open file */ + msg_Dbg (p_access, "opening file `%s'", p_access->psz_path); - p_sys->filev = calloc (p_sys->filec, sizeof (p_sys->filev[0])); - if (p_sys->filev == NULL) - { - free (catlist); - free (p_sys); - return VLC_ENOMEM; - } + if (b_stdin) + fd = dup (0); + else + fd = open_file (p_access, p_access->psz_path); - p_sys->sizev = calloc (p_sys->filec, sizeof (p_sys->sizev[0])); - if (p_sys->sizev == NULL) - { - free (catlist); - free (p_sys->filev); - free (p_sys); - return VLC_ENOMEM; - } +#ifdef HAVE_SYS_STAT_H + struct stat st; - /* Open files */ - char *filename = catlist; - for (unsigned i = 0; i < p_sys->filec; i++) + while (fd != -1) { - int fd = -1; - - if (i == 0) - { - msg_Dbg (p_access, "opening file `%s'", p_access->psz_path); - - if (b_stdin) - fd = dup (0); - else - fd = OpenFile (p_access, p_access->psz_path); - } + if (fstat (fd, &st)) + msg_Err (p_access, "fstat(%d): %m", fd); else - { - assert (filename != NULL); - - char *ptr = strchr (filename, ','); - if (ptr != NULL) - *ptr = 0; - - msg_Dbg (p_access, "opening additionnal file `%s'", filename); - fd = OpenFile (p_access, filename); - filename = ptr + 1; - } - -#ifdef HAVE_SYS_STAT_H - struct stat st; + if (S_ISDIR (st.st_mode)) + /* The directory plugin takes care of that */ + msg_Dbg (p_access, "file is a directory, aborting"); + else + break; // success - if ((fd != -1) && fstat (fd, &st)) - { - msg_Err (p_access, "fstat(%d): %s", fd, strerror (errno)); - close (fd); - fd = -1; - } + close (fd); + fd = -1; + } #endif - if (fd == -1) - { - free (catlist); - p_sys->filec = i; - Close (p_this); - return VLC_EGENERIC; - } - p_sys->filev[i] = fd; + if (fd == -1) + { + free (p_sys); + return VLC_EGENERIC; + } + p_sys->fd = fd; #ifdef HAVE_SYS_STAT_H - p_sys->sizev[i] = st.st_size; - p_access->info.i_size += st.st_size; - - if (!S_ISREG (st.st_mode) && !S_ISBLK (st.st_mode) - && (!S_ISCHR (st.st_mode) || (st.st_size == 0))) - // If one file is not seekable, the concatenation is not either - p_sys->b_seekable = VLC_FALSE; + p_access->info.i_size = st.st_size; + if (!S_ISREG (st.st_mode) && !S_ISBLK (st.st_mode) + && (!S_ISCHR (st.st_mode) || (st.st_size == 0))) + p_sys->b_seekable = VLC_FALSE; #else - p_sys->b_seekable = !b_stdin; + p_sys->b_seekable = !b_stdin; +# warning File size not known! #endif - } - - free (catlist); - - if (p_sys->b_seekable && !p_access->info.i_size) + if (p_sys->b_seekable && (p_access->info.i_size == 0)) { /* FIXME that's bad because all others access will be probed */ - msg_Err (p_access, "file %s is empty, aborting", p_access->psz_path); + msg_Err (p_access, "file is empty, aborting"); Close (p_this); return VLC_EGENERIC; } @@ -283,11 +217,7 @@ static void Close (vlc_object_t * p_this) access_t *p_access = (access_t*)p_this; access_sys_t *p_sys = p_access->p_sys; - for (unsigned i = 0; i < p_sys->filec; i++) - close (p_sys->filev[i]); - - free (p_sys->filev); - free (p_sys->sizev); + close (p_sys->fd); free (p_sys); } @@ -298,7 +228,7 @@ static int Read( access_t *p_access, uint8_t *p_buffer, int i_len ) { access_sys_t *p_sys = p_access->p_sys; int i_ret; - int fd = p_sys->filev[p_sys->filep]; + int fd = p_sys->fd; #if !defined(WIN32) && !defined(UNDER_CE) if( !p_sys->b_pace_control ) @@ -347,7 +277,8 @@ static int Read( access_t *p_access, uint8_t *p_buffer, int i_len ) break; default: - msg_Err (p_access, "read failed (%s)", strerror (errno)); + msg_Err (p_access, "read failed (%m)"); + /* FIXME: DO NOT USE strerror!!!! */ intf_UserFatal (p_access, VLC_FALSE, _("File reading failed"), _("VLC could not read file \"%s\"."), strerror (errno)); @@ -365,28 +296,16 @@ static int Read( access_t *p_access, uint8_t *p_buffer, int i_len ) (p_sys->i_nb_reads % INPUT_FSTAT_NB_READS) == 0 ) { struct stat st; - int i = p_sys->filep; if ((fstat (fd, &st) == 0) - && (p_sys->sizev[i] != st.st_size)) + && (p_access->info.i_size != st.st_size)) { - p_access->info.i_size += st.st_size - p_sys->sizev[i]; - p_sys->sizev[i] = st.st_size; + p_access->info.i_size = st.st_size; p_access->info.i_update |= INPUT_UPDATE_SIZE; } } #endif - /* If we reached an EOF then switch to the next file in the list */ - if (i_ret == 0) - { - if (++p_sys->filep < p_sys->filec) - /* We have to read some data */ - return Read (p_access, p_buffer, i_len); - else - p_sys->filep--; - } - if( i_ret > 0 ) p_access->info.i_pos += i_ret; else if( i_ret == 0 ) @@ -400,34 +319,22 @@ static int Read( access_t *p_access, uint8_t *p_buffer, int i_len ) *****************************************************************************/ static int Seek (access_t *p_access, int64_t i_pos) { - access_sys_t *p_sys = p_access->p_sys; - - if (p_access->info.i_size < p_access->info.i_pos) + if (i_pos > p_access->info.i_size) { msg_Err (p_access, "seeking too far"); - i_pos = p_access->info.i_pos = p_access->info.i_size; + i_pos = p_access->info.i_size; } - else if (p_access->info.i_pos < 0) + else if (i_pos < 0) { msg_Err (p_access, "seeking too early"); - i_pos = p_access->info.i_pos = 0; + i_pos = 0; } p_access->info.i_pos = i_pos; p_access->info.b_eof = VLC_FALSE; /* Determine which file we need to access */ - unsigned i = 0; - assert (p_sys->filec > 0); - - while (i_pos > p_sys->sizev[i]) - { - i_pos -= p_sys->sizev[i++]; - assert (i < p_sys->filec); - } - p_sys->filep = i; - - lseek (p_sys->filev[i], i_pos, SEEK_SET); + lseek (p_access->p_sys->fd, i_pos, SEEK_SET); return VLC_SUCCESS; } @@ -513,9 +420,9 @@ static char *expand_path (const access_t *p_access, const char *path) /***************************************************************************** - * OpenFile: Opens a specific file + * open_file: Opens a specific file *****************************************************************************/ -static int OpenFile (access_t *p_access, const char *psz_name) +static int open_file (access_t *p_access, const char *psz_name) { char *path = expand_path (p_access, psz_name); @@ -524,7 +431,7 @@ static int OpenFile (access_t *p_access, const char *psz_name) if ( !p_sys->fd ) { msg_Err( p_access, "cannot open file %s", psz_name ); - intf_UserFatal( p_access, VLC_FALSE, _("File reading failed"), + intf_UserFatal( p_access, VLC_FALSE, _("File reading failed"), _("VLC could not open file \"%s\"."), psz_name ); free (path); return VLC_EGENERIC; @@ -535,24 +442,12 @@ static int OpenFile (access_t *p_access, const char *psz_name) p_access->info.i_update |= INPUT_UPDATE_SIZE; fseek( p_sys->fd, 0, SEEK_SET ); #else - const char *psz_localname = ToLocale (path); - if (psz_localname == NULL) - { - msg_Err (p_access, "incorrect file name %s", psz_name); - free (path); - return -1; - } - - // FIXME: support non-ANSI filenames on Win32 - int fd = open (path, O_NONBLOCK /*| O_LARGEFILE*/); - LocaleFree (psz_localname); + int fd = utf8_open (path, O_RDONLY | O_NONBLOCK /* O_LARGEFILE*/, 0666); free (path); - if (fd == -1) { - msg_Err (p_access, "cannot open file %s (%s)", psz_name, - strerror (errno)); - intf_UserFatal (p_access, VLC_FALSE, _("File reading failed"), + msg_Err (p_access, "cannot open file %s (%m)", psz_name); + intf_UserFatal (p_access, VLC_FALSE, _("File reading failed"), _("VLC could not open file \"%s\" (%s)."), psz_name, strerror (errno)); return -1;