Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit dd65150

Browse files
danmoseleyjkotas
authored andcommitted
Update filetimes to nsec (#15872)
1 parent ccc9329 commit dd65150

File tree

7 files changed

+66
-11
lines changed

7 files changed

+66
-11
lines changed

src/mscorlib/shared/Interop/Unix/System.Native/Interop.Stat.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,13 @@ internal struct FileStatus
2424
internal uint Gid;
2525
internal long Size;
2626
internal long ATime;
27+
internal long ATimeNsec;
2728
internal long MTime;
29+
internal long MTimeNsec;
2830
internal long CTime;
31+
internal long CTimeNsec;
2932
internal long BirthTime;
33+
internal long BirthTimeNsec;
3034
internal long Dev;
3135
internal long Ino;
3236
}
@@ -49,13 +53,13 @@ internal enum FileStatusFlags
4953
HasBirthTime = 1,
5054
}
5155

52-
[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_FStat", SetLastError = true)]
56+
[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_FStat2", SetLastError = true)]
5357
internal static extern int FStat(SafeFileHandle fd, out FileStatus output);
5458

55-
[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_Stat", SetLastError = true)]
59+
[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_Stat2", SetLastError = true)]
5660
internal static extern int Stat(string path, out FileStatus output);
5761

58-
[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_LStat", SetLastError = true)]
62+
[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_LStat2", SetLastError = true)]
5963
internal static extern int LStat(string path, out FileStatus output);
6064
}
6165
}

src/pal/src/config.h.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@
7171
#cmakedefine01 HAVE_PR_SET_PTRACER
7272

7373
#cmakedefine01 HAVE_STAT_TIMESPEC
74+
#cmakedefine01 HAVE_STAT_TIM
7475
#cmakedefine01 HAVE_STAT_NSEC
7576
#cmakedefine01 HAVE_TM_GMTOFF
7677

src/pal/src/configure.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ int main(int argc, char **argv) {
134134
}" HAVE_CPUSET_T)
135135

136136
check_struct_has_member ("struct stat" st_atimespec "sys/types.h;sys/stat.h" HAVE_STAT_TIMESPEC)
137+
check_struct_has_member ("struct stat" st_atim "sys/types.h;sys/stat.h" HAVE_STAT_TIM)
137138
check_struct_has_member ("struct stat" st_atimensec "sys/types.h;sys/stat.h" HAVE_STAT_NSEC)
138139
check_struct_has_member ("struct tm" tm_gmtoff time.h HAVE_TM_GMTOFF)
139140
check_struct_has_member ("ucontext_t" uc_mcontext.gregs[0] ucontext.h HAVE_GREGSET_T)

src/pal/src/file/file.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1759,6 +1759,22 @@ GetFileAttributesExW(
17591759
FILEUnixTimeToFileTime( stat_data.st_mtime,
17601760
ST_MTIME_NSEC(&stat_data) );
17611761

1762+
/* if Unix mtime is greater than atime, return mtime
1763+
as the last access time */
1764+
if (CompareFileTime(&attr_data->ftLastAccessTime,
1765+
&attr_data->ftLastWriteTime) < 0)
1766+
{
1767+
attr_data->ftLastAccessTime = attr_data->ftLastWriteTime;
1768+
}
1769+
1770+
/* if Unix ctime is greater than mtime, return mtime
1771+
as the create time */
1772+
if (CompareFileTime(&attr_data->ftLastWriteTime,
1773+
&attr_data->ftCreationTime) < 0)
1774+
{
1775+
attr_data->ftCreationTime = attr_data->ftLastWriteTime;
1776+
}
1777+
17621778
/* Get the file size. GetFileSize is not used because it gets the
17631779
size of an already-open file */
17641780
attr_data->nFileSizeLow = (DWORD) stat_data.st_size;
@@ -4451,6 +4467,22 @@ GetFileInformationByHandle(
44514467
FILEUnixTimeToFileTime( stat_data.st_mtime,
44524468
ST_MTIME_NSEC(&stat_data) );
44534469

4470+
/* if Unix mtime is greater than atime, return mtime
4471+
as the last access time */
4472+
if (CompareFileTime(&lpFileInformation->ftLastAccessTime,
4473+
&lpFileInformation->ftLastWriteTime) < 0)
4474+
{
4475+
lpFileInformation->ftLastAccessTime = lpFileInformation->ftLastWriteTime;
4476+
}
4477+
4478+
/* if Unix ctime is greater than mtime, return mtime
4479+
as the create time */
4480+
if (CompareFileTime(&lpFileInformation->ftLastWriteTime,
4481+
&lpFileInformation->ftCreationTime) < 0)
4482+
{
4483+
lpFileInformation->ftCreationTime = lpFileInformation->ftLastWriteTime;
4484+
}
4485+
44544486
lpFileInformation->dwVolumeSerialNumber = stat_data.st_dev;
44554487

44564488
/* Get the file size. GetFileSize is not used because it gets the

src/pal/src/file/filetime.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@ if it exists, and are defined as 0 otherwise.
4242
4343
--
4444
45-
Also note that there is no analog to "creation time" on Unix systems.
45+
Also note that there is no analog to "creation time" on Linux systems.
4646
Instead, we use the inode change time, which is set to the current time
4747
whenever mtime changes or when chmod, chown, etc. syscalls modify the
48-
file status.
49-
48+
file status; or mtime if older. Ideally we would use birthtime when
49+
available.
5050
5151
5252
--*/

src/pal/src/file/find.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -417,24 +417,32 @@ FindNextFileA(
417417

418418
if ( stat_result )
419419
{
420-
lpFindFileData->ftCreationTime =
420+
lpFindFileData->ftCreationTime =
421421
FILEUnixTimeToFileTime( stat_data.st_ctime,
422422
ST_CTIME_NSEC(&stat_data) );
423-
lpFindFileData->ftLastAccessTime =
423+
lpFindFileData->ftLastAccessTime =
424424
FILEUnixTimeToFileTime( stat_data.st_atime,
425425
ST_ATIME_NSEC(&stat_data) );
426-
lpFindFileData->ftLastWriteTime =
426+
lpFindFileData->ftLastWriteTime =
427427
FILEUnixTimeToFileTime( stat_data.st_mtime,
428428
ST_MTIME_NSEC(&stat_data) );
429429

430-
/* if Unix mtime is greater than atime, return mtime
430+
/* if Unix mtime is greater than atime, return mtime
431431
as the last access time */
432-
if (CompareFileTime(&lpFindFileData->ftLastAccessTime,
432+
if (CompareFileTime(&lpFindFileData->ftLastAccessTime,
433433
&lpFindFileData->ftLastWriteTime) < 0)
434434
{
435435
lpFindFileData->ftLastAccessTime = lpFindFileData->ftLastWriteTime;
436436
}
437437

438+
/* if Unix ctime is greater than mtime, return mtime
439+
as the create time */
440+
if (CompareFileTime(&lpFindFileData->ftLastWriteTime,
441+
&lpFindFileData->ftCreationTime) < 0)
442+
{
443+
lpFindFileData->ftCreationTime = lpFindFileData->ftLastWriteTime;
444+
}
445+
438446
/* get file size */
439447
lpFindFileData->nFileSizeLow = (DWORD)stat_data.st_size;
440448
#if SIZEOF_OFF_T > 4

src/pal/src/include/pal/filetime.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ extern "C"
3838

3939
#else /* HAVE_STAT_TIMESPEC */
4040

41+
#if HAVE_STAT_TIM
42+
43+
#define ST_ATIME_NSEC(statstruct) ((statstruct)->st_atim.tv_nsec)
44+
#define ST_MTIME_NSEC(statstruct) ((statstruct)->st_mtim.tv_nsec)
45+
#define ST_CTIME_NSEC(statstruct) ((statstruct)->st_ctim.tv_nsec)
46+
47+
#else /* HAVE_STAT_TIM */
48+
4149
#if HAVE_STAT_NSEC
4250

4351
#define ST_ATIME_NSEC(statstruct) ((statstruct)->st_atimensec)
@@ -51,6 +59,7 @@ extern "C"
5159
#define ST_CTIME_NSEC(statstruct) 0
5260

5361
#endif /* HAVE_STAT_NSEC */
62+
#endif /* HAVE_STAT_TIM */
5463
#endif /* HAVE_STAT_TIMESPEC */
5564

5665
FILETIME FILEUnixTimeToFileTime( time_t sec, long nsec );

0 commit comments

Comments
 (0)