Commit c0660ee3 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

file: restore file descriptor support (fixes #14897)

parent 024cbe94
...@@ -36,16 +36,8 @@ ...@@ -36,16 +36,8 @@
#include <vlc_access.h> #include <vlc_access.h>
#include <vlc_input_item.h> #include <vlc_input_item.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <vlc_fs.h> #include <vlc_fs.h>
#include <vlc_url.h> #include <vlc_url.h>
#include <vlc_strings.h>
#include <vlc_charset.h>
struct access_sys_t struct access_sys_t
{ {
...@@ -60,14 +52,6 @@ int DirInit (access_t *p_access, DIR *p_dir) ...@@ -60,14 +52,6 @@ int DirInit (access_t *p_access, DIR *p_dir)
{ {
char *psz_base_uri; char *psz_base_uri;
if (!p_access->psz_filepath)
return VLC_EGENERIC;
if (!p_dir)
p_dir = vlc_opendir (p_access->psz_filepath);
if (p_dir == NULL)
return VLC_EGENERIC;
if (!strcmp (p_access->psz_access, "fd")) if (!strcmp (p_access->psz_access, "fd"))
{ {
if (asprintf (&psz_base_uri, "fd://%s", p_access->psz_location) == -1) if (asprintf (&psz_base_uri, "fd://%s", p_access->psz_location) == -1)
...@@ -81,7 +65,6 @@ int DirInit (access_t *p_access, DIR *p_dir) ...@@ -81,7 +65,6 @@ int DirInit (access_t *p_access, DIR *p_dir)
return VLC_ENOMEM; return VLC_ENOMEM;
} }
p_access->p_sys = calloc (1, sizeof(access_sys_t)); p_access->p_sys = calloc (1, sizeof(access_sys_t));
if (!p_access->p_sys) if (!p_access->p_sys)
{ {
...@@ -102,7 +85,16 @@ int DirInit (access_t *p_access, DIR *p_dir) ...@@ -102,7 +85,16 @@ int DirInit (access_t *p_access, DIR *p_dir)
*****************************************************************************/ *****************************************************************************/
int DirOpen (vlc_object_t *p_this) int DirOpen (vlc_object_t *p_this)
{ {
return DirInit ((access_t*)p_this, NULL); access_t *access = (access_t *)p_this;
if (access->psz_filepath == NULL)
return VLC_EGENERIC;
DIR *dir = vlc_opendir (access->psz_filepath);
if (dir == NULL)
return VLC_EGENERIC;
return DirInit (access, dir);
} }
/***************************************************************************** /*****************************************************************************
...@@ -119,83 +111,31 @@ void DirClose( vlc_object_t * p_this ) ...@@ -119,83 +111,31 @@ void DirClose( vlc_object_t * p_this )
free (p_sys); free (p_sys);
} }
static bool is_looping(access_t *p_access, const char *psz_uri)
{
#ifdef S_ISLNK
struct stat st;
bool b_looping = false;
if (vlc_lstat (psz_uri, &st) != 0)
return false;
if (S_ISLNK (st.st_mode))
{
char *psz_link = malloc(st.st_size + 1);
ssize_t i_ret;
if (psz_link)
{
i_ret = readlink(psz_uri, psz_link, st.st_size + 1);
if (i_ret > 0 && i_ret <= st.st_size)
{
psz_link[i_ret] = '\0';
if (strstr(p_access->psz_filepath, psz_link))
b_looping = true;
}
free (psz_link);
}
}
return b_looping;
#else
VLC_UNUSED(p_access);
VLC_UNUSED(psz_uri);
return false;
#endif
}
input_item_t* DirRead (access_t *p_access) input_item_t* DirRead (access_t *p_access)
{ {
access_sys_t *p_sys = p_access->p_sys; access_sys_t *p_sys = p_access->p_sys;
DIR *p_dir = p_sys->p_dir; const char *entry;
input_item_t *p_item = NULL;
const char *psz_entry;
while (!p_item && (psz_entry = vlc_readdir (p_dir))) while ((entry = vlc_readdir (p_sys->p_dir)) != NULL)
{ {
char *psz_uri, *psz_encoded_entry;
struct stat st;
int i_type;
/* Check if it is a directory or even readable */
if (asprintf (&psz_uri, "%s/%s",
p_access->psz_filepath, psz_entry) == -1)
return NULL;
if (vlc_stat (psz_uri, &st) != 0)
{
free (psz_uri);
continue;
}
i_type = S_ISDIR (st.st_mode) ? ITEM_TYPE_DIRECTORY : ITEM_TYPE_FILE;
if (i_type == ITEM_TYPE_DIRECTORY && is_looping(p_access, psz_uri))
{
free (psz_uri);
continue;
}
free (psz_uri);
/* Create an input item for the current entry */ /* Create an input item for the current entry */
psz_encoded_entry = encode_URI_component (psz_entry); char *encoded_entry = encode_URI_component (entry);
if (psz_encoded_entry == NULL) if (unlikely(entry == NULL))
continue;
if (asprintf (&psz_uri, "%s/%s",
p_sys->psz_base_uri, psz_encoded_entry) == -1)
return NULL; return NULL;
free (psz_encoded_entry);
p_item = input_item_NewWithType (psz_uri, psz_entry, char *uri;
0, NULL, 0, 0, i_type); if (unlikely(asprintf (&uri, "%s/%s", p_sys->psz_base_uri,
free (psz_uri); encoded_entry) == -1))
if (!p_item) uri = NULL;
free (encoded_entry);
if (unlikely(uri == NULL))
return NULL; return NULL;
input_item_t *item = input_item_NewWithType (uri, entry, 0, NULL, 0, 0,
ITEM_TYPE_FILE);
free (uri);
if (likely(item != NULL))
return item;
} }
return p_item; return NULL;
} }
...@@ -138,7 +138,7 @@ static int FileControl (access_t *, int, va_list); ...@@ -138,7 +138,7 @@ static int FileControl (access_t *, int, va_list);
*****************************************************************************/ *****************************************************************************/
int FileOpen( vlc_object_t *p_this ) int FileOpen( vlc_object_t *p_this )
{ {
access_t *p_access = (access_t*)p_this; access_t *p_access = (access_t*)p_this;
/* Open file */ /* Open file */
int fd = -1; int fd = -1;
...@@ -163,23 +163,24 @@ int FileOpen( vlc_object_t *p_this ) ...@@ -163,23 +163,24 @@ int FileOpen( vlc_object_t *p_this )
} }
else else
{ {
const char *path = p_access->psz_filepath; if (unlikely(p_access->psz_filepath == NULL))
if (unlikely(path == NULL))
return VLC_EGENERIC; return VLC_EGENERIC;
msg_Dbg (p_access, "opening file `%s'", path); fd = vlc_open (p_access->psz_filepath, O_RDONLY | O_NONBLOCK);
fd = vlc_open (path, O_RDONLY | O_NONBLOCK);
if (fd == -1)
{
msg_Err (p_access, "cannot open file %s (%s)", path,
vlc_strerror_c(errno));
dialog_Fatal (p_access, _("File reading failed"),
_("VLC could not open the file \"%s\" (%s)."), path,
vlc_strerror(errno));
}
} }
if (fd == -1) if (fd == -1)
{
msg_Err (p_access, "cannot open file %s (%s)",
p_access->psz_filepath ? p_access->psz_filepath
: p_access->psz_location,
vlc_strerror_c(errno));
dialog_Fatal (p_access, _("File reading failed"),
_("VLC could not open the file \"%s\" (%s)."),
p_access->psz_filepath ? p_access->psz_filepath
: p_access->psz_location,
vlc_strerror(errno));
return VLC_EGENERIC; return VLC_EGENERIC;
}
struct stat st; struct stat st;
if (fstat (fd, &st)) if (fstat (fd, &st))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment