summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2008-01-16 10:11:26 +0000
committerAlexander Larsson <alexl@src.gnome.org>2008-01-16 10:11:26 +0000
commit87cd883e8d851eb3b844be9a74f2a444f2e2f190 (patch)
tree4cb442fd0fb92c47d4a12bb72deb0653fbe78ec2
parent218827445d8b83b38c153ef810338cc41dd6d172 (diff)
downloadglib-87cd883e8d851eb3b844be9a74f2a444f2e2f190.tar.gz
Add g_file_query_exists (#508771)
2008-01-16 Alexander Larsson <alexl@redhat.com> * gfile.[ch]: * gio.symbols: Add g_file_query_exists (#508771) svn path=/trunk/; revision=6319
-rw-r--r--gio/ChangeLog6
-rw-r--r--gio/gfile.c47
-rw-r--r--gio/gfile.h2
-rw-r--r--gio/gio.symbols1
4 files changed, 56 insertions, 0 deletions
diff --git a/gio/ChangeLog b/gio/ChangeLog
index 99abddd7e..0d0da7672 100644
--- a/gio/ChangeLog
+++ b/gio/ChangeLog
@@ -1,3 +1,9 @@
+2008-01-16 Alexander Larsson <alexl@redhat.com>
+
+ * gfile.[ch]:
+ * gio.symbols:
+ Add g_file_query_exists (#508771)
+
2008-01-15 Murray Cumming <murrayc@murrayc.com>
* gdrive.c:
diff --git a/gio/gfile.c b/gio/gfile.c
index 84611ce7c..3cc7579a8 100644
--- a/gio/gfile.c
+++ b/gio/gfile.c
@@ -812,6 +812,53 @@ g_file_enumerate_children_finish (GFile *file,
return (* iface->enumerate_children_finish) (file, res, error);
}
+/**
+ * g_file_query_exists:
+ * @file: input #GFile.
+ * @cancellable: optional #GCancellable object, %NULL to ignore.
+ *
+ * Utility function to check if a particular file exists. This is
+ * implemented using g_file_query_info() and as such does blocking I/O.
+ *
+ * Note that in many cases it is racy to first check for file existance
+ * and then execute something based on the outcome of that, because the
+ * file might have been created or removed inbetween the operations. The
+ * general approach to handling that is to not check, but just do the
+ * operation and handle the errors as they come.
+ *
+ * As an example of race-free checking. Take the case of reading a file, and
+ * if it doesn't exist, create it. There are two racy versions: read it, and
+ * on error create it; and: check if it exists, if not create it. These
+ * can both result in two processes creating the file (with perhaps a partially
+ * written file as the result). The correct approach is to always try to create
+ * the file with g_file_create() which will either atomically create the file
+ * or fail with an G_IO_ERROR_EXISTS error.
+ *
+ * However, in many cases an existance check is useful in a user
+ * interface, for instance to make a menu item sensitive/insensitive, so that
+ * you don't have to fool users that something is possible and then just show
+ * and error dialog. If you do this, you should make sure to also handle the
+ * errors that can happen due to races when you execute the operation.
+ *
+ * Returns: %TRUE if the file exists (and can be detected without error), %FALSE otherwise (or if cancelled).
+ */
+gboolean
+g_file_query_exists (GFile *file,
+ GCancellable *cancellable)
+{
+ GFileInfo *info;
+
+ info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_TYPE,
+ G_FILE_QUERY_INFO_NONE,
+ cancellable, NULL);
+ if (info != NULL)
+ {
+ g_object_unref (info);
+ return TRUE;
+ }
+
+ return FALSE;
+}
/**
* g_file_query_info:
diff --git a/gio/gfile.h b/gio/gfile.h
index 0fd571883..8d8ee6b8c 100644
--- a/gio/gfile.h
+++ b/gio/gfile.h
@@ -612,6 +612,8 @@ void g_file_replace_async (GFile
GFileOutputStream * g_file_replace_finish (GFile *file,
GAsyncResult *res,
GError **error);
+gboolean g_file_query_exists (GFile *file,
+ GCancellable *cancellable);
GFileInfo * g_file_query_info (GFile *file,
const char *attributes,
GFileQueryInfoFlags flags,
diff --git a/gio/gio.symbols b/gio/gio.symbols
index e679f789a..d15e53d3f 100644
--- a/gio/gio.symbols
+++ b/gio/gio.symbols
@@ -243,6 +243,7 @@ g_file_create_async
g_file_create_finish
g_file_replace_async
g_file_replace_finish
+g_file_query_exists
g_file_query_info
g_file_query_info_async
g_file_query_info_finish