fix Issue 15803 - std.file should support sub-second file time precision on POSIX

This commit is contained in:
Vladimir Panteleev 2016-03-16 20:57:49 +00:00
parent c08032edd4
commit c3f0469b2b

View file

@ -822,6 +822,28 @@ unittest
}
// Reads a time field from a stat_t with full precision.
version(Posix)
private SysTime statTimeToStdTime(char which)(ref stat_t statbuf)
{
auto unixTime = mixin(`statbuf.st_` ~ which ~ `time`);
long stdTime = unixTimeToStdTime(unixTime);
static if (is(typeof(mixin(`statbuf.st_` ~ which ~ `tim`))))
stdTime += mixin(`statbuf.st_` ~ which ~ `tim.tv_nsec`) / 100;
else
static if (is(typeof(mixin(`statbuf.st_` ~ which ~ `timensec`))))
stdTime += mixin(`statbuf.st_` ~ which ~ `timensec`) / 100;
else
static if (is(typeof(mixin(`statbuf.st_` ~ which ~ `time_nsec`))))
stdTime += mixin(`statbuf.st_` ~ which ~ `time_nsec`) / 100;
else
static if (is(typeof(mixin(`statbuf.__st_` ~ which ~ `timensec`))))
stdTime += mixin(`statbuf.__st_` ~ which ~ `timensec`) / 100;
return SysTime(stdTime);
}
/++
Get the access and modified times of file or folder $(D name).
@ -863,8 +885,8 @@ void getTimes(R)(R name,
string names = null;
cenforce(trustedStat(namez, statbuf) == 0, names, namez);
accessTime = SysTime(unixTimeToStdTime(statbuf.st_atime));
modificationTime = SysTime(unixTimeToStdTime(statbuf.st_mtime));
accessTime = statTimeToStdTime!'a'(statbuf);
modificationTime = statTimeToStdTime!'m'(statbuf);
}
}
@ -1217,7 +1239,7 @@ SysTime timeLastModified(R)(R name)
string names = null;
cenforce(trustedStat(namez, statbuf) == 0, names, namez);
return SysTime(unixTimeToStdTime(statbuf.st_mtime));
return statTimeToStdTime!'m'(statbuf);
}
}
@ -1288,7 +1310,7 @@ SysTime timeLastModified(R)(R name, SysTime returnIfMissing)
return trustedStat(namez, statbuf) != 0 ?
returnIfMissing :
SysTime(unixTimeToStdTime(statbuf.st_mtime));
statTimeToStdTime!'m'(statbuf);
}
}
@ -1312,6 +1334,35 @@ unittest
}
// Tests sub-second precision of querying file times.
// Should pass on most modern systems running on modern filesystems.
// Exceptions:
// - FreeBSD, where one would need to first set the
// vfs.timestamp_precision sysctl to a value greater than zero.
// - OS X, where the native filesystem (HFS+) stores filesystem
// timestamps with 1-second precision.
version (FreeBSD) {} else
version (OSX) {} else
unittest
{
import core.thread;
if(exists(deleteme))
remove(deleteme);
SysTime lastTime;
foreach (n; 0..3)
{
write(deleteme, "a");
auto time = timeLastModified(deleteme);
remove(deleteme);
assert(time != lastTime);
lastTime = time;
Thread.sleep(10.msecs);
}
}
/**
* Determine whether the given file (or directory) exists.
* Params:
@ -2844,21 +2895,21 @@ else version(Posix)
{
_ensureStatDone();
return SysTime(unixTimeToStdTime(_statBuf.st_ctime));
return statTimeToStdTime!'c'(_statBuf);
}
@property SysTime timeLastAccessed()
{
_ensureStatDone();
return SysTime(unixTimeToStdTime(_statBuf.st_ctime));
return statTimeToStdTime!'a'(_statBuf);
}
@property SysTime timeLastModified()
{
_ensureStatDone();
return SysTime(unixTimeToStdTime(_statBuf.st_mtime));
return statTimeToStdTime!'m'(_statBuf);
}
@property uint attributes()