[tracker/writeback: 11/16] tracker-file-utils.c: Add file locking API.



commit d2a97ebb0e45d1d330f75ffe2f7ec26e131df445
Author: Carlos Garnacho <carlos lanedo com>
Date:   Tue Nov 17 15:32:15 2009 +0100

    tracker-file-utils.c: Add file locking API.
    
    This API will be used by the writeback service, so TrackerMinerFS
    implementations don't obey updates while metadata is being written.

 src/libtracker-common/tracker-file-utils.c |  126 ++++++++++++++++++++++++++++
 src/libtracker-common/tracker-file-utils.h |    4 +
 2 files changed, 130 insertions(+), 0 deletions(-)
---
diff --git a/src/libtracker-common/tracker-file-utils.c b/src/libtracker-common/tracker-file-utils.c
index 2eac645..c61c941 100644
--- a/src/libtracker-common/tracker-file-utils.c
+++ b/src/libtracker-common/tracker-file-utils.c
@@ -30,8 +30,10 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/statvfs.h>
+#include <sys/file.h>
 #include <fcntl.h>
 #include <limits.h>
+#include <errno.h>
 
 #include <glib.h>
 #include <gio/gio.h>
@@ -687,3 +689,127 @@ tracker_env_check_xdg_dirs (void)
 
 	return success;
 }
+
+static int
+flock_file (GFile *file,
+	    gint   flags)
+{
+	gchar *path;
+	gint fd, retval;
+
+	g_return_val_if_fail (G_IS_FILE (file), -1);
+
+	if (g_file_is_native (file)) {
+		return -1;
+	}
+
+	path = g_file_get_path (file);
+
+	if (!path) {
+		return -1;
+	}
+
+	fd = open (path, O_RDONLY);
+
+	if (fd < 0) {
+		g_warning ("Could not open '%s'", path);
+		retval = -1;
+	} else {
+		retval = flock (fd, flags);
+		close (fd);
+	}
+
+	g_free (path);
+
+	return retval;
+}
+
+gboolean
+tracker_file_lock (GFile *file)
+{
+	gint retval;
+
+	g_return_val_if_fail (G_IS_FILE (file), FALSE);
+
+	retval = flock_file (file, LOCK_EX);
+
+	if (retval < 0) {
+		gchar *path;
+
+		path = g_file_get_path (file);
+		g_warning ("Could not lock file '%s'", path);
+		g_free (path);
+
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+gboolean
+tracker_file_unlock (GFile *file)
+{
+	gint retval;
+
+	g_return_val_if_fail (G_IS_FILE (file), FALSE);
+
+	retval = flock_file (file, LOCK_UN);
+
+	if (retval < 0) {
+		gchar *path;
+
+		path = g_file_get_path (file);
+		g_warning ("Could not unlock file '%s'", path);
+		g_free (path);
+
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+gboolean
+tracker_file_is_locked (GFile *file)
+{
+	gboolean retval = FALSE;
+	gchar *path;
+	gint fd;
+
+	g_return_val_if_fail (G_IS_FILE (file), FALSE);
+
+	if (g_file_is_native (file)) {
+		return FALSE;
+	}
+
+	path = g_file_get_path (file);
+
+	if (!path) {
+		return FALSE;
+	}
+
+	fd = open (path, O_RDONLY);
+
+	if (fd < 0) {
+		g_warning ("Could not open '%s'", path);
+		g_free (path);
+
+		return FALSE;
+	}
+
+	/* Check for locks */
+	retval = flock (fd, LOCK_EX | LOCK_NB);
+
+	if (retval < 0) {
+		if (errno == EWOULDBLOCK) {
+			retval = TRUE;
+		}
+	} else {
+		/* Oops, call was successful, unlock again the file */
+		flock (fd, LOCK_UN);
+	}
+
+	close (fd);
+	g_free (path);
+
+	return retval;
+}
diff --git a/src/libtracker-common/tracker-file-utils.h b/src/libtracker-common/tracker-file-utils.h
index b3b0c0d..174adbf 100644
--- a/src/libtracker-common/tracker-file-utils.h
+++ b/src/libtracker-common/tracker-file-utils.h
@@ -52,6 +52,10 @@ gchar *  tracker_path_evaluate_name                (const gchar  *uri);
 
 gboolean tracker_env_check_xdg_dirs                (void);
 
+gboolean tracker_file_lock                         (GFile *file);
+gboolean tracker_file_unlock                       (GFile *file);
+gboolean tracker_file_is_locked                    (GFile *file);
+
 G_END_DECLS
 
 #endif /* __LIBTRACKER_COMMON_FILE_UTILS_H__ */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]