From 18aaf33cf150d1221005475ee7505854f10df021 Mon Sep 17 00:00:00 2001 From: Andre Miranda Date: Fri, 14 Aug 2020 16:12:05 +0100 Subject: [PATCH] glocalfileinfo: Support STX_BTIME for G_FILE_ATTRIBUTE_TIME_CREATED If `statx()` is supported, query it for the file creation time and use that if returned. Incorporating some minor code rearrangement by Philip Withnall . Fixes: #1970 --- gio/gfileinfo.h | 3 ++- gio/glocalfileinfo.c | 20 +++++++++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/gio/gfileinfo.h b/gio/gfileinfo.h index 073a7496b..da202e6a7 100644 --- a/gio/gfileinfo.h +++ b/gio/gfileinfo.h @@ -540,7 +540,8 @@ typedef struct _GFileInfoClass GFileInfoClass; * and contains the time since the file was created, in seconds since the UNIX * epoch. * - * This corresponds to the NTFS ctime. + * This may correspond to Linux stx_btime, FreeBSD st_birthtim, NetBSD + * st_birthtime or NTFS ctime. **/ #define G_FILE_ATTRIBUTE_TIME_CREATED "time::created" /* uint64 */ diff --git a/gio/glocalfileinfo.c b/gio/glocalfileinfo.c index 0115a385a..a34c1b78a 100644 --- a/gio/glocalfileinfo.c +++ b/gio/glocalfileinfo.c @@ -1048,7 +1048,13 @@ set_info_from_stat (GFileInfo *info, #endif #endif -#if defined (HAVE_STRUCT_STAT_ST_BIRTHTIME) && defined (HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC) +#if defined (HAVE_STATX) + if (_g_stat_has_field (statbuf, G_LOCAL_FILE_STAT_FIELD_BTIME)) + { + _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CREATED, statbuf->stx_btime.tv_sec); + _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CREATED_USEC, statbuf->stx_btime.tv_nsec / 1000); + } +#elif defined (HAVE_STRUCT_STAT_ST_BIRTHTIME) && defined (HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC) _g_file_info_set_attribute_uint64_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CREATED, statbuf->st_birthtime); _g_file_info_set_attribute_uint32_by_id (info, G_FILE_ATTRIBUTE_ID_TIME_CREATED_USEC, statbuf->st_birthtimensec / 1000); #elif defined (HAVE_STRUCT_STAT_ST_BIRTHTIM) && defined (HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC) @@ -1798,8 +1804,8 @@ _g_local_file_info_get (const char *basename, } res = g_local_file_lstat (path, - G_LOCAL_FILE_STAT_FIELD_BASIC_STATS, - G_LOCAL_FILE_STAT_FIELD_ALL, + G_LOCAL_FILE_STAT_FIELD_BASIC_STATS | G_LOCAL_FILE_STAT_FIELD_BTIME, + G_LOCAL_FILE_STAT_FIELD_ALL & (~G_LOCAL_FILE_STAT_FIELD_BTIME), &statbuf); if (res == -1) @@ -1848,8 +1854,8 @@ _g_local_file_info_get (const char *basename, if (!(flags & G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS)) { res = g_local_file_stat (path, - G_LOCAL_FILE_STAT_FIELD_BASIC_STATS, - G_LOCAL_FILE_STAT_FIELD_ALL, + G_LOCAL_FILE_STAT_FIELD_BASIC_STATS | G_LOCAL_FILE_STAT_FIELD_BTIME, + G_LOCAL_FILE_STAT_FIELD_ALL & (~G_LOCAL_FILE_STAT_FIELD_BTIME), &statbuf2); /* Report broken links as symlinks */ @@ -2071,8 +2077,8 @@ _g_local_file_info_get_from_fd (int fd, GFileInfo *info; if (g_local_file_fstat (fd, - G_LOCAL_FILE_STAT_FIELD_BASIC_STATS, - G_LOCAL_FILE_STAT_FIELD_ALL, + G_LOCAL_FILE_STAT_FIELD_BASIC_STATS | G_LOCAL_FILE_STAT_FIELD_BTIME, + G_LOCAL_FILE_STAT_FIELD_ALL & (~G_LOCAL_FILE_STAT_FIELD_BTIME), &stat_buf) == -1) { int errsv = errno;