Skip to content

Commit c89a1c3

Browse files
author
Brian Burkhalter
committed
8338696: (fs) BasicFileAttributes.creationTime() falls back to epoch if birth time is unavailable (Linux)
Reviewed-by: sgehwolf, alanb
1 parent 813546f commit c89a1c3

File tree

1 file changed

+21
-9
lines changed

1 file changed

+21
-9
lines changed

src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,10 @@ struct my_statx
133133
#define STATX_BTIME 0x00000800U
134134
#endif
135135

136-
#ifndef STATX_ALL
137-
#define STATX_ALL (STATX_BTIME | STATX_BASIC_STATS)
138-
#endif
136+
//
137+
// STATX_ALL is deprecated; use a different name to avoid confusion.
138+
//
139+
#define LOCAL_STATX_ALL (STATX_BASIC_STATS | STATX_BTIME)
139140

140141
#ifndef AT_FDCWD
141142
#define AT_FDCWD -100
@@ -619,8 +620,19 @@ static void copy_statx_attributes(JNIEnv* env, struct my_statx* buf, jobject att
619620
(*env)->SetLongField(env, attrs, attrs_st_atime_sec, (jlong)buf->stx_atime.tv_sec);
620621
(*env)->SetLongField(env, attrs, attrs_st_mtime_sec, (jlong)buf->stx_mtime.tv_sec);
621622
(*env)->SetLongField(env, attrs, attrs_st_ctime_sec, (jlong)buf->stx_ctime.tv_sec);
622-
(*env)->SetLongField(env, attrs, attrs_st_birthtime_sec, (jlong)buf->stx_btime.tv_sec);
623-
(*env)->SetLongField(env, attrs, attrs_st_birthtime_nsec, (jlong)buf->stx_btime.tv_nsec);
623+
if ((buf->stx_mask & STATX_BTIME) != 0) {
624+
// Birth time was filled in so use it
625+
(*env)->SetLongField(env, attrs, attrs_st_birthtime_sec,
626+
(jlong)buf->stx_btime.tv_sec);
627+
(*env)->SetLongField(env, attrs, attrs_st_birthtime_nsec,
628+
(jlong)buf->stx_btime.tv_nsec);
629+
} else {
630+
// Birth time was not filled in: fall back to last modification time
631+
(*env)->SetLongField(env, attrs, attrs_st_birthtime_sec,
632+
(jlong)buf->stx_mtime.tv_sec);
633+
(*env)->SetLongField(env, attrs, attrs_st_birthtime_nsec,
634+
(jlong)buf->stx_mtime.tv_nsec);
635+
}
624636
(*env)->SetLongField(env, attrs, attrs_st_atime_nsec, (jlong)buf->stx_atime.tv_nsec);
625637
(*env)->SetLongField(env, attrs, attrs_st_mtime_nsec, (jlong)buf->stx_mtime.tv_nsec);
626638
(*env)->SetLongField(env, attrs, attrs_st_ctime_nsec, (jlong)buf->stx_ctime.tv_nsec);
@@ -674,7 +686,7 @@ Java_sun_nio_fs_UnixNativeDispatcher_stat0(JNIEnv* env, jclass this,
674686
#if defined(__linux__)
675687
struct my_statx statx_buf;
676688
int flags = AT_STATX_SYNC_AS_STAT;
677-
unsigned int mask = STATX_ALL;
689+
unsigned int mask = LOCAL_STATX_ALL;
678690

679691
if (my_statx_func != NULL) {
680692
// Prefer statx over stat on Linux if it's available
@@ -706,7 +718,7 @@ Java_sun_nio_fs_UnixNativeDispatcher_lstat0(JNIEnv* env, jclass this,
706718
#if defined(__linux__)
707719
struct my_statx statx_buf;
708720
int flags = AT_STATX_SYNC_AS_STAT | AT_SYMLINK_NOFOLLOW;
709-
unsigned int mask = STATX_ALL;
721+
unsigned int mask = LOCAL_STATX_ALL;
710722

711723
if (my_statx_func != NULL) {
712724
// Prefer statx over stat on Linux if it's available
@@ -737,7 +749,7 @@ Java_sun_nio_fs_UnixNativeDispatcher_fstat0(JNIEnv* env, jclass this, jint fd,
737749
#if defined(__linux__)
738750
struct my_statx statx_buf;
739751
int flags = AT_EMPTY_PATH | AT_STATX_SYNC_AS_STAT;
740-
unsigned int mask = STATX_ALL;
752+
unsigned int mask = LOCAL_STATX_ALL;
741753

742754
if (my_statx_func != NULL) {
743755
// statx supports FD use via dirfd iff pathname is an empty string and the
@@ -770,7 +782,7 @@ Java_sun_nio_fs_UnixNativeDispatcher_fstatat0(JNIEnv* env, jclass this, jint dfd
770782
#if defined(__linux__)
771783
struct my_statx statx_buf;
772784
int flags = AT_STATX_SYNC_AS_STAT;
773-
unsigned int mask = STATX_ALL;
785+
unsigned int mask = LOCAL_STATX_ALL;
774786

775787
if (my_statx_func != NULL) {
776788
// Prefer statx over stat on Linux if it's available

0 commit comments

Comments
 (0)