keystore/file: use POSIX file locking when flock() is unavailable
authorSean McGovern <gseanmcg@gmail.com>
Tue, 12 Apr 2016 15:14:37 +0000 (11:14 -0400)
committerThomas Guillem <thomas@gllm.fr>
Tue, 12 Apr 2016 15:35:45 +0000 (17:35 +0200)
Additionally, remove the unlock call as fclose() will drop
the lock for us.

Signed-off-by: Thomas Guillem <thomas@gllm.fr>
modules/keystore/file.c

index 381ec87..3c7a75b 100644 (file)
@@ -27,6 +27,9 @@
 #ifdef HAVE_FLOCK
 #include <sys/file.h>
 #endif
+#ifdef HAVE_FCNTL
+#include <fcntl.h>
+#endif
 
 #include <vlc_common.h>
 #include <vlc_plugin.h>
@@ -262,6 +265,27 @@ end:
     }
     return VLC_SUCCESS;
 }
+#if (!defined(HAVE_FLOCK) && defined (HAVE_FCNTL) && defined (F_SETLKW))
+static int
+posix_lock_fd(int fd)
+{
+    struct flock lock;
+    int flags;
+
+    if (fd == -1)
+        return -1;
+
+    flags = fcntl(fd, F_GETFL);
+
+    lock.l_start = 0;
+    lock.l_len = 0;
+    lock.l_whence = SEEK_SET;
+    lock.l_type = (flags & O_ACCMODE) == O_RDONLY ? F_RDLCK : F_WRLCK;
+
+    return fcntl(fd, F_SETLKW, &lock);
+}
+#endif
 
 static int
 file_open(const char *psz_file, const char *psz_mode, FILE **pp_file)
@@ -279,17 +303,19 @@ file_open(const char *psz_file, const char *psz_mode, FILE **pp_file)
     {
         fclose(p_file);
     }
+#elif defined (HAVE_FCNTL) && defined (F_SETLKW)
+    if (posix_lock_fd(i_fd) != 0)
+    {
+        fclose(p_file);
+    }
 #endif
     *pp_file = p_file;
     return i_fd;
 }
 
 static void
-file_close(FILE *p_file, int i_fd)
+file_close(FILE *p_file)
 {
-#ifdef HAVE_FLOCK
-    flock(i_fd, LOCK_UN);
-#endif
     fclose(p_file);
 }
 
@@ -349,7 +375,7 @@ Store(vlc_keystore *p_keystore, const char *const ppsz_values[KEY_MAX],
     i_ret = file_save(p_keystore, p_file, i_fd, &list);
 
 end:
-    file_close(p_file, i_fd);
+    file_close(p_file);
     ks_list_free(&list);
     return i_ret;
 }
@@ -413,7 +439,7 @@ Find(vlc_keystore *p_keystore, const char *const ppsz_values[KEY_MAX],
 
     *pp_entries = out_list.p_entries;
 end:
-    file_close(p_file, i_fd);
+    file_close(p_file);
     ks_list_free(&list);
     return out_list.i_count;
 }
@@ -445,7 +471,7 @@ Remove(vlc_keystore *p_keystore, const char *const ppsz_values[KEY_MAX])
         i_count = 0;
 
 end:
-    file_close(p_file, i_fd);
+    file_close(p_file);
     ks_list_free(&list);
     return i_count;
 }