@@ -184,6 +184,7 @@ static jfieldID attrs_st_birthtime_sec;
184184#if defined(__linux__ ) // Linux has nsec granularity if supported
185185static jfieldID attrs_st_birthtime_nsec ;
186186#endif
187+ static jfieldID attrs_birthtime_available ;
187188
188189static jfieldID attrs_f_frsize ;
189190static jfieldID attrs_f_blocks ;
@@ -332,6 +333,8 @@ Java_sun_nio_fs_UnixNativeDispatcher_init(JNIEnv* env, jclass this)
332333 attrs_st_birthtime_nsec = (* env )-> GetFieldID (env , clazz , "st_birthtime_nsec" , "J" );
333334 CHECK_NULL_RETURN (attrs_st_birthtime_nsec , 0 );
334335#endif
336+ attrs_birthtime_available = (* env )-> GetFieldID (env , clazz , "birthtime_available" , "Z" );
337+ CHECK_NULL_RETURN (attrs_birthtime_available , 0 );
335338
336339 clazz = (* env )-> FindClass (env , "sun/nio/fs/UnixFileStoreAttributes" );
337340 CHECK_NULL_RETURN (clazz , 0 );
@@ -620,19 +623,19 @@ static void copy_statx_attributes(JNIEnv* env, struct my_statx* buf, jobject att
620623 (* env )-> SetLongField (env , attrs , attrs_st_atime_sec , (jlong )buf -> stx_atime .tv_sec );
621624 (* env )-> SetLongField (env , attrs , attrs_st_mtime_sec , (jlong )buf -> stx_mtime .tv_sec );
622625 (* env )-> SetLongField (env , attrs , attrs_st_ctime_sec , (jlong )buf -> stx_ctime .tv_sec );
626+
627+ // Check mask for birth time and set flag accordingly. The birth time is
628+ // filled in if and only if the STATX_BTIME bit is set in the mask.
629+ // Although the statx system call might be supported by the operating
630+ // system, the birth time is not necessarily supported by the file system.
623631 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 );
632+ (* env )-> SetBooleanField (env , attrs , attrs_birthtime_available , (jboolean )JNI_TRUE );
633+ (* env )-> SetLongField (env , attrs , attrs_st_birthtime_sec , (jlong )buf -> stx_btime .tv_sec );
634+ (* env )-> SetLongField (env , attrs , attrs_st_birthtime_nsec , (jlong )buf -> stx_btime .tv_nsec );
629635 } 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 );
636+ (* env )-> SetBooleanField (env , attrs , attrs_birthtime_available , (jboolean )JNI_FALSE );
635637 }
638+
636639 (* env )-> SetLongField (env , attrs , attrs_st_atime_nsec , (jlong )buf -> stx_atime .tv_nsec );
637640 (* env )-> SetLongField (env , attrs , attrs_st_mtime_nsec , (jlong )buf -> stx_mtime .tv_nsec );
638641 (* env )-> SetLongField (env , attrs , attrs_st_ctime_nsec , (jlong )buf -> stx_ctime .tv_nsec );
@@ -661,7 +664,9 @@ static void copy_stat_attributes(JNIEnv* env, struct stat* buf, jobject attrs) {
661664 (* env )-> SetLongField (env , attrs , attrs_st_ctime_sec , (jlong )buf -> st_ctime );
662665
663666#ifdef _DARWIN_FEATURE_64_BIT_INODE
667+ // birthtime_available defaults to 'false'; on Darwin, it is always true
664668 (* env )-> SetLongField (env , attrs , attrs_st_birthtime_sec , (jlong )buf -> st_birthtime );
669+ (* env )-> SetBooleanField (env , attrs , attrs_birthtime_available , (jboolean )JNI_TRUE );
665670 // rely on default value of 0 for st_birthtime_nsec field on Darwin
666671#endif
667672
0 commit comments