ref: c126d5ac7843a809857a6dc14fbaae29a2499ff0
parent: 5bec036cfee3950d002f3c46c17bbd4e375d5bd6
author: Frank Henigman <fjhenigman@gmail.com>
date: Fri Feb 3 06:23:28 EST 2017
Fix directory existence check. mkdir() followed by errno==EEXIST is not sufficient to determine if a directory exists. Do a stat() to check for existence before trying mkdir(). Signed-off-by: Frank Henigman <fjhenigman@gmail.com> Signed-off-by: Jean-Baptiste Kempf <jb@videolan.org>
--- a/src/libdvdcss.c
+++ b/src/libdvdcss.c
@@ -143,6 +143,16 @@
#define MANUFACTURING_DATE_OFFSET 813
#define MANUFACTURING_DATE_LENGTH 16
+static int exists_or_mkdir( const char *path, int perm )
+{
+ /* mkdir() may return an error if making the directory would fail,
+ * even if the directory exists, so use stat() to test for existence
+ * before trying to make the directory. */
+ struct stat st;
+ if( stat(path, &st) )
+ return mkdir(path, perm);
+ return 0;
+}
static dvdcss_t dvdcss_open_common ( const char *psz_target, void *p_stream,
dvdcss_stream_cb *p_stream_cb );
@@ -221,7 +231,7 @@
* directory in userland */
char *psz_home = "/sdcard/Android/data/org.videolan.dvdcss";
- int i_ret = mkdir( psz_home, 0755 );
+ int i_ret = exists_or_mkdir( psz_home, 0755 );
if( i_ret < 0 && errno != EEXIST )
{
print_error( dvdcss, "failed creating home directory" );
@@ -302,7 +312,7 @@
char psz_tagfile[PATH_MAX];
int i_fd, i_ret;
- i_ret = mkdir( dvdcss->psz_cachefile, 0755 );
+ i_ret = exists_or_mkdir( dvdcss->psz_cachefile, 0755 );
if( i_ret < 0 && errno != EEXIST )
{
print_error( dvdcss, "failed creating cache directory '%s'", dvdcss->psz_cachefile );
@@ -425,7 +435,7 @@
/* We have a disc name or ID, we can create the cache subdirectory. */
i = sprintf( dvdcss->psz_cachefile, "%s/%s-%s-%s",
dvdcss->psz_cachefile, psz_title, psz_serial, psz_key );
- i_ret = mkdir( dvdcss->psz_cachefile, 0755 );
+ i_ret = exists_or_mkdir( dvdcss->psz_cachefile, 0755 );
if( i_ret < 0 && errno != EEXIST )
{
print_error( dvdcss, "failed creating cache subdirectory" );