[vlc-devel] [PATCH 1/3] file: fix directory subitems type
Thomas Guillem
thomas at gllm.fr
Wed Nov 4 19:35:49 CET 2015
---
modules/access/directory.c | 77 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 76 insertions(+), 1 deletion(-)
diff --git a/modules/access/directory.c b/modules/access/directory.c
index 4985855..72d33ee 100644
--- a/modules/access/directory.c
+++ b/modules/access/directory.c
@@ -31,6 +31,11 @@
# include "config.h"
#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+
#include <vlc_common.h>
#include "fs.h"
#include <vlc_access.h>
@@ -43,6 +48,7 @@ struct access_sys_t
{
char *psz_base_uri;
DIR *p_dir;
+ int fd;
};
/*****************************************************************************
@@ -51,11 +57,14 @@ struct access_sys_t
int DirInit (access_t *p_access, DIR *p_dir)
{
char *psz_base_uri;
+ int fd = -1;
if (!strcmp (p_access->psz_access, "fd"))
{
if (asprintf (&psz_base_uri, "fd://%s", p_access->psz_location) == -1)
psz_base_uri = NULL;
+
+ fd = dirfd (p_dir);
}
else
psz_base_uri = vlc_path2uri (p_access->psz_filepath, "file");
@@ -73,6 +82,7 @@ int DirInit (access_t *p_access, DIR *p_dir)
return VLC_ENOMEM;
}
p_access->p_sys->p_dir = p_dir;
+ p_access->p_sys->fd = fd;
p_access->p_sys->psz_base_uri = psz_base_uri;
p_access->pf_readdir = DirRead;
p_access->pf_control = access_vaDirectoryControlHelper;
@@ -111,6 +121,38 @@ void DirClose( vlc_object_t * p_this )
free (p_sys);
}
+static bool DirIsLooping (access_t *p_access, const char *uri)
+{
+#ifdef S_ISLNK
+ struct stat st;
+ bool looping = false;
+
+ if (vlc_lstat (uri, &st) != 0)
+ return false;
+ if (S_ISLNK (st.st_mode))
+ {
+ char *link = malloc (st.st_size + 1);
+
+ if (link)
+ {
+ ssize_t ret = readlink (uri, link, st.st_size + 1);
+ if (ret > 0 && ret <= st.st_size)
+ {
+ link[ret] = '\0';
+ if (strstr (p_access->psz_filepath, link))
+ looping = true;
+ }
+ free (link);
+ }
+ }
+ return looping;
+#else
+ VLC_UNUSED (p_access);
+ VLC_UNUSED (uri);
+ return false;
+#endif
+}
+
input_item_t* DirRead (access_t *p_access)
{
access_sys_t *p_sys = p_access->p_sys;
@@ -118,6 +160,39 @@ input_item_t* DirRead (access_t *p_access)
while ((entry = vlc_readdir (p_sys->p_dir)) != NULL)
{
+ /* Check if the current entry is a directory */
+ int i_type = ITEM_TYPE_FILE;
+ if (p_sys->fd != -1)
+ {
+ int fd = vlc_openat (p_sys->fd, entry, O_RDONLY);
+ if (fd != -1)
+ {
+ struct stat st;
+ if (fstat(fd, &st) == 0 && S_ISDIR (st.st_mode))
+ i_type = ITEM_TYPE_DIRECTORY;
+ close(fd);
+ }
+ }
+ else
+ {
+ char *uri;
+ if (unlikely(asprintf (&uri, "%s/%s", p_access->psz_filepath,
+ entry) == -1))
+ return NULL;
+
+ struct stat st;
+ if (vlc_stat (uri, &st) == 0 && S_ISDIR (st.st_mode))
+ i_type = ITEM_TYPE_DIRECTORY;
+
+ if (i_type == ITEM_TYPE_DIRECTORY && DirIsLooping (p_access, uri))
+ {
+ free (uri);
+ continue;
+ }
+
+ free (uri);
+ }
+
/* Create an input item for the current entry */
char *encoded_entry = encode_URI_component (entry);
if (unlikely(entry == NULL))
@@ -132,7 +207,7 @@ input_item_t* DirRead (access_t *p_access)
return NULL;
input_item_t *item = input_item_NewWithType (uri, entry, 0, NULL, 0, 0,
- ITEM_TYPE_FILE);
+ i_type);
free (uri);
if (likely(item != NULL))
return item;
--
2.1.4
More information about the vlc-devel
mailing list