mirror of
https://sourceware.org/git/glibc.git
synced 2025-06-16 17:41:01 +03:00
io: Check at runtime if timestamp supports nanoseconds
Now that non-LFS stat function is implemented on to on LFS, it will use statx when available. It allows to check for nanosecond timestamp if the kernel supports __NR_statx. Checked on s390-linux-gnu with 4.12.14 kernel.
This commit is contained in:
@ -25,6 +25,7 @@
|
|||||||
#include <support/xunistd.h>
|
#include <support/xunistd.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/sysmacros.h>
|
#include <sys/sysmacros.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -73,6 +74,10 @@ do_test (void)
|
|||||||
|
|
||||||
test_t tests[] = { stat_check, lstat_check, fstat_check, fstatat_check };
|
test_t tests[] = { stat_check, lstat_check, fstat_check, fstatat_check };
|
||||||
|
|
||||||
|
bool check_ns = support_stat_nanoseconds (path);
|
||||||
|
if (!check_ns)
|
||||||
|
printf ("warning: timestamp with nanoseconds not supportted\n");
|
||||||
|
|
||||||
for (int i = 0; i < array_length (tests); i++)
|
for (int i = 0; i < array_length (tests); i++)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
@ -92,7 +97,7 @@ do_test (void)
|
|||||||
|
|
||||||
TEST_COMPARE (stx.stx_ctime.tv_sec, st.st_ctim.tv_sec);
|
TEST_COMPARE (stx.stx_ctime.tv_sec, st.st_ctim.tv_sec);
|
||||||
TEST_COMPARE (stx.stx_mtime.tv_sec, st.st_mtim.tv_sec);
|
TEST_COMPARE (stx.stx_mtime.tv_sec, st.st_mtim.tv_sec);
|
||||||
if (support_stat_nanoseconds ())
|
if (check_ns)
|
||||||
{
|
{
|
||||||
TEST_COMPARE (stx.stx_ctime.tv_nsec, st.st_ctim.tv_nsec);
|
TEST_COMPARE (stx.stx_ctime.tv_nsec, st.st_ctim.tv_nsec);
|
||||||
TEST_COMPARE (stx.stx_mtime.tv_nsec, st.st_mtim.tv_nsec);
|
TEST_COMPARE (stx.stx_mtime.tv_nsec, st.st_mtim.tv_nsec);
|
||||||
|
@ -142,7 +142,7 @@ static __inline bool support_path_support_time64 (const char *path)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Return true if stat supports nanoseconds resolution. */
|
/* Return true if stat supports nanoseconds resolution. */
|
||||||
extern bool support_stat_nanoseconds (void);
|
extern bool support_stat_nanoseconds (const char *path);
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
|
@ -16,16 +16,42 @@
|
|||||||
License along with the GNU C Library; if not, see
|
License along with the GNU C Library; if not, see
|
||||||
<https://www.gnu.org/licenses/>. */
|
<https://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <support/check.h>
|
||||||
|
#include <support/support.h>
|
||||||
|
#include <support/timespec.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
bool
|
bool
|
||||||
support_stat_nanoseconds (void)
|
support_stat_nanoseconds (const char *path)
|
||||||
{
|
{
|
||||||
/* s390 stat64 compat symbol does not support nanoseconds resolution
|
bool support;
|
||||||
and it used on non-LFS [f,l]stat[at] implementations. */
|
#ifdef __linux__
|
||||||
#if defined __linux__ && !defined __s390x__ && defined __s390__
|
/* Obtain the original timestamp to restore at the end. */
|
||||||
return false;
|
struct stat ost;
|
||||||
#else
|
TEST_VERIFY_EXIT (stat (path, &ost) == 0);
|
||||||
return true;
|
|
||||||
|
const struct timespec tsp[] = { { 0, TIMESPEC_HZ - 1 },
|
||||||
|
{ 0, TIMESPEC_HZ / 2 } };
|
||||||
|
TEST_VERIFY_EXIT (utimensat (AT_FDCWD, path, tsp, 0) == 0);
|
||||||
|
|
||||||
|
struct stat st;
|
||||||
|
TEST_VERIFY_EXIT (stat (path, &st) == 0);
|
||||||
|
|
||||||
|
support = st.st_atim.tv_nsec == tsp[0].tv_nsec
|
||||||
|
&& st.st_mtim.tv_nsec == tsp[1].tv_nsec;
|
||||||
|
|
||||||
|
/* Reset to original timestamps. */
|
||||||
|
const struct timespec otsp[] =
|
||||||
|
{
|
||||||
|
{ ost.st_atim.tv_sec, ost.st_atim.tv_nsec },
|
||||||
|
{ ost.st_mtim.tv_sec, ost.st_mtim.tv_nsec },
|
||||||
|
};
|
||||||
|
TEST_VERIFY_EXIT (utimensat (AT_FDCWD, path, otsp, 0) == 0);
|
||||||
#endif
|
#endif
|
||||||
|
return support;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user