1 /* GLib testing framework examples and tests
2 * Copyright (C) 2008 Red Hat, Inc.
3 * Authors: Tomas Bzatek <tbzatek@redhat.com>
5 * SPDX-License-Identifier: LicenseRef-old-glib-tests
7 * This work is provided "as is"; redistribution and modification
8 * in whole or in part, in any medium, physical or electronic is
9 * permitted without restriction.
11 * This work is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 * In no event shall the authors or contributors be liable for any
16 * direct, indirect, incidental, special, exemplary, or consequential
17 * damages (including, but not limited to, procurement of substitute
18 * goods or services; loss of use, data, or profits; or business
19 * interruption) however caused and on any theory of liability, whether
20 * in contract, strict liability, or tort (including negligence or
21 * otherwise) arising in any way out of the use of this software, even
22 * if advised of the possibility of such damage.
27 #include <glib/glib.h>
33 #include <glib/gstdio.h>
36 #include <io.h> /* for _get_osfhandle */
39 #define TEST_NAME "Prilis zlutoucky kun"
40 #define TEST_DISPLAY_NAME "UTF-8 p\xc5\x99\xc3\xadli\xc5\xa1 \xc5\xbelu\xc5\xa5ou\xc4\x8dk\xc3\xbd k\xc5\xaf\xc5\x88"
41 #define TEST_SIZE 0xFFFFFFF0
44 test_assigned_values (GFileInfo *info)
46 const char *name, *name_filepath, *display_name, *mistake;
50 /* Test for attributes presence */
51 g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_NAME));
52 g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME));
53 g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SIZE));
54 g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_COPY_NAME));
56 /* Retrieve data back and compare */
58 name = g_file_info_get_attribute_byte_string (info, G_FILE_ATTRIBUTE_STANDARD_NAME);
59 name_filepath = g_file_info_get_attribute_file_path (info, G_FILE_ATTRIBUTE_STANDARD_NAME);
60 display_name = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME);
61 mistake = g_file_info_get_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_COPY_NAME);
62 size = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_STANDARD_SIZE);
63 type = g_file_info_get_file_type (info);
65 g_assert_cmpstr (name, ==, TEST_NAME);
66 g_assert_cmpstr (name_filepath, ==, name);
67 g_assert_cmpstr (display_name, ==, TEST_DISPLAY_NAME);
68 g_assert_null (mistake);
69 g_assert_cmpint (size, ==, TEST_SIZE);
70 g_assert_cmpstr (name, ==, g_file_info_get_name (info));
71 g_assert_cmpstr (display_name, ==, g_file_info_get_display_name (info));
72 g_assert_cmpint (size, ==, g_file_info_get_size (info) );
73 g_assert_cmpint (type, ==, G_FILE_TYPE_DIRECTORY);
79 test_g_file_info (void)
85 GFileAttributeMatcher *matcher;
87 info = g_file_info_new ();
89 /* Test for empty instance */
90 attr_list = g_file_info_list_attributes (info, NULL);
91 g_assert_nonnull (attr_list);
92 g_assert_null (*attr_list);
93 g_strfreev (attr_list);
95 g_file_info_set_attribute_byte_string (info, G_FILE_ATTRIBUTE_STANDARD_NAME, TEST_NAME);
96 g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, TEST_DISPLAY_NAME);
97 g_file_info_set_attribute_uint64 (info, G_FILE_ATTRIBUTE_STANDARD_SIZE, TEST_SIZE);
98 g_file_info_set_file_type (info, G_FILE_TYPE_DIRECTORY);
100 /* The attr list should not be empty now */
101 attr_list = g_file_info_list_attributes (info, NULL);
102 g_assert_nonnull (attr_list);
103 g_assert_nonnull (*attr_list);
104 g_strfreev (attr_list);
106 test_assigned_values (info);
108 /* Test the file path encoding functions */
109 g_file_info_set_attribute_file_path (info, G_FILE_ATTRIBUTE_STANDARD_NAME, "something different");
110 g_assert_cmpstr (g_file_info_get_attribute_file_path (info, G_FILE_ATTRIBUTE_STANDARD_NAME), ==, "something different");
111 g_file_info_set_attribute_file_path (info, G_FILE_ATTRIBUTE_STANDARD_NAME, TEST_NAME);
114 info_dup = g_file_info_dup (info);
115 g_assert_nonnull (info_dup);
116 test_assigned_values (info_dup);
118 info_copy = g_file_info_new ();
119 g_file_info_copy_into (info_dup, info_copy);
120 g_assert_nonnull (info_copy);
121 test_assigned_values (info_copy);
123 /* Test remove attribute */
124 g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER));
125 g_file_info_set_attribute_int32 (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER, 10);
126 g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER));
128 g_assert_cmpint (g_file_info_get_attribute_type (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER), ==, G_FILE_ATTRIBUTE_TYPE_INT32);
129 g_assert_cmpint (g_file_info_get_attribute_status (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER), !=, G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING);
131 g_file_info_remove_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER);
132 g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER));
133 g_assert_cmpint (g_file_info_get_attribute_type (info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER), ==, G_FILE_ATTRIBUTE_TYPE_INVALID);
135 matcher = g_file_attribute_matcher_new (G_FILE_ATTRIBUTE_STANDARD_NAME ","
136 G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME);
138 g_assert_true (g_file_attribute_matcher_matches (matcher, G_FILE_ATTRIBUTE_STANDARD_NAME));
139 g_assert_false (g_file_attribute_matcher_matches_only (matcher, G_FILE_ATTRIBUTE_STANDARD_NAME));
140 g_assert_false (g_file_attribute_matcher_matches (matcher, G_FILE_ATTRIBUTE_STANDARD_SIZE));
142 g_file_info_set_attribute_mask (info, matcher);
143 g_file_attribute_matcher_unref (matcher);
145 g_assert_false (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_SIZE));
146 g_assert_true (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_NAME));
148 g_object_unref (info);
149 g_object_unref (info_dup);
150 g_object_unref (info_copy);
154 test_g_file_info_modification_time (void)
157 GFileIOStream *io_stream = NULL;
158 GFileInfo *info = NULL;
159 GDateTime *dt = NULL, *dt_usecs = NULL, *dt_new = NULL, *dt_new_usecs = NULL;
161 gboolean nsecs_supported;
164 GError *error = NULL;
166 g_test_summary ("Test that getting the modification time of a file works.");
168 file = g_file_new_tmp ("g-file-info-test-XXXXXX", &io_stream, &error);
169 g_assert_no_error (error);
171 info = g_file_query_info (file,
172 G_FILE_ATTRIBUTE_TIME_MODIFIED,
173 G_FILE_QUERY_INFO_NONE,
175 g_assert_no_error (error);
177 /* Check the modification time is retrievable. */
178 dt = g_file_info_get_modification_date_time (info);
179 g_assert_nonnull (dt);
181 /* Try again with microsecond precision. */
182 g_clear_object (&info);
183 info = g_file_query_info (file,
184 G_FILE_ATTRIBUTE_TIME_MODIFIED "," G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC,
185 G_FILE_QUERY_INFO_NONE,
187 g_assert_no_error (error);
189 dt_usecs = g_file_info_get_modification_date_time (info);
190 g_assert_nonnull (dt_usecs);
192 ts = g_date_time_difference (dt_usecs, dt);
193 g_assert_cmpint (ts, >=, 0);
194 g_assert_cmpint (ts, <, G_USEC_PER_SEC);
196 /* Try again with nanosecond precision. */
197 g_clear_object (&info);
198 info = g_file_query_info (file,
199 G_FILE_ATTRIBUTE_TIME_MODIFIED "," G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC "," G_FILE_ATTRIBUTE_TIME_MODIFIED_NSEC,
200 G_FILE_QUERY_INFO_NONE,
202 g_assert_no_error (error);
204 nsecs_supported = g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED_NSEC);
207 usecs = g_date_time_get_microsecond (dt_usecs);
208 nsecs = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED_NSEC);
210 g_assert_cmpuint (nsecs, >=, usecs * 1000);
211 g_assert_cmpuint (nsecs, <, (usecs + 1) * 1000);
214 /* Try round-tripping the modification time. */
215 dt_new = g_date_time_add (dt_usecs, G_USEC_PER_SEC + 50);
216 g_file_info_set_modification_date_time (info, dt_new);
218 dt_new_usecs = g_file_info_get_modification_date_time (info);
219 ts = g_date_time_difference (dt_new_usecs, dt_new);
220 g_assert_cmpint (ts, ==, 0);
222 /* Setting the modification time with usec-precision should have cleared nsecs. */
223 g_assert_cmpuint (g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED_NSEC), ==, 0);
225 /* Try setting the modification time with nsec-precision and it should set the
231 GDateTime *new_dt_usecs = NULL;
233 g_file_set_attribute_uint32 (file, G_FILE_ATTRIBUTE_TIME_MODIFIED_NSEC, nsecs + 100,
234 G_FILE_QUERY_INFO_NONE, NULL, &error);
235 g_assert_no_error (error);
237 g_clear_object (&info);
238 info = g_file_query_info (file,
239 G_FILE_ATTRIBUTE_TIME_MODIFIED "," G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC "," G_FILE_ATTRIBUTE_TIME_MODIFIED_NSEC,
240 G_FILE_QUERY_INFO_NONE,
242 g_assert_no_error (error);
244 new_dt_usecs = g_file_info_get_modification_date_time (info);
245 g_assert_nonnull (new_dt_usecs);
247 new_usecs = g_date_time_get_microsecond (new_dt_usecs);
248 new_nsecs = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED_NSEC);
250 g_assert_cmpuint (new_nsecs, ==, nsecs + 100);
251 g_assert_cmpuint (new_nsecs, >=, new_usecs * 1000);
252 g_assert_cmpuint (new_nsecs, <, (new_usecs + 1) * 1000);
254 g_date_time_unref (new_dt_usecs);
258 g_clear_object (&io_stream);
259 g_file_delete (file, NULL, NULL);
260 g_clear_object (&file);
262 g_clear_object (&info);
263 g_date_time_unref (dt);
264 g_date_time_unref (dt_usecs);
265 g_date_time_unref (dt_new);
266 g_date_time_unref (dt_new_usecs);
270 test_g_file_info_access_time (void)
273 GFileIOStream *io_stream = NULL;
274 GFileInfo *info = NULL;
275 GDateTime *dt = NULL, *dt_usecs = NULL, *dt_new = NULL, *dt_new_usecs = NULL,
276 *dt_before_epoch = NULL, *dt_before_epoch_returned = NULL;
278 gboolean nsecs_supported;
281 GError *error = NULL;
283 g_test_summary ("Test that getting the access time of a file works.");
285 file = g_file_new_tmp ("g-file-info-test-XXXXXX", &io_stream, &error);
286 g_assert_no_error (error);
288 info = g_file_query_info (file,
289 G_FILE_ATTRIBUTE_TIME_ACCESS,
290 G_FILE_QUERY_INFO_NONE,
292 g_assert_no_error (error);
294 if (!g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_ACCESS))
296 g_test_skip ("Skipping testing access time as it’s not supported by the kernel");
297 g_file_delete (file, NULL, NULL);
298 g_clear_object (&file);
299 g_clear_object (&info);
303 /* Check the access time is retrievable. */
304 dt = g_file_info_get_access_date_time (info);
305 g_assert_nonnull (dt);
307 /* Try again with microsecond precision. */
308 g_clear_object (&info);
309 info = g_file_query_info (file,
310 G_FILE_ATTRIBUTE_TIME_ACCESS "," G_FILE_ATTRIBUTE_TIME_ACCESS_USEC,
311 G_FILE_QUERY_INFO_NONE,
313 g_assert_no_error (error);
315 dt_usecs = g_file_info_get_access_date_time (info);
316 g_assert_nonnull (dt_usecs);
318 ts = g_date_time_difference (dt_usecs, dt);
319 g_assert_cmpint (ts, >=, 0);
320 g_assert_cmpint (ts, <, G_USEC_PER_SEC);
322 /* Try again with nanosecond precision. */
323 g_clear_object (&info);
324 info = g_file_query_info (file,
325 G_FILE_ATTRIBUTE_TIME_ACCESS "," G_FILE_ATTRIBUTE_TIME_ACCESS_USEC "," G_FILE_ATTRIBUTE_TIME_ACCESS_NSEC,
326 G_FILE_QUERY_INFO_NONE,
328 g_assert_no_error (error);
330 nsecs_supported = g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_ACCESS_NSEC);
333 usecs = g_date_time_get_microsecond (dt_usecs);
334 nsecs = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_ACCESS_NSEC);
336 g_assert_cmpuint (nsecs, >=, usecs * 1000);
337 g_assert_cmpuint (nsecs, <, (usecs + 1) * 1000);
340 /* Try round-tripping the access time. */
341 dt_new = g_date_time_add (dt_usecs, G_USEC_PER_SEC + 50);
342 g_file_info_set_access_date_time (info, dt_new);
344 dt_new_usecs = g_file_info_get_access_date_time (info);
345 ts = g_date_time_difference (dt_new_usecs, dt_new);
346 g_assert_cmpint (ts, ==, 0);
348 // try with a negative timestamp
349 dt_before_epoch = g_date_time_new_from_unix_utc (-10000);
350 g_file_info_set_access_date_time (info, dt_before_epoch);
351 dt_before_epoch_returned = g_file_info_get_access_date_time (info);
352 ts = g_date_time_difference (dt_before_epoch, dt_before_epoch_returned);
353 g_assert_cmpint (ts, ==, 0);
355 /* Setting the access time with usec-precision should have cleared nsecs. */
356 g_assert_cmpuint (g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_ACCESS_NSEC), ==, 0);
358 /* Try setting the access time with nsec-precision and it should set the
364 GDateTime *new_dt_usecs = NULL;
366 g_file_set_attribute_uint32 (file, G_FILE_ATTRIBUTE_TIME_ACCESS_NSEC, nsecs + 100,
367 G_FILE_QUERY_INFO_NONE, NULL, &error);
368 g_assert_no_error (error);
370 g_clear_object (&info);
371 info = g_file_query_info (file,
372 G_FILE_ATTRIBUTE_TIME_ACCESS "," G_FILE_ATTRIBUTE_TIME_ACCESS_USEC "," G_FILE_ATTRIBUTE_TIME_ACCESS_NSEC,
373 G_FILE_QUERY_INFO_NONE,
375 g_assert_no_error (error);
377 new_dt_usecs = g_file_info_get_access_date_time (info);
378 g_assert_nonnull (new_dt_usecs);
380 new_usecs = g_date_time_get_microsecond (new_dt_usecs);
381 new_nsecs = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_ACCESS_NSEC);
383 g_assert_cmpuint (new_nsecs, ==, nsecs + 100);
384 g_assert_cmpuint (new_nsecs, >=, new_usecs * 1000);
385 g_assert_cmpuint (new_nsecs, <, (new_usecs + 1) * 1000);
387 g_date_time_unref (new_dt_usecs);
391 g_clear_object (&io_stream);
392 g_file_delete (file, NULL, NULL);
393 g_clear_object (&file);
395 g_clear_object (&info);
396 g_date_time_unref (dt);
397 g_date_time_unref (dt_usecs);
398 g_date_time_unref (dt_new);
399 g_date_time_unref (dt_new_usecs);
400 g_date_time_unref (dt_before_epoch);
401 g_date_time_unref (dt_before_epoch_returned);
405 test_g_file_info_creation_time (void)
408 GFileIOStream *io_stream = NULL;
409 GFileInfo *info = NULL;
410 GDateTime *dt = NULL, *dt_usecs = NULL, *dt_new = NULL, *dt_new_usecs = NULL,
411 *dt_before_epoch = NULL, *dt_before_epoch_returned = NULL;
413 gboolean nsecs_supported;
416 GError *error = NULL;
418 g_test_summary ("Test that getting the creation time of a file works.");
420 file = g_file_new_tmp ("g-file-info-test-XXXXXX", &io_stream, &error);
421 g_assert_no_error (error);
423 info = g_file_query_info (file,
424 G_FILE_ATTRIBUTE_TIME_CREATED,
425 G_FILE_QUERY_INFO_NONE,
427 g_assert_no_error (error);
429 if (!g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_CREATED))
431 g_test_skip ("Skipping testing creation time as it’s not supported by the kernel");
432 g_clear_object (&io_stream);
433 g_file_delete (file, NULL, NULL);
434 g_clear_object (&file);
435 g_clear_object (&info);
439 /* Check the creation time is retrievable. */
440 dt = g_file_info_get_creation_date_time (info);
442 /* Try again with microsecond precision. */
443 g_clear_object (&info);
444 info = g_file_query_info (file,
445 G_FILE_ATTRIBUTE_TIME_CREATED "," G_FILE_ATTRIBUTE_TIME_CREATED_USEC,
446 G_FILE_QUERY_INFO_NONE,
448 g_assert_no_error (error);
450 dt_usecs = g_file_info_get_creation_date_time (info);
451 g_assert_nonnull (dt_usecs);
453 ts = g_date_time_difference (dt_usecs, dt);
454 g_assert_cmpint (ts, >=, 0);
455 g_assert_cmpint (ts, <, G_USEC_PER_SEC);
457 /* Try again with nanosecond precision. */
458 g_clear_object (&info);
459 info = g_file_query_info (file,
460 G_FILE_ATTRIBUTE_TIME_CREATED "," G_FILE_ATTRIBUTE_TIME_CREATED_USEC "," G_FILE_ATTRIBUTE_TIME_CREATED_NSEC,
461 G_FILE_QUERY_INFO_NONE,
463 g_assert_no_error (error);
465 nsecs_supported = g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_TIME_CREATED_NSEC);
468 usecs = g_date_time_get_microsecond (dt_usecs);
469 nsecs = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_CREATED_NSEC);
471 g_assert_cmpuint (nsecs, >=, usecs * 1000);
472 g_assert_cmpuint (nsecs, <, (usecs + 1) * 1000);
475 /* Try round-tripping the creation time. */
476 dt_new = g_date_time_add (dt_usecs, G_USEC_PER_SEC + 50);
477 g_file_info_set_creation_date_time (info, dt_new);
479 dt_new_usecs = g_file_info_get_creation_date_time (info);
480 ts = g_date_time_difference (dt_new_usecs, dt_new);
481 g_assert_cmpint (ts, ==, 0);
483 // try with a negative timestamp
484 dt_before_epoch = g_date_time_new_from_unix_utc (-10000);
485 g_file_info_set_creation_date_time (info, dt_before_epoch);
486 dt_before_epoch_returned = g_file_info_get_creation_date_time (info);
487 ts = g_date_time_difference (dt_before_epoch, dt_before_epoch_returned);
488 g_assert_cmpint (ts, ==, 0);
490 /* Setting the creation time with usec-precision should have cleared nsecs. */
491 g_assert_cmpuint (g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_CREATED_NSEC), ==, 0);
493 /* Try setting the creation time with nsec-precision and it should set the
499 GDateTime *new_dt_usecs = NULL;
501 /* This can fail on some platforms, even if reading CREATED_NSEC works */
502 g_file_set_attribute_uint32 (file, G_FILE_ATTRIBUTE_TIME_CREATED_NSEC, nsecs + 100,
503 G_FILE_QUERY_INFO_NONE, NULL, &error);
506 g_clear_object (&info);
507 info = g_file_query_info (file,
508 G_FILE_ATTRIBUTE_TIME_CREATED "," G_FILE_ATTRIBUTE_TIME_CREATED_USEC "," G_FILE_ATTRIBUTE_TIME_CREATED_NSEC,
509 G_FILE_QUERY_INFO_NONE,
511 g_assert_no_error (error);
513 new_dt_usecs = g_file_info_get_creation_date_time (info);
514 g_assert_nonnull (new_dt_usecs);
516 new_usecs = g_date_time_get_microsecond (new_dt_usecs);
517 new_nsecs = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_CREATED_NSEC);
519 g_assert_cmpuint (new_nsecs, ==, nsecs + 100);
520 g_assert_cmpuint (new_nsecs, >=, new_usecs * 1000);
521 g_assert_cmpuint (new_nsecs, <, (new_usecs + 1) * 1000);
523 g_date_time_unref (new_dt_usecs);
527 if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
528 g_clear_error (&error);
529 g_assert_no_error (error);
534 g_clear_object (&io_stream);
535 g_file_delete (file, NULL, NULL);
536 g_clear_object (&file);
538 g_clear_object (&info);
539 g_date_time_unref (dt);
540 g_date_time_unref (dt_usecs);
541 g_date_time_unref (dt_new);
542 g_date_time_unref (dt_new_usecs);
543 g_date_time_unref (dt_before_epoch);
544 g_date_time_unref (dt_before_epoch_returned);
549 test_internal_enhanced_stdio (void)
554 wchar_t *tmp_dir_root_w;
561 GStatBuf statbuf_p0, statbuf_p1, statbuf_ps;
562 GFile *gf_p0, *gf_p1, *gf_ps;
563 GFileInfo *fi_p0, *fi_p1, *fi_ps;
564 guint64 size_p0, alsize_p0, size_ps, alsize_ps;
569 wchar_t *programdata_dir_w;
570 wchar_t *users_dir_w;
571 static const GUID folder_id_programdata =
572 { 0x62AB5D82, 0xFDC1, 0x4DC3, { 0xA9, 0xDD, 0x07, 0x0D, 0x1D, 0x49, 0x5D, 0x97 } };
573 static const GUID folder_id_users =
574 { 0x0762D272, 0xC50A, 0x4BB0, { 0xA3, 0x82, 0x69, 0x7D, 0xCD, 0x72, 0x9B, 0x80 } };
575 GDateTime *dt = NULL, *dt2 = NULL;
577 /* Just before SYSTEMTIME limit (Jan 1 30827) */
578 const gint64 one_sec_before_systemtime_limit = 910670515199;
580 GError *local_error = NULL;
583 programdata_dir_w = NULL;
584 SHGetKnownFolderPath (&folder_id_programdata, 0, NULL, &programdata_dir_w);
587 SHGetKnownFolderPath (&folder_id_users, 0, NULL, &users_dir_w);
589 if (programdata_dir_w != NULL && users_dir_w != NULL)
595 GFile *gf_programdata, *gf_allusers, *gf_commondata;
596 GFileInfo *fi_programdata, *fi_allusers, *fi_allusers_target, *fi_commondata, *fi_commondata_target;
597 GFileType ft_allusers;
598 GFileType ft_allusers_target;
599 GFileType ft_programdata;
600 GFileType ft_commondata;
601 gboolean allusers_is_symlink;
602 gboolean commondata_is_symlink;
603 gboolean commondata_is_mount_point;
604 guint32 allusers_reparse_tag;
605 guint32 commondata_reparse_tag;
606 const gchar *id_allusers;
607 const gchar *id_allusers_target;
608 const gchar *id_commondata_target;
609 const gchar *id_programdata;
610 const gchar *allusers_target;
611 const gchar *commondata_target;
614 programdata = g_utf16_to_utf8 (programdata_dir_w, -1, NULL, NULL, NULL);
615 g_assert_nonnull (programdata);
617 users_dir = g_utf16_to_utf8 (users_dir_w, -1, NULL, NULL, NULL);
618 g_assert_nonnull (users_dir);
619 /* "C:/Users/All Users" is a known directory symlink
620 * for "C:/ProgramData".
622 allusers = g_build_filename (users_dir, "All Users", NULL);
624 /* "C:/Users/All Users/Application Data" is a known
625 * junction for "C:/ProgramData"
627 commondata = g_build_filename (allusers, "Application Data", NULL);
629 /* We don't test g_stat() and g_lstat() on these directories,
630 * because it is pointless - there's no way to tell that these
631 * functions behave correctly in this case
632 * (st_ino is useless, so we can't tell apart g_stat() and g_lstat()
633 * results; st_mode is also useless as it does not support S_ISLNK;
634 * and these directories have no interesting properties other
635 * than [not] being symlinks).
637 gf_programdata = g_file_new_for_path (programdata);
638 gf_allusers = g_file_new_for_path (allusers);
639 gf_commondata = g_file_new_for_path (commondata);
641 fi_programdata = g_file_query_info (gf_programdata,
642 G_FILE_ATTRIBUTE_ID_FILE ","
643 G_FILE_ATTRIBUTE_STANDARD_TYPE,
644 G_FILE_QUERY_INFO_NONE,
647 fi_allusers_target = g_file_query_info (gf_allusers,
648 G_FILE_ATTRIBUTE_ID_FILE ","
649 G_FILE_ATTRIBUTE_STANDARD_TYPE,
650 G_FILE_QUERY_INFO_NONE,
653 fi_allusers = g_file_query_info (gf_allusers,
654 G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET ","
655 G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK ","
656 G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG ","
657 G_FILE_ATTRIBUTE_ID_FILE ","
658 G_FILE_ATTRIBUTE_STANDARD_TYPE,
659 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
662 fi_commondata = g_file_query_info (gf_commondata,
663 G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET ","
664 G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK ","
665 G_FILE_ATTRIBUTE_DOS_IS_MOUNTPOINT ","
666 G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG ","
667 G_FILE_ATTRIBUTE_ID_FILE ","
668 G_FILE_ATTRIBUTE_STANDARD_TYPE,
669 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
672 fi_commondata_target = g_file_query_info (gf_commondata,
673 G_FILE_ATTRIBUTE_ID_FILE ","
674 G_FILE_ATTRIBUTE_STANDARD_TYPE,
675 G_FILE_QUERY_INFO_NONE,
678 g_assert_true (g_file_info_has_attribute (fi_programdata, G_FILE_ATTRIBUTE_ID_FILE));
679 g_assert_true (g_file_info_has_attribute (fi_programdata, G_FILE_ATTRIBUTE_STANDARD_TYPE));
681 g_assert_true (g_file_info_has_attribute (fi_allusers_target, G_FILE_ATTRIBUTE_ID_FILE));
682 g_assert_true (g_file_info_has_attribute (fi_allusers_target, G_FILE_ATTRIBUTE_STANDARD_TYPE));
683 g_assert_true (g_file_info_has_attribute (fi_commondata_target, G_FILE_ATTRIBUTE_ID_FILE));
684 g_assert_true (g_file_info_has_attribute (fi_commondata_target, G_FILE_ATTRIBUTE_STANDARD_TYPE));
686 g_assert_true (g_file_info_has_attribute (fi_allusers, G_FILE_ATTRIBUTE_ID_FILE));
687 g_assert_true (g_file_info_has_attribute (fi_allusers, G_FILE_ATTRIBUTE_STANDARD_TYPE));
688 g_assert_true (g_file_info_has_attribute (fi_allusers, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK));
689 g_assert_true (g_file_info_has_attribute (fi_allusers, G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG));
690 g_assert_true (g_file_info_has_attribute (fi_allusers, G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET));
692 g_assert_true (g_file_info_has_attribute (fi_commondata, G_FILE_ATTRIBUTE_ID_FILE));
693 g_assert_true (g_file_info_has_attribute (fi_commondata, G_FILE_ATTRIBUTE_STANDARD_TYPE));
694 g_assert_true (g_file_info_has_attribute (fi_commondata, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK));
695 g_assert_true (g_file_info_has_attribute (fi_commondata, G_FILE_ATTRIBUTE_DOS_IS_MOUNTPOINT));
696 g_assert_true (g_file_info_has_attribute (fi_commondata, G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG));
697 g_assert_true (g_file_info_has_attribute (fi_commondata, G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET));
699 ft_allusers = g_file_info_get_file_type (fi_allusers);
700 ft_allusers_target = g_file_info_get_file_type (fi_allusers_target);
701 ft_programdata = g_file_info_get_file_type (fi_programdata);
702 ft_commondata = g_file_info_get_file_type (fi_commondata);
704 g_assert_cmpint (ft_allusers, ==, G_FILE_TYPE_DIRECTORY);
705 g_assert_cmpint (ft_allusers_target, ==, G_FILE_TYPE_DIRECTORY);
706 g_assert_cmpint (ft_programdata, ==, G_FILE_TYPE_DIRECTORY);
707 g_assert_cmpint (ft_commondata, ==, G_FILE_TYPE_DIRECTORY);
709 allusers_is_symlink = g_file_info_get_attribute_boolean (fi_allusers, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK);
710 allusers_reparse_tag = g_file_info_get_attribute_uint32 (fi_allusers, G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG);
711 commondata_is_symlink = g_file_info_get_attribute_boolean (fi_commondata, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK);
712 commondata_is_mount_point = g_file_info_get_attribute_boolean (fi_commondata, G_FILE_ATTRIBUTE_DOS_IS_MOUNTPOINT);
713 commondata_reparse_tag = g_file_info_get_attribute_uint32 (fi_commondata, G_FILE_ATTRIBUTE_DOS_REPARSE_POINT_TAG);
715 g_assert_true (allusers_is_symlink);
716 g_assert_cmpuint (allusers_reparse_tag, ==, IO_REPARSE_TAG_SYMLINK);
717 g_assert_true (commondata_is_symlink);
718 g_assert_true (commondata_is_mount_point);
719 g_assert_cmpuint (commondata_reparse_tag, ==, IO_REPARSE_TAG_MOUNT_POINT);
721 id_allusers = g_file_info_get_attribute_string (fi_allusers, G_FILE_ATTRIBUTE_ID_FILE);
722 id_allusers_target = g_file_info_get_attribute_string (fi_allusers_target, G_FILE_ATTRIBUTE_ID_FILE);
723 id_commondata_target = g_file_info_get_attribute_string (fi_commondata_target, G_FILE_ATTRIBUTE_ID_FILE);
724 id_programdata = g_file_info_get_attribute_string (fi_programdata, G_FILE_ATTRIBUTE_ID_FILE);
726 g_assert_cmpstr (id_allusers_target, ==, id_programdata);
727 g_assert_cmpstr (id_commondata_target, ==, id_programdata);
728 g_assert_cmpstr (id_allusers, !=, id_programdata);
730 allusers_target = g_file_info_get_symlink_target (fi_allusers);
732 g_assert_true (g_str_has_suffix (allusers_target, "ProgramData"));
734 commondata_target = g_file_info_get_symlink_target (fi_commondata);
736 g_assert_true (g_str_has_suffix (commondata_target, "ProgramData"));
738 g_object_unref (fi_allusers);
739 g_object_unref (fi_allusers_target);
740 g_object_unref (fi_commondata);
741 g_object_unref (fi_commondata_target);
742 g_object_unref (fi_programdata);
743 g_object_unref (gf_allusers);
744 g_object_unref (gf_commondata);
745 g_object_unref (gf_programdata);
750 g_free (programdata);
753 if (programdata_dir_w)
754 CoTaskMemFree (programdata_dir_w);
757 CoTaskMemFree (users_dir_w);
759 tmp_dir = g_dir_make_tmp ("glib_stdio_testXXXXXX", NULL);
760 g_assert_nonnull (tmp_dir);
762 /* Technically, this isn't necessary - we already assume NTFS, because of
763 * symlink support, and NTFS also supports sparse files. Still, given
764 * the amount of unusual I/O APIs called in this test, checking for
765 * sparse file support of the filesystem where temp directory is
766 * doesn't seem to be out of place.
769 tmp_dir_root = g_strdup (tmp_dir);
770 /* We need "C:\\" or "C:/", with a trailing [back]slash */
771 for (c = tmp_dir_root; c && c[0] && c[1]; c++)
777 tmp_dir_root_w = g_utf8_to_utf16 (tmp_dir_root, -1, NULL, NULL, NULL);
778 g_assert_nonnull (tmp_dir_root_w);
779 g_free (tmp_dir_root);
780 g_assert_true (GetVolumeInformationW (tmp_dir_root_w, NULL, 0, NULL, NULL, &fsflags, NULL, 0));
781 g_free (tmp_dir_root_w);
782 try_sparse = (fsflags & FILE_SUPPORTS_SPARSE_FILES) == FILE_SUPPORTS_SPARSE_FILES;
784 p0 = g_build_filename (tmp_dir, "zool", NULL);
785 p1 = g_build_filename (tmp_dir, "looz", NULL);
786 ps = g_build_filename (tmp_dir, "sparse", NULL);
790 FILE_SET_SPARSE_BUFFER ssb;
791 FILE_ZERO_DATA_INFORMATION zdi;
795 f = g_fopen (ps, "wb");
796 g_assert_nonnull (f);
798 h = (HANDLE) _get_osfhandle (fileno (f));
799 g_assert_cmpuint ((guintptr) h, !=, (guintptr) INVALID_HANDLE_VALUE);
801 ssb.SetSparse = TRUE;
802 g_assert_true (DeviceIoControl (h,
805 NULL, 0, NULL, NULL));
807 /* Make it a sparse file that starts with 4GBs of zeros */
808 zdi.FileOffset.QuadPart = 0;
809 zdi.BeyondFinalZero.QuadPart = 0xFFFFFFFFULL + 1;
810 g_assert_true (DeviceIoControl (h,
813 NULL, 0, NULL, NULL));
815 /* Let's not keep this seemingly 4GB monster around
816 * longer than we absolutely need to. Do all operations
817 * without assertions, then remove the file immediately.
819 _fseeki64 (f, 0xFFFFFFFFULL, SEEK_SET);
820 fprintf (f, "Hello 4GB World!");
824 memset (&statbuf_ps, 0, sizeof (statbuf_ps));
826 g_stat (ps, &statbuf_ps);
828 gf_ps = g_file_new_for_path (ps);
830 fi_ps = g_file_query_info (gf_ps,
831 G_FILE_ATTRIBUTE_STANDARD_SIZE ","
832 G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE,
833 G_FILE_QUERY_INFO_NONE,
838 g_assert_true (g_file_info_has_attribute (fi_ps, G_FILE_ATTRIBUTE_STANDARD_SIZE));
839 g_assert_true (g_file_info_has_attribute (fi_ps, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE));
841 size_ps = g_file_info_get_attribute_uint64 (fi_ps, G_FILE_ATTRIBUTE_STANDARD_SIZE);
842 alsize_ps = g_file_info_get_attribute_uint64 (fi_ps, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE);
844 /* allocated size should small (usually - size of the FS cluster,
845 * let's assume it's less than 1 gigabyte),
846 * size should be more than 4 gigabytes,
847 * st_size should not exceed its 0xFFFFFFFF 32-bit limit,
848 * and should be nonzero (this also detects a failed g_stat() earlier).
850 g_assert_cmpuint (alsize_ps, <, 0x40000000);
851 g_assert_cmpuint (size_ps, >, G_GUINT64_CONSTANT (0xFFFFFFFF));
852 g_assert_cmpuint (statbuf_ps.st_size, >, 0);
854 g_assert_cmpuint (statbuf_ps.st_size, ==, G_GUINT64_CONSTANT (0x10000000f));
856 g_assert_cmpuint (statbuf_ps.st_size, <=, 0xFFFFFFFF);
859 g_object_unref (fi_ps);
860 g_object_unref (gf_ps);
863 /* Wa-a-ay past 02/07/2106 @ 6:28am (UTC),
864 * which is the date corresponding to 0xFFFFFFFF + 1.
865 * This is easier to check than Y2038 (0x80000000 + 1),
866 * since there's no need to worry about signedness this way.
874 st.wMilliseconds = 0;
876 g_assert_true (SystemTimeToFileTime (&st, &ft));
878 f = g_fopen (p0, "w");
879 g_assert_nonnull (f);
881 h = (HANDLE) _get_osfhandle (fileno (f));
882 g_assert_cmpuint ((guintptr) h, !=, (guintptr) INVALID_HANDLE_VALUE);
887 g_assert_true (SetFileTime (h, &ft, &ft, &ft));
891 f = g_fopen (p1, "w");
892 g_assert_nonnull (f);
896 memset (&statbuf_p0, 0, sizeof (statbuf_p0));
897 memset (&statbuf_p1, 0, sizeof (statbuf_p1));
899 g_assert_cmpint (g_stat (p0, &statbuf_p0), ==, 0);
900 g_assert_cmpint (g_stat (p1, &statbuf_p1), ==, 0);
902 gf_p0 = g_file_new_for_path (p0);
903 gf_p1 = g_file_new_for_path (p1);
905 fi_p0 = g_file_query_info (gf_p0,
906 G_FILE_ATTRIBUTE_STANDARD_SIZE ","
907 G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE ","
908 G_FILE_ATTRIBUTE_ID_FILE ","
909 G_FILE_ATTRIBUTE_TIME_MODIFIED ","
910 G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC ","
911 G_FILE_ATTRIBUTE_TIME_MODIFIED_NSEC,
912 G_FILE_QUERY_INFO_NONE,
915 fi_p1 = g_file_query_info (gf_p1,
916 G_FILE_ATTRIBUTE_STANDARD_SIZE ","
917 G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE ","
918 G_FILE_ATTRIBUTE_ID_FILE ","
919 G_FILE_ATTRIBUTE_TIME_MODIFIED ","
920 G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC ","
921 G_FILE_ATTRIBUTE_TIME_MODIFIED_NSEC,
922 G_FILE_QUERY_INFO_NONE,
925 g_assert_true (g_file_info_has_attribute (fi_p0, G_FILE_ATTRIBUTE_STANDARD_SIZE));
926 g_assert_true (g_file_info_has_attribute (fi_p0, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE));
927 g_assert_true (g_file_info_has_attribute (fi_p0, G_FILE_ATTRIBUTE_ID_FILE));
928 g_assert_true (g_file_info_has_attribute (fi_p0, G_FILE_ATTRIBUTE_TIME_MODIFIED));
929 g_assert_true (g_file_info_has_attribute (fi_p0, G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC));
930 g_assert_true (g_file_info_has_attribute (fi_p0, G_FILE_ATTRIBUTE_TIME_MODIFIED_NSEC));
932 g_assert_true (g_file_info_has_attribute (fi_p1, G_FILE_ATTRIBUTE_STANDARD_SIZE));
933 g_assert_true (g_file_info_has_attribute (fi_p1, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE));
934 g_assert_true (g_file_info_has_attribute (fi_p1, G_FILE_ATTRIBUTE_ID_FILE));
935 g_assert_true (g_file_info_has_attribute (fi_p1, G_FILE_ATTRIBUTE_TIME_MODIFIED));
936 g_assert_true (g_file_info_has_attribute (fi_p1, G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC));
937 g_assert_true (g_file_info_has_attribute (fi_p1, G_FILE_ATTRIBUTE_TIME_MODIFIED_NSEC));
939 size_p0 = g_file_info_get_attribute_uint64 (fi_p0, G_FILE_ATTRIBUTE_STANDARD_SIZE);
940 alsize_p0 = g_file_info_get_attribute_uint64 (fi_p0, G_FILE_ATTRIBUTE_STANDARD_ALLOCATED_SIZE);
942 /* size should be 1, allocated size should be something else
943 * (could be 0 or the size of the FS cluster, but never 1).
945 g_assert_cmpuint (size_p0, ==, statbuf_p0.st_size);
946 g_assert_cmpuint (size_p0, ==, 1);
947 g_assert_cmpuint (alsize_p0, !=, size_p0);
949 id_p0 = g_file_info_get_attribute_string (fi_p0, G_FILE_ATTRIBUTE_ID_FILE);
950 id_p1 = g_file_info_get_attribute_string (fi_p1, G_FILE_ATTRIBUTE_ID_FILE);
952 /* st_ino from W32 stat() is useless for file identification.
953 * It will be either 0, or it will be the same for both files.
955 g_assert_cmpint (statbuf_p0.st_ino, ==, statbuf_p1.st_ino);
956 g_assert_cmpstr (id_p0, !=, id_p1);
958 time_p0 = g_file_info_get_attribute_uint64 (fi_p0, G_FILE_ATTRIBUTE_TIME_MODIFIED);
960 /* Check that GFileInfo doesn't suffer from Y2106 problem.
961 * Don't check stat(), as its contents may vary depending on
962 * the host platform architecture
963 * (time fields are 32-bit on 32-bit Windows,
964 * and 64-bit on 64-bit Windows, usually),
965 * so it *can* pass this test in some cases.
967 g_assert_cmpuint (time_p0, >, G_GUINT64_CONSTANT (0xFFFFFFFF));
969 dt = g_file_info_get_modification_date_time (fi_p0);
970 g_assert_nonnull (dt);
971 dt2 = g_date_time_add (dt, G_USEC_PER_SEC / 100 * 200);
972 g_object_unref (fi_p0);
973 fi_p0 = g_file_info_new ();
974 g_file_info_set_modification_date_time (fi_p0, dt2);
976 g_assert_true (g_file_set_attributes_from_info (gf_p0,
978 G_FILE_QUERY_INFO_NONE,
981 g_date_time_unref (dt2);
982 g_object_unref (fi_p0);
983 fi_p0 = g_file_query_info (gf_p0,
984 G_FILE_ATTRIBUTE_TIME_MODIFIED ","
985 G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC ","
986 G_FILE_ATTRIBUTE_TIME_MODIFIED_NSEC,
987 G_FILE_QUERY_INFO_NONE,
989 dt2 = g_file_info_get_modification_date_time (fi_p0);
990 ts = g_date_time_difference (dt2, dt);
991 g_assert_cmpint (ts, >, 0);
992 g_assert_cmpint (ts, <, G_USEC_PER_SEC / 100 * 300);
994 g_date_time_unref (dt);
995 g_date_time_unref (dt2);
997 g_file_info_set_attribute_uint64 (fi_p0,
998 G_FILE_ATTRIBUTE_TIME_MODIFIED,
999 one_sec_before_systemtime_limit);
1000 g_file_info_set_attribute_uint32 (fi_p0, G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC, 0);
1001 g_assert_true (g_file_set_attributes_from_info (gf_p0,
1003 G_FILE_QUERY_INFO_NONE,
1007 g_file_info_set_attribute_uint64 (fi_p0,
1008 G_FILE_ATTRIBUTE_TIME_MODIFIED,
1009 one_sec_before_systemtime_limit + G_USEC_PER_SEC * 2);
1010 g_file_info_set_attribute_uint32 (fi_p0, G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC, 0);
1011 retval = g_file_set_attributes_from_info (gf_p0,
1013 G_FILE_QUERY_INFO_NONE,
1016 g_assert_error (local_error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA);
1017 g_assert_false (retval);
1018 g_clear_error (&local_error);
1020 g_object_unref (fi_p0);
1021 g_object_unref (fi_p1);
1022 g_object_unref (gf_p0);
1023 g_object_unref (gf_p1);
1036 GFileIOStream *stream = NULL;
1037 GFileInfo *file_info0 = NULL, *file_info1 = NULL, *file_info2 = NULL;
1038 GError *local_error = NULL;
1040 g_test_summary ("Test setting and getting escaped xattrs");
1042 /* Create a temporary file; no need to write anything to it. */
1043 file = g_file_new_tmp ("g-file-info-test-xattrs-XXXXXX", &stream, &local_error);
1044 g_assert_no_error (local_error);
1045 g_assert_nonnull (file);
1047 g_io_stream_close (G_IO_STREAM (stream), NULL, NULL);
1048 g_object_unref (stream);
1050 /* Check the existing xattrs. */
1051 file_info0 = g_file_query_info (file, "xattr::*", G_FILE_QUERY_INFO_NONE, NULL, &local_error);
1052 g_assert_no_error (local_error);
1053 g_assert_nonnull (file_info0);
1055 /* Set some new xattrs, with escaping and some embedded nuls. */
1056 g_file_info_set_attribute_string (file_info0, "xattr::escaped", "hello\\x82\\x80\\xbd");
1057 g_file_info_set_attribute_string (file_info0, "xattr::string", "hi there");
1058 g_file_info_set_attribute_string (file_info0, "xattr::embedded-nul", "hi\\x00there");
1059 g_file_info_set_attribute_string (file_info0, "xattr::deleteme", "this attribute will be deleted");
1061 g_file_set_attributes_from_info (file, file_info0, G_FILE_QUERY_INFO_NONE, NULL, &local_error);
1063 g_object_unref (file_info0);
1065 if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
1067 g_test_skip ("xattrs not supported on this file system");
1068 g_clear_error (&local_error);
1072 g_assert_no_error (local_error);
1074 /* Check they were set properly. */
1075 file_info1 = g_file_query_info (file, "xattr::*", G_FILE_QUERY_INFO_NONE, NULL, &local_error);
1076 g_assert_no_error (local_error);
1077 g_assert_nonnull (file_info1);
1079 g_assert_true (g_file_info_has_namespace (file_info1, "xattr"));
1081 g_assert_cmpstr (g_file_info_get_attribute_string (file_info1, "xattr::escaped"), ==, "hello\\x82\\x80\\xbd");
1082 g_assert_cmpstr (g_file_info_get_attribute_string (file_info1, "xattr::string"), ==, "hi there");
1083 g_assert_cmpstr (g_file_info_get_attribute_string (file_info1, "xattr::embedded-nul"), ==, "hi\\x00there");
1084 g_assert_cmpstr (g_file_info_get_attribute_string (file_info1, "xattr::deleteme"), ==, "this attribute will be deleted");
1086 g_object_unref (file_info1);
1088 /* Check whether removing extended attributes works. */
1089 g_file_set_attribute (file, "xattr::deleteme", G_FILE_ATTRIBUTE_TYPE_INVALID, NULL, G_FILE_QUERY_INFO_NONE, NULL, &local_error);
1090 g_assert_no_error (local_error);
1091 file_info2 = g_file_query_info (file, "xattr::deleteme", G_FILE_QUERY_INFO_NONE, NULL, &local_error);
1092 g_assert_no_error (local_error);
1093 g_assert_nonnull (file_info2);
1094 g_assert_cmpstr (g_file_info_get_attribute_string (file_info2, "xattr::deleteme"), ==, NULL);
1096 g_object_unref (file_info2);
1100 g_file_delete (file, NULL, NULL);
1102 g_object_unref (file);
1106 test_set_modified_date_time_precision (void)
1108 GDateTime *modified = NULL;
1110 GFileIOStream *stream = NULL;
1111 GFileInfo *info = NULL;
1112 GError *local_error = NULL;
1115 g_test_summary ("Test that g_file_info_set_modified_date_time() preserves microseconds");
1116 g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/3116");
1118 file = g_file_new_tmp ("g-file-info-test-set-modified-date-time-precision-XXXXXX", &stream, &local_error);
1119 g_assert_no_error (local_error);
1121 modified = g_date_time_new_from_iso8601 ("2000-01-01T00:00:00.123456Z", NULL);
1123 info = g_file_query_info (file,
1124 G_FILE_ATTRIBUTE_TIME_MODIFIED ","
1125 G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC ","
1126 G_FILE_ATTRIBUTE_TIME_MODIFIED_NSEC, G_FILE_QUERY_INFO_NONE, NULL, &local_error);
1127 g_assert_no_error (local_error);
1129 g_file_info_set_modification_date_time (info, modified);
1130 g_assert_true (g_file_set_attributes_from_info (file, info, G_FILE_QUERY_INFO_NONE, NULL, &local_error));
1131 g_assert_no_error (local_error);
1133 g_clear_object (&info);
1134 g_clear_pointer (&modified, g_date_time_unref);
1136 info = g_file_query_info (file,
1137 G_FILE_ATTRIBUTE_TIME_MODIFIED ","
1138 G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC ","
1139 G_FILE_ATTRIBUTE_TIME_MODIFIED_NSEC, G_FILE_QUERY_INFO_NONE, NULL, &local_error);
1140 g_assert_no_error (local_error);
1142 g_assert_cmpuint (g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC), ==, 123456);
1144 g_clear_object (&stream);
1145 g_clear_object (&info);
1146 g_clear_object (&file);
1153 g_test_init (&argc, &argv, NULL);
1155 g_test_add_func ("/g-file-info/test_g_file_info", test_g_file_info);
1156 g_test_add_func ("/g-file-info/test_g_file_info/modification-time", test_g_file_info_modification_time);
1157 g_test_add_func ("/g-file-info/test_g_file_info/access-time", test_g_file_info_access_time);
1158 g_test_add_func ("/g-file-info/test_g_file_info/creation-time", test_g_file_info_creation_time);
1160 g_test_add_func ("/g-file-info/internal-enhanced-stdio", test_internal_enhanced_stdio);
1162 g_test_add_func ("/g-file-info/xattrs", test_xattrs);
1163 g_test_add_func ("/g-file-info/set-modified-date-time-precision", test_set_modified_date_time_precision);
1165 return g_test_run();