diff --git a/gio/glocalfileinfo.c b/gio/glocalfileinfo.c index 7c2524e8d..4f51427f5 100644 --- a/gio/glocalfileinfo.c +++ b/gio/glocalfileinfo.c @@ -2832,6 +2832,16 @@ set_mtime_atime (char *filename, } } + if (atime_usec_value) + { + guint32 val_usec = 0; + + if (!get_uint32 (atime_usec_value, &val_usec, error)) + return FALSE; + + times_n[0].tv_nsec = val_usec * 1000; + } + if (atime_nsec_value) { guint32 val_nsec = 0; @@ -2861,6 +2871,16 @@ set_mtime_atime (char *filename, } } + if (mtime_usec_value) + { + guint32 val_usec = 0; + + if (!get_uint32 (mtime_usec_value, &val_usec, error)) + return FALSE; + + times_n[1].tv_nsec = val_usec * 1000; + } + if (mtime_nsec_value) { guint32 val_nsec = 0; diff --git a/gio/tests/g-file-info.c b/gio/tests/g-file-info.c index 9b4c6368c..9d97d5ac4 100644 --- a/gio/tests/g-file-info.c +++ b/gio/tests/g-file-info.c @@ -1102,6 +1102,50 @@ test_xattrs (void) g_object_unref (file); } +static void +test_set_modified_date_time_precision (void) +{ + GDateTime *modified = NULL; + GFile *file = NULL; + GFileIOStream *stream = NULL; + GFileInfo *info = NULL; + GError *local_error = NULL; + + + g_test_summary ("Test that g_file_info_set_modified_date_time() preserves microseconds"); + g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/3116"); + + file = g_file_new_tmp ("g-file-info-test-set-modified-date-time-precision-XXXXXX", &stream, &local_error); + g_assert_no_error (local_error); + + modified = g_date_time_new_from_iso8601 ("2000-01-01T00:00:00.123456Z", NULL); + + info = g_file_query_info (file, + G_FILE_ATTRIBUTE_TIME_MODIFIED "," + G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC "," + G_FILE_ATTRIBUTE_TIME_MODIFIED_NSEC, G_FILE_QUERY_INFO_NONE, NULL, &local_error); + g_assert_no_error (local_error); + + g_file_info_set_modification_date_time (info, modified); + g_assert_true (g_file_set_attributes_from_info (file, info, G_FILE_QUERY_INFO_NONE, NULL, &local_error)); + g_assert_no_error (local_error); + + g_clear_object (&info); + g_clear_pointer (&modified, g_date_time_unref); + + info = g_file_query_info (file, + G_FILE_ATTRIBUTE_TIME_MODIFIED "," + G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC "," + G_FILE_ATTRIBUTE_TIME_MODIFIED_NSEC, G_FILE_QUERY_INFO_NONE, NULL, &local_error); + g_assert_no_error (local_error); + + g_assert_cmpuint (g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC), ==, 123456); + + g_clear_object (&stream); + g_clear_object (&info); + g_clear_object (&file); +} + int main (int argc, char *argv[]) @@ -1116,6 +1160,7 @@ main (int argc, g_test_add_func ("/g-file-info/internal-enhanced-stdio", test_internal_enhanced_stdio); #endif g_test_add_func ("/g-file-info/xattrs", test_xattrs); + g_test_add_func ("/g-file-info/set-modified-date-time-precision", test_set_modified_date_time_precision); return g_test_run(); }