Skip to content

Commit c4d39f3

Browse files
committed
8338696: (fs) BasicFileAttributes.creationTime() falls back to epoch if birth time is unavailable (Linux)
Backport-of: c89a1c3
1 parent 0b340d1 commit c4d39f3

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
@@ -146,9 +146,10 @@ struct my_statx
146146
#define STATX_BTIME 0x00000800U
147147
#endif
148148

149-
#ifndef STATX_ALL
150-
#define STATX_ALL (STATX_BTIME | STATX_BASIC_STATS)
151-
#endif
149+
//
150+
// STATX_ALL is deprecated; use a different name to avoid confusion.
151+
//
152+
#define LOCAL_STATX_ALL (STATX_BASIC_STATS | STATX_BTIME)
152153

153154
#ifndef AT_FDCWD
154155
#define AT_FDCWD -100
@@ -624,8 +625,19 @@ static void copy_statx_attributes(JNIEnv* env, struct my_statx* buf, jobject att
624625
(*env)->SetLongField(env, attrs, attrs_st_atime_sec, (jlong)buf->stx_atime.tv_sec);
625626
(*env)->SetLongField(env, attrs, attrs_st_mtime_sec, (jlong)buf->stx_mtime.tv_sec);
626627
(*env)->SetLongField(env, attrs, attrs_st_ctime_sec, (jlong)buf->stx_ctime.tv_sec);
627-
(*env)->SetLongField(env, attrs, attrs_st_birthtime_sec, (jlong)buf->stx_btime.tv_sec);
628-
(*env)->SetLongField(env, attrs, attrs_st_birthtime_nsec, (jlong)buf->stx_btime.tv_nsec);
628+
if ((buf->stx_mask & STATX_BTIME) != 0) {
629+
// Birth time was filled in so use it
630+
(*env)->SetLongField(env, attrs, attrs_st_birthtime_sec,
631+
(jlong)buf->stx_btime.tv_sec);
632+
(*env)->SetLongField(env, attrs, attrs_st_birthtime_nsec,
633+
(jlong)buf->stx_btime.tv_nsec);
634+
} else {
635+
// Birth time was not filled in: fall back to last modification time
636+
(*env)->SetLongField(env, attrs, attrs_st_birthtime_sec,
637+
(jlong)buf->stx_mtime.tv_sec);
638+
(*env)->SetLongField(env, attrs, attrs_st_birthtime_nsec,
639+
(jlong)buf->stx_mtime.tv_nsec);
640+
}
629641
(*env)->SetLongField(env, attrs, attrs_st_atime_nsec, (jlong)buf->stx_atime.tv_nsec);
630642
(*env)->SetLongField(env, attrs, attrs_st_mtime_nsec, (jlong)buf->stx_mtime.tv_nsec);
631643
(*env)->SetLongField(env, attrs, attrs_st_ctime_nsec, (jlong)buf->stx_ctime.tv_nsec);
@@ -679,7 +691,7 @@ Java_sun_nio_fs_UnixNativeDispatcher_stat0(JNIEnv* env, jclass this,
679691
#if defined(__linux__)
680692
struct my_statx statx_buf;
681693
int flags = AT_STATX_SYNC_AS_STAT;
682-
unsigned int mask = STATX_ALL;
694+
unsigned int mask = LOCAL_STATX_ALL;
683695

684696
if (my_statx_func != NULL) {
685697
// Prefer statx over stat64 on Linux if it's available
@@ -711,7 +723,7 @@ Java_sun_nio_fs_UnixNativeDispatcher_lstat0(JNIEnv* env, jclass this,
711723
#if defined(__linux__)
712724
struct my_statx statx_buf;
713725
int flags = AT_STATX_SYNC_AS_STAT | AT_SYMLINK_NOFOLLOW;
714-
unsigned int mask = STATX_ALL;
726+
unsigned int mask = LOCAL_STATX_ALL;
715727

716728
if (my_statx_func != NULL) {
717729
// Prefer statx over stat64 on Linux if it's available
@@ -742,7 +754,7 @@ Java_sun_nio_fs_UnixNativeDispatcher_fstat0(JNIEnv* env, jclass this, jint fd,
742754
#if defined(__linux__)
743755
struct my_statx statx_buf;
744756
int flags = AT_EMPTY_PATH | AT_STATX_SYNC_AS_STAT;
745-
unsigned int mask = STATX_ALL;
757+
unsigned int mask = LOCAL_STATX_ALL;
746758

747759
if (my_statx_func != NULL) {
748760
// statx supports FD use via dirfd iff pathname is an empty string and the
@@ -775,7 +787,7 @@ Java_sun_nio_fs_UnixNativeDispatcher_fstatat0(JNIEnv* env, jclass this, jint dfd
775787
#if defined(__linux__)
776788
struct my_statx statx_buf;
777789
int flags = AT_STATX_SYNC_AS_STAT;
778-
unsigned int mask = STATX_ALL;
790+
unsigned int mask = LOCAL_STATX_ALL;
779791

780792
if (my_statx_func != NULL) {
781793
// Prefer statx over stat64 on Linux if it's available

0 commit comments

Comments
 (0)