From: Alexander Larsson Date: Thu, 18 Jun 2009 07:05:27 +0000 (+0200) Subject: Add extension point for adding metadata for local files X-Git-Tag: 2.21.3~42 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7662c86611bf44175f18ec6eb66f159040ac73c5;p=platform%2Fupstream%2Fglib.git Add extension point for adding metadata for local files This adds a local_file_add_info vfunc to GVfs that vfs implementations can override to add metadata for local files. --- diff --git a/gio/glocalfile.c b/gio/glocalfile.c index 8ac60144d..1f956a5cc 100644 --- a/gio/glocalfile.c +++ b/gio/glocalfile.c @@ -110,7 +110,7 @@ static void g_local_file_file_iface_init (GFileIface *iface); static GFileAttributeInfoList *local_writable_attributes = NULL; -static GFileAttributeInfoList *local_writable_namespaces = NULL; +static /* GFileAttributeInfoList * */ gsize local_writable_namespaces = 0; struct _GLocalFile { @@ -201,24 +201,6 @@ g_local_file_class_init (GLocalFileClass *klass) #endif local_writable_attributes = list; - - /* Writable namespaces: */ - - list = g_file_attribute_info_list_new (); - -#ifdef HAVE_XATTR - g_file_attribute_info_list_add (list, - "xattr", - G_FILE_ATTRIBUTE_TYPE_STRING, - G_FILE_ATTRIBUTE_INFO_COPY_WITH_FILE | - G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED); - g_file_attribute_info_list_add (list, - "xattr-sys", - G_FILE_ATTRIBUTE_TYPE_STRING, - G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED); -#endif - - local_writable_namespaces = list; } static void @@ -1204,6 +1186,8 @@ g_local_file_query_info (GFile *file, matcher, flags, &parent_info, error); + + _g_local_file_info_free_parent_info (&parent_info); g_free (basename); g_file_attribute_matcher_unref (matcher); @@ -1224,7 +1208,38 @@ g_local_file_query_writable_namespaces (GFile *file, GCancellable *cancellable, GError **error) { - return g_file_attribute_info_list_ref (local_writable_namespaces); + GFileAttributeInfoList *list; + GVfsClass *class; + GVfs *vfs; + + if (g_once_init_enter (&local_writable_namespaces)) + { + /* Writable namespaces: */ + + list = g_file_attribute_info_list_new (); + +#ifdef HAVE_XATTR + g_file_attribute_info_list_add (list, + "xattr", + G_FILE_ATTRIBUTE_TYPE_STRING, + G_FILE_ATTRIBUTE_INFO_COPY_WITH_FILE | + G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED); + g_file_attribute_info_list_add (list, + "xattr-sys", + G_FILE_ATTRIBUTE_TYPE_STRING, + G_FILE_ATTRIBUTE_INFO_COPY_WHEN_MOVED); +#endif + + vfs = g_vfs_get_default (); + class = G_VFS_GET_CLASS (vfs); + if (class->add_writable_namespaces) + class->add_writable_namespaces (vfs, list); + + g_once_init_leave (&local_writable_namespaces, (gsize)list); + } + list = (GFileAttributeInfoList *)local_writable_namespaces; + + return g_file_attribute_info_list_ref (list); } static gboolean @@ -1409,7 +1424,9 @@ g_local_file_delete (GFile *file, GError **error) { GLocalFile *local = G_LOCAL_FILE (file); - + GVfsClass *class; + GVfs *vfs; + if (g_remove (local->filename) == -1) { int errsv = errno; @@ -1426,7 +1443,12 @@ g_local_file_delete (GFile *file, g_strerror (errsv)); return FALSE; } - + + vfs = g_vfs_get_default (); + class = G_VFS_GET_CLASS (vfs); + if (class->local_file_removed) + class->local_file_removed (vfs, local->filename); + return TRUE; } @@ -2176,7 +2198,9 @@ g_local_file_move (GFile *source, char *backup_name; int res; off_t source_size; - + GVfsClass *class; + GVfs *vfs; + if (!G_IS_LOCAL_FILE (source) || !G_IS_LOCAL_FILE (destination)) { @@ -2294,6 +2318,11 @@ g_local_file_move (GFile *source, return FALSE; } + vfs = g_vfs_get_default (); + class = G_VFS_GET_CLASS (vfs); + if (class->local_file_moved) + class->local_file_moved (vfs, local_source->filename, local_destination->filename); + /* Make sure we send full copied size */ if (progress_callback) progress_callback (source_size, source_size, progress_callback_data); diff --git a/gio/glocalfileenumerator.c b/gio/glocalfileenumerator.c index eda7b034a..e39c05071 100644 --- a/gio/glocalfileenumerator.c +++ b/gio/glocalfileenumerator.c @@ -116,6 +116,8 @@ g_local_file_enumerator_finalize (GObject *object) local = G_LOCAL_FILE_ENUMERATOR (object); + if (local->got_parent_info) + _g_local_file_info_free_parent_info (&local->parent_info); g_free (local->filename); g_file_attribute_matcher_unref (local->matcher); if (local->dir) diff --git a/gio/glocalfileinfo.c b/gio/glocalfileinfo.c index 95ccf2ee8..c6d4be0c6 100644 --- a/gio/glocalfileinfo.c +++ b/gio/glocalfileinfo.c @@ -60,6 +60,7 @@ #include #include +#include #include "glibintl.h" @@ -791,7 +792,9 @@ _g_local_file_info_get_parent_info (const char *dir, */ struct stat statbuf; int res; - + + parent_info->extra_data = NULL; + parent_info->free_extra_data = NULL; parent_info->writable = FALSE; parent_info->is_sticky = FALSE; parent_info->has_trash_dir = FALSE; @@ -833,6 +836,14 @@ _g_local_file_info_get_parent_info (const char *dir, } } +void +_g_local_file_info_free_parent_info (GLocalParentFileInfo *parent_info) +{ + if (parent_info->extra_data && + parent_info->free_extra_data) + parent_info->free_extra_data (parent_info->extra_data); +} + static void get_access_rights (GFileAttributeMatcher *attribute_matcher, GFileInfo *info, @@ -1417,6 +1428,9 @@ _g_local_file_info_get (const char *basename, #ifdef G_OS_WIN32 DWORD dos_attributes; #endif + char *symlink_target; + GVfs *vfs; + GVfsClass *class; info = g_file_info_new (); @@ -1514,16 +1528,15 @@ _g_local_file_info_get (const char *basename, g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_DOS_IS_SYSTEM, TRUE); #endif -#ifdef S_ISLNK - if (is_symlink && - g_file_attribute_matcher_matches (attribute_matcher, - G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET)) + symlink_target = NULL; + if (is_symlink) { - char *link = read_link (path); - g_file_info_set_symlink_target (info, link); - g_free (link); + symlink_target = read_link (path); + if (symlink_target && + g_file_attribute_matcher_matches (attribute_matcher, + G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET)) + g_file_info_set_symlink_target (info, symlink_target); } -#endif if (g_file_attribute_matcher_matches (attribute_matcher, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME)) @@ -1689,9 +1702,34 @@ _g_local_file_info_get (const char *basename, if (g_file_attribute_matcher_matches (attribute_matcher, G_FILE_ATTRIBUTE_THUMBNAIL_PATH)) get_thumbnail_attributes (path, info); - + + vfs = g_vfs_get_default (); + class = G_VFS_GET_CLASS (vfs); + if (class->local_file_add_info) + { + const char *extra_target; + + extra_target = path; + if (!(flags & G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS) && + is_symlink && + !symlink_broken && + symlink_target != NULL) + extra_target = symlink_target; + + class->local_file_add_info (vfs, + extra_target, + statbuf.st_dev, + attribute_matcher, + info, + NULL, + &parent_info->extra_data, + &parent_info->free_extra_data); + } + g_file_info_unset_attribute_mask (info); + g_free (symlink_target); + return info; } @@ -2126,6 +2164,8 @@ _g_local_file_info_set_attribute (char *filename, GError **error) { GFileAttributeValue value = { 0 }; + GVfsClass *class; + GVfs *vfs; _g_file_attribute_value_set_from_pointer (&value, type, value_p, FALSE); @@ -2166,7 +2206,36 @@ _g_local_file_info_set_attribute (char *filename, else if (strcmp (attribute, G_FILE_ATTRIBUTE_SELINUX_CONTEXT) == 0) return set_selinux_context (filename, &value, error); #endif - + + vfs = g_vfs_get_default (); + class = G_VFS_GET_CLASS (vfs); + if (class->local_file_set_attributes) + { + GFileInfo *info; + + info = g_file_info_new (); + g_file_info_set_attribute (info, + attribute, + type, + value_p); + if (!class->local_file_set_attributes (vfs, filename, + info, + flags, cancellable, + error)) + { + g_object_unref (info); + return FALSE; + } + + if (g_file_info_get_attribute_status (info, attribute) == G_FILE_ATTRIBUTE_STATUS_SET) + { + g_object_unref (info); + return TRUE; + } + + g_object_unref (info); + } + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, _("Setting attribute %s not supported"), attribute); return FALSE; @@ -2190,6 +2259,8 @@ _g_local_file_info_set_attributes (char *filename, GFileAttributeStatus status; #endif gboolean res; + GVfsClass *class; + GVfs *vfs; /* Handles setting multiple specified data in a single set, and takes care of ordering restrictions when setting attributes */ @@ -2310,5 +2381,20 @@ _g_local_file_info_set_attributes (char *filename, } #endif + vfs = g_vfs_get_default (); + class = G_VFS_GET_CLASS (vfs); + if (class->local_file_set_attributes) + { + if (!class->local_file_set_attributes (vfs, filename, + info, + flags, cancellable, + error)) + { + res = FALSE; + /* Don't set error multiple times */ + error = NULL; + } + } + return res; } diff --git a/gio/glocalfileinfo.h b/gio/glocalfileinfo.h index 29ccfc04c..82ad7463a 100644 --- a/gio/glocalfileinfo.h +++ b/gio/glocalfileinfo.h @@ -39,6 +39,8 @@ typedef struct gboolean has_trash_dir; int owner; dev_t device; + gpointer extra_data; + GDestroyNotify free_extra_data; } GLocalParentFileInfo; #ifdef G_OS_WIN32 @@ -53,6 +55,7 @@ gboolean _g_local_file_has_trash_dir (const char *dirname, void _g_local_file_info_get_parent_info (const char *dir, GFileAttributeMatcher *attribute_matcher, GLocalParentFileInfo *parent_info); +void _g_local_file_info_free_parent_info (GLocalParentFileInfo *parent_info); GFileInfo *_g_local_file_info_get (const char *basename, const char *path, GFileAttributeMatcher *attribute_matcher, diff --git a/gio/gvfs.h b/gio/gvfs.h index bb8fd8034..be0156f3c 100644 --- a/gio/gvfs.h +++ b/gio/gvfs.h @@ -75,6 +75,27 @@ struct _GVfsClass /*< private >*/ /* Padding for future expansion */ + void (* local_file_add_info) (GVfs *vfs, + const char *filename, + guint64 device, + GFileAttributeMatcher *attribute_matcher, + GFileInfo *info, + GCancellable *cancellable, + gpointer *extra_data, + GDestroyNotify *free_extra_data); + void (* add_writable_namespaces) (GVfs *vfs, + GFileAttributeInfoList *list); + gboolean (* local_file_set_attributes) (GVfs *vfs, + const char *filename, + GFileInfo *info, + GFileQueryInfoFlags flags, + GCancellable *cancellable, + GError **error); + void (* local_file_removed) (GVfs *vfs, + const char *filename); + void (* local_file_moved) (GVfs *vfs, + const char *source, + const char *dest); void (*_g_reserved1) (void); void (*_g_reserved2) (void); void (*_g_reserved3) (void); @@ -82,11 +103,6 @@ struct _GVfsClass void (*_g_reserved5) (void); void (*_g_reserved6) (void); void (*_g_reserved7) (void); - void (*_g_reserved8) (void); - void (*_g_reserved9) (void); - void (*_g_reserved10) (void); - void (*_g_reserved11) (void); - void (*_g_reserved12) (void); }; GType g_vfs_get_type (void) G_GNUC_CONST;