On filesystems which do not support birthtime, stats.birthtime can be greater than stats.mtime
stats.birthtime tracks ctime on filesystems which do not support birthtime, even if stats.ctime > stats.mtime or stats.ctime > stats.atime.
It would be better in this case if stats.birthtime be set to the earliest of all available timestamps.
Here is a test to reproduce, which should pass on OS X and fail on Ubuntu:
var fs = require('fs');
console.log('creating...');
try {
fs.unlinkSync('testbirthtime');
} catch (error) {}
fs.writeFileSync('testbirthtime', '');
console.log('statting...');
var before = fs.statSync('testbirthtime');
if (before.mtime.getTime() === before.ctime.getTime() && before.ctime.getTime() === before.birthtime.getTime()) {
console.log('stats.mtime===stats.ctime===stats.birthtime');
} else {
console.log(JSON.stringify(before));
// should never be here, unless the test is faulty.
throw new Error('expected stats.mtime===stats.ctime===stats.birthtime after create');
}
// give enough time for filesystem timestamp granularity
console.log('waiting 3 seconds...');
setTimeout(
function() {
console.log('changing mode to bump ctime...');
fs.chmodSync('testbirthtime', '777');
console.log('statting again...');
var after = fs.statSync('testbirthtime');
try {
fs.unlinkSync('testbirthtime');
} catch (error) {}
if (after.birthtime.getTime() === before.birthtime.getTime()) {
console.log('===========');
console.log('TEST PASSED');
console.log('stats.birthtime stayed the same after chmod');
} else {
console.log('===========');
console.log('TEST FAILED');
console.log('stats.birthtime after chmod !== stats.birthtime at creation');
if (after.birthtime.getTime() > before.birthtime.getTime()) {
console.log('stats.birthtime has gone forward in time');
} else {
console.log('stats.birthtime has gone backward in time');
}
if (after.mtime.getTime() === before.mtime.getTime()) {
console.log('stats.mtime stayed the same after chmod');
}
if (after.birthtime.getTime() === after.ctime.getTime()) {
console.log('stats.birthtime now equals newer stats.ctime');
console.log('where birthtime is not supported by filesystem:');
console.log(' stats.birthtime should be earlier of stats.mtime and stats.ctime');
}
}
},
3000
);