diff options
author | Tomas Bzatek <tbzatek@redhat.com> | 2009-11-19 15:48:56 +0100 |
---|---|---|
committer | Alexander Larsson <alexl@redhat.com> | 2009-11-27 15:15:15 +0100 |
commit | 2a6663bf3f98b797b3a21dcd21833b91d3d97793 (patch) | |
tree | 61514c8414fc36ce00333971c1ee56c875be0c8d | |
parent | a455d9e65d6725067317ee0176275c2e18d9a16b (diff) | |
download | gvfs-2a6663bf3f98b797b3a21dcd21833b91d3d97793.tar.gz |
fuse: Fix setting timestamps
We need to set time in seconds and microseconds separately.
Moreover, backends may not fully support setting all attributes
so don't report failure when at least one succeeded.
At the moment, only SMB supports setting G_FILE_ATTRIBUTE_TIME_MODIFIED.
(cherry picked from commit 59bea4126cf23c575323c59a4cb1123f7cb44e2b)
-rw-r--r-- | client/gvfsfusedaemon.c | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/client/gvfsfusedaemon.c b/client/gvfsfusedaemon.c index 6e82e156..38939373 100644 --- a/client/gvfsfusedaemon.c +++ b/client/gvfsfusedaemon.c @@ -2083,40 +2083,53 @@ vfs_utimens (const gchar *path, const struct timespec tv [2]) if (file) { guint64 atime; + guint32 atime_usec; guint64 mtime; + guint32 mtime_usec; + GFileInfo *info; if (tv) { - atime = (guint64) tv [0].tv_sec * 1000000 + (guint64) tv [0].tv_nsec / (guint64) 1000; - mtime = (guint64) tv [1].tv_sec * 1000000 + (guint64) tv [1].tv_nsec / (guint64) 1000; + atime = (guint64) tv [0].tv_sec; + atime_usec = (guint32) tv [0].tv_nsec / (guint32) 1000; + mtime = (guint64) tv [1].tv_sec; + mtime_usec = (guint32) tv [1].tv_nsec / (guint32) 1000; } else { struct timeval tiv; gettimeofday (&tiv, NULL); - atime = (guint64) tiv.tv_sec * (guint64) 1000000 + (guint64) tiv.tv_usec; + atime = (guint64) tiv.tv_sec; + atime_usec = (guint32) tiv.tv_usec; mtime = atime; + mtime_usec = atime_usec; } - g_file_set_attribute (file, G_FILE_ATTRIBUTE_TIME_ACCESS_USEC, - G_FILE_ATTRIBUTE_TYPE_UINT64, &atime, - 0, NULL, &error); + info = g_file_info_new (); + g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED, mtime); + g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC, mtime_usec); + g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_TIME_ACCESS, atime); + g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_ACCESS_USEC, atime_usec); - if (!error) - { - g_file_set_attribute (file, G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC, - G_FILE_ATTRIBUTE_TYPE_UINT64, &mtime, - 0, NULL, &error); - } + g_file_set_attributes_from_info (file, info, 0, NULL, &error); if (error) { - result = -errno_from_error (error); + /* As long as not all backends support all attributes we set, + report failure only if neither mtime and atime have been set. */ + if (g_file_info_get_attribute_status (info, G_FILE_ATTRIBUTE_TIME_ACCESS) == G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING && + g_file_info_get_attribute_status (info, G_FILE_ATTRIBUTE_TIME_MODIFIED) == G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING) + { + /* Note: we only get first error from the attributes we try to set, might not be accurate + (a limitation of g_file_set_attributes_from_info()). */ + result = -errno_from_error (error); + } g_error_free (error); } g_object_unref (file); + g_object_unref (info); } else if (path_is_mount_list (path)) { |