Skip to content

Commit

Permalink
fix Issue 15803 - std.file should support sub-second file time precis…
Browse files Browse the repository at this point in the history
…ion on POSIX
  • Loading branch information
CyberShadow committed Mar 16, 2016
1 parent c08032e commit c3f0469
Showing 1 changed file with 58 additions and 7 deletions.
65 changes: 58 additions & 7 deletions std/file.d
Expand Up @@ -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).
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -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);
}
}

Expand All @@ -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:
Expand Down Expand Up @@ -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()
Expand Down

0 comments on commit c3f0469

Please sign in to comment.