Merge branch 'utimes' into develop
minor correction to test description corrected calling the callback function if failed to queue operation for utimes
This commit is contained in:
commit
bf5c84520d
1
AUTHORS
1
AUTHORS
|
@ -1,3 +1,4 @@
|
||||||
Alan K <ack@modeswitch.org> (blog.modeswitch.org)
|
Alan K <ack@modeswitch.org> (blog.modeswitch.org)
|
||||||
David Humphrey <david.humphrey@senecacollege.ca> (@humphd)
|
David Humphrey <david.humphrey@senecacollege.ca> (@humphd)
|
||||||
Abir Viqar <abiviq@hushmail.com>
|
Abir Viqar <abiviq@hushmail.com>
|
||||||
|
Barry Tulchinsky <barry.tulchinsky@gmail.com> (@btulchinsky)
|
||||||
|
|
|
@ -336,3 +336,11 @@ Asynchronous truncate(2). Callback gets no additional arguments.
|
||||||
#### fs.ftruncate(fd, length, callback)
|
#### fs.ftruncate(fd, length, callback)
|
||||||
|
|
||||||
Asynchronous ftruncate(2). Callback gets no additional arguments.
|
Asynchronous ftruncate(2). Callback gets no additional arguments.
|
||||||
|
|
||||||
|
#### fs.utimes(path, atime, mtime, callback)
|
||||||
|
|
||||||
|
Asynchronous utimes(3). Callback gets no additional arguments.
|
||||||
|
|
||||||
|
#### fs.futimes(fd, atime, mtime, callback)
|
||||||
|
|
||||||
|
Asynchronous futimes(3). Callback gets no additional arguments.
|
||||||
|
|
121
src/fs.js
121
src/fs.js
|
@ -1069,6 +1069,55 @@ define(function(require) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function utimes_file(context, path, atime, mtime, callback) {
|
||||||
|
path = normalize(path);
|
||||||
|
|
||||||
|
function update_times (error, node) {
|
||||||
|
if (error) {
|
||||||
|
callback(error);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
node.atime = atime;
|
||||||
|
node.mtime = mtime;
|
||||||
|
context.put(node.id, node, callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof atime != 'number' || typeof mtime != 'number') {
|
||||||
|
callback(new EInvalid('atime and mtime must be number'));
|
||||||
|
}
|
||||||
|
else if (atime < 0 || mtime < 0) {
|
||||||
|
callback(new EInvalid('atime and mtime must be positive integers'));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
find_node(context, path, update_times);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function futimes_file(context, ofd, atime, mtime, callback) {
|
||||||
|
|
||||||
|
function update_times (error, node) {
|
||||||
|
if (error) {
|
||||||
|
callback(error);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
node.atime = atime;
|
||||||
|
node.mtime = mtime;
|
||||||
|
context.put(node.id, node, callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof atime != 'number' || typeof mtime != 'number') {
|
||||||
|
callback(new EInvalid('atime and mtime must be a number'));
|
||||||
|
}
|
||||||
|
else if (atime < 0 || mtime < 0) {
|
||||||
|
callback(new EInvalid('atime and mtime must be positive integers'));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
context.get(ofd.id, update_times);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function validate_flags(flags) {
|
function validate_flags(flags) {
|
||||||
if(!_(O_FLAGS).has(flags)) {
|
if(!_(O_FLAGS).has(flags)) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -1555,9 +1604,47 @@ define(function(require) {
|
||||||
read_directory(context, path, check_result);
|
read_directory(context, path, check_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
function _utimes(path, atime, mtime, callback) {
|
function _utimes(context, path, atime, mtime, callback) {
|
||||||
// TODO
|
if(!nullCheck(path, callback)) return;
|
||||||
// if(!nullCheck(path, callback)) return;
|
|
||||||
|
var currentTime = Date.now();
|
||||||
|
atime = (atime) ? atime : currentTime;
|
||||||
|
mtime = (mtime) ? mtime : currentTime;
|
||||||
|
|
||||||
|
function check_result(error) {
|
||||||
|
if (error) {
|
||||||
|
callback(error);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
utimes_file(context, path, atime, mtime, check_result)
|
||||||
|
}
|
||||||
|
|
||||||
|
function _futimes(fs, context, fd, atime, mtime, callback) {
|
||||||
|
function check_result(error) {
|
||||||
|
if (error) {
|
||||||
|
callback(error);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentTime = Date.now()
|
||||||
|
atime = (atime) ? atime : currentTime;
|
||||||
|
mtime = (mtime) ? mtime : currentTime;
|
||||||
|
|
||||||
|
var ofd = fs.openFiles[fd];
|
||||||
|
|
||||||
|
if(!ofd) {
|
||||||
|
callback(new EBadFileDescriptor('invalid file descriptor'));
|
||||||
|
} else if(!_(ofd.flags).contains(O_WRITE)) {
|
||||||
|
callback(new EBadFileDescriptor('descriptor does not permit writing'));
|
||||||
|
} else {
|
||||||
|
futimes_file(context, ofd, atime, mtime, check_result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _rename(context, oldpath, newpath, callback) {
|
function _rename(context, oldpath, newpath, callback) {
|
||||||
|
@ -1895,6 +1982,34 @@ define(function(require) {
|
||||||
);
|
);
|
||||||
if(error) callback(error);
|
if(error) callback(error);
|
||||||
};
|
};
|
||||||
|
FileSystem.prototype.utimes = function(path, atime, mtime, callback) {
|
||||||
|
callback = maybeCallback(callback);
|
||||||
|
var fs = this;
|
||||||
|
var error = fs.queueOrRun(
|
||||||
|
function () {
|
||||||
|
var context = fs.provider.getReadWriteContext();
|
||||||
|
_utimes(context, path, atime, mtime, callback);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
callback(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
FileSystem.prototype.futimes = function(fd, atime, mtime, callback) {
|
||||||
|
callback = maybeCallback(callback);
|
||||||
|
var fs = this;
|
||||||
|
var error = fs.queueOrRun(
|
||||||
|
function () {
|
||||||
|
var context = fs.provider.getReadWriteContext();
|
||||||
|
_futimes(fs, context, fd, atime, mtime, callback);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
callback(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return FileSystem;
|
return FileSystem;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,317 @@
|
||||||
|
define(["IDBFS"], function(IDBFS) {
|
||||||
|
|
||||||
|
describe('fs.utimes', function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
this.db_name = mk_db_name();
|
||||||
|
this.fs = new IDBFS.FileSystem({
|
||||||
|
name: this.db_name,
|
||||||
|
flags: 'FORMAT'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function() {
|
||||||
|
indexedDB.deleteDatabase(this.db_name);
|
||||||
|
delete this.fs;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be a function', function() {
|
||||||
|
expect(typeof this.fs.utimes).toEqual('function');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should error when atime is negative', function () {
|
||||||
|
var complete = false;
|
||||||
|
var _error;
|
||||||
|
var that = this;
|
||||||
|
|
||||||
|
that.fs.writeFile('/testfile', '', function(error) {
|
||||||
|
if (error) throw error;
|
||||||
|
|
||||||
|
that.fs.utimes('/testfile', -1, Date.now(), function (error) {
|
||||||
|
_error = error;
|
||||||
|
complete = true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
waitsFor(function () {
|
||||||
|
return complete;
|
||||||
|
}, 'test to complete', DEFAULT_TIMEOUT);
|
||||||
|
|
||||||
|
runs(function () {
|
||||||
|
expect(_error).toBeDefined();
|
||||||
|
expect(_error.name).toEqual('EInvalid');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should error when mtime is negative', function () {
|
||||||
|
var complete = false;
|
||||||
|
var _error;
|
||||||
|
var that = this;
|
||||||
|
|
||||||
|
that.fs.writeFile('/testfile', '', function(error) {
|
||||||
|
if (error) throw error;
|
||||||
|
|
||||||
|
that.fs.utimes('/testfile', Date.now(), -1, function (error) {
|
||||||
|
_error = error;
|
||||||
|
complete = true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
waitsFor(function () {
|
||||||
|
return complete;
|
||||||
|
}, 'test to complete', DEFAULT_TIMEOUT);
|
||||||
|
|
||||||
|
runs(function () {
|
||||||
|
expect(_error).toBeDefined();
|
||||||
|
expect(_error.name).toEqual('EInvalid');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should error when atime is as invalid number', function () {
|
||||||
|
var complete = false;
|
||||||
|
var _error;
|
||||||
|
var that = this;
|
||||||
|
|
||||||
|
that.fs.writeFile('/testfile', '', function (error) {
|
||||||
|
if (error) throw error;
|
||||||
|
|
||||||
|
that.fs.utimes('/testfile', 'invalid datetime', Date.now(), function (error) {
|
||||||
|
_error = error;
|
||||||
|
complete = true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
waitsFor(function () {
|
||||||
|
return complete;
|
||||||
|
}, 'test to complete', DEFAULT_TIMEOUT);
|
||||||
|
|
||||||
|
runs(function () {
|
||||||
|
expect(_error).toBeDefined();
|
||||||
|
expect(_error.name).toEqual('EInvalid');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it ('should error when path does not exist', function () {
|
||||||
|
var complete = false;
|
||||||
|
var _error;
|
||||||
|
var that = this;
|
||||||
|
|
||||||
|
var atime = Date.parse('1 Oct 2000 15:33:22');
|
||||||
|
var mtime = Date.parse('30 Sep 2000 06:43:54');
|
||||||
|
|
||||||
|
that.fs.utimes('/pathdoesnotexist', atime, mtime, function (error) {
|
||||||
|
_error = error;
|
||||||
|
complete = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
waitsFor(function () {
|
||||||
|
return complete;
|
||||||
|
}, 'test to complete', DEFAULT_TIMEOUT);
|
||||||
|
|
||||||
|
runs(function () {
|
||||||
|
expect(_error).toBeDefined();
|
||||||
|
expect(_error.name).toEqual('ENoEntry');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should error when mtime is an invalid number', function () {
|
||||||
|
var complete = false;
|
||||||
|
var _error;
|
||||||
|
var that = this;
|
||||||
|
|
||||||
|
that.fs.writeFile('/testfile', '', function (error) {
|
||||||
|
if (error) throw error;
|
||||||
|
|
||||||
|
that.fs.utimes('/testfile', Date.now(), 'invalid datetime', function (error) {
|
||||||
|
_error = error;
|
||||||
|
complete = true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
waitsFor(function () {
|
||||||
|
return complete;
|
||||||
|
}, 'test to complete', DEFAULT_TIMEOUT);
|
||||||
|
|
||||||
|
runs(function () {
|
||||||
|
expect(_error).toBeDefined();
|
||||||
|
expect(_error.name).toEqual('EInvalid');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it ('should error when file descriptor is invalid', function () {
|
||||||
|
var complete = false;
|
||||||
|
var _error;
|
||||||
|
var that = this;
|
||||||
|
|
||||||
|
var atime = Date.parse('1 Oct 2000 15:33:22');
|
||||||
|
var mtime = Date.parse('30 Sep 2000 06:43:54');
|
||||||
|
|
||||||
|
that.fs.futimes(1, atime, mtime, function (error) {
|
||||||
|
_error = error;
|
||||||
|
complete = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
waitsFor(function () {
|
||||||
|
return complete;
|
||||||
|
}, 'test to complete', DEFAULT_TIMEOUT);
|
||||||
|
|
||||||
|
runs(function () {
|
||||||
|
expect(_error).toBeDefined();
|
||||||
|
expect(_error.name).toEqual('EBadFileDescriptor');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should change atime and mtime of a file path', function () {
|
||||||
|
var complete = false;
|
||||||
|
var _error;
|
||||||
|
var that = this;
|
||||||
|
|
||||||
|
var _stat;
|
||||||
|
|
||||||
|
var atime = Date.parse('1 Oct 2000 15:33:22');
|
||||||
|
var mtime = Date.parse('30 Sep 2000 06:43:54');
|
||||||
|
|
||||||
|
that.fs.writeFile('/testfile', '', function (error) {
|
||||||
|
if (error) throw error;
|
||||||
|
|
||||||
|
that.fs.utimes('/testfile', atime, mtime, function (error) {
|
||||||
|
_error = error;
|
||||||
|
|
||||||
|
that.fs.stat('/testfile', function (error, stat) {
|
||||||
|
if (error) throw error;
|
||||||
|
|
||||||
|
_stat = stat;
|
||||||
|
complete = true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
waitsFor(function() {
|
||||||
|
return complete;
|
||||||
|
}, 'test to complete', DEFAULT_TIMEOUT);
|
||||||
|
|
||||||
|
runs(function() {
|
||||||
|
expect(_error).toEqual(null);
|
||||||
|
expect(_stat.atime).toEqual(atime);
|
||||||
|
expect(_stat.mtime).toEqual(mtime);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it ('should change atime and mtime for a valid file descriptor', function (error) {
|
||||||
|
var complete = false;
|
||||||
|
var _error;
|
||||||
|
var that = this;
|
||||||
|
|
||||||
|
var ofd;
|
||||||
|
var _stat;
|
||||||
|
|
||||||
|
var atime = Date.parse('1 Oct 2000 15:33:22');
|
||||||
|
var mtime = Date.parse('30 Sep 2000 06:43:54');
|
||||||
|
|
||||||
|
that.fs.open('/testfile', 'w', function (error, result) {
|
||||||
|
if (error) throw error;
|
||||||
|
|
||||||
|
ofd = result;
|
||||||
|
|
||||||
|
that.fs.futimes(ofd, atime, mtime, function (error) {
|
||||||
|
_error = error;
|
||||||
|
|
||||||
|
that.fs.fstat(ofd, function (error, stat) {
|
||||||
|
if (error) throw error;
|
||||||
|
|
||||||
|
_stat = stat;
|
||||||
|
complete = true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
waitsFor(function () {
|
||||||
|
return complete;
|
||||||
|
}, 'test to complete', DEFAULT_TIMEOUT);
|
||||||
|
|
||||||
|
runs(function () {
|
||||||
|
expect(_error).toEqual(null);
|
||||||
|
expect(_stat.atime).toEqual(atime);
|
||||||
|
expect(_stat.mtime).toEqual(mtime);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it ('should update atime and mtime of directory path', function (error) {
|
||||||
|
var complete = false
|
||||||
|
var _error;
|
||||||
|
|
||||||
|
//Note: required as the filesystem somehow gets removed from the Jasmine object
|
||||||
|
var fs = this.fs;
|
||||||
|
|
||||||
|
var _stat;
|
||||||
|
|
||||||
|
var atime = Date.parse('1 Oct 2000 15:33:22');
|
||||||
|
var mtime = Date.parse('30 Sep 2000 06:43:54');
|
||||||
|
|
||||||
|
fs.mkdir('/testdir', function (error) {
|
||||||
|
if (error) throw error;
|
||||||
|
|
||||||
|
fs.utimes('/testdir', atime, mtime, function (error) {
|
||||||
|
_error = error;
|
||||||
|
|
||||||
|
fs.stat('/testdir', function (error, stat) {
|
||||||
|
if (error) throw error;
|
||||||
|
|
||||||
|
_stat = stat;
|
||||||
|
complete = true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
waitsFor(function () {
|
||||||
|
return complete;
|
||||||
|
}, 'test to complete', DEFAULT_TIMEOUT);
|
||||||
|
|
||||||
|
runs(function () {
|
||||||
|
expect(_error).toEqual(null);
|
||||||
|
expect(_stat.atime).toEqual(atime);
|
||||||
|
expect(_stat.mtime).toEqual(mtime);
|
||||||
|
delete fs;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it ('should update atime and mtime when they are null', function () {
|
||||||
|
var complete = false;
|
||||||
|
var _error;
|
||||||
|
var that = this;
|
||||||
|
|
||||||
|
var atimeEst;
|
||||||
|
var mtimeEst;
|
||||||
|
var now;
|
||||||
|
|
||||||
|
that.fs.writeFile('/myfile', '', function (error) {
|
||||||
|
if (error) throw error;
|
||||||
|
|
||||||
|
that.fs.utimes('/myfile', null, null, function (error) {
|
||||||
|
_error = error;
|
||||||
|
|
||||||
|
now = Date.now();
|
||||||
|
|
||||||
|
that.fs.stat('/myfile', function (error, stat) {
|
||||||
|
if (error) throw error;
|
||||||
|
|
||||||
|
atimeEst = now - stat.atime;
|
||||||
|
mtimeEst = now - stat.mtime;
|
||||||
|
complete = true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
waitsFor(function (){
|
||||||
|
return complete;
|
||||||
|
}, 'test to complete', DEFAULT_TIMEOUT);
|
||||||
|
|
||||||
|
runs(function () {
|
||||||
|
expect(_error).toEqual(null);
|
||||||
|
// Note: testing estimation as time may differ by a couple of milliseconds
|
||||||
|
// This number should be increased if tests are on slow systems
|
||||||
|
expect(atimeEst).toBeLessThan(10);
|
||||||
|
expect(mtimeEst).toBeLessThan(10);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -27,6 +27,7 @@ define([
|
||||||
"spec/fs.symlink.spec",
|
"spec/fs.symlink.spec",
|
||||||
"spec/fs.readlink.spec",
|
"spec/fs.readlink.spec",
|
||||||
"spec/fs.truncate.spec",
|
"spec/fs.truncate.spec",
|
||||||
|
"spec/fs.utimes.spec",
|
||||||
"spec/path-resolution.spec",
|
"spec/path-resolution.spec",
|
||||||
|
|
||||||
// IDBFS.FileSystem.providers.*
|
// IDBFS.FileSystem.providers.*
|
||||||
|
|
Loading…
Reference in New Issue