Merge pull request #190 from gideonthomas/Issue145

Fixes #145
This commit is contained in:
Alan K 2014-05-21 12:22:00 -04:00
commit d850157a84
7 changed files with 3414 additions and 4330 deletions

View File

@ -277,6 +277,7 @@ var fs = new Filer.FileSystem();
* [fs.readlink(path, callback)](#readlink)
* [fs.realpath(path, [cache], callback)](#realpath)
* [fs.unlink(path, callback)](#unlink)
* [fs.mknod(path, mode, callback)](#mknod)
* [fs.rmdir(path, callback)](#rmdir)
* [fs.mkdir(path, [mode], callback)](#mkdir)
* [fs.readdir(path, callback)](#readdir)
@ -574,6 +575,26 @@ fs.unlink('/backup.old', function(err) {
});
```
#### fs.mknod(path, mode, callback)<a name="mknod"></a>
Creates a node at `path` based on the mode passed which is either `FILE` or `DIRECTORY`. Asynchronous [mknod(2)](http://pubs.opengroup.org/onlinepubs/009695399/functions/mknod.html). Callback gets no additional arguments.
Example:
```javascript
// Create a /dir directory
fs.mknod('/dir', 'DIRECTORY', function(err) {
if(err) throw err;
// /dir is now created
// Create a file inside /dir
fs.mknod('/dir/myfile', 'FILE', function(err) {
if(err) throw err;
// /dir/myfile now exists
});
});
```
#### fs.rmdir(path, callback)<a name="rmdir"></a>
Removes the directory at `path`. Asynchronous [rmdir(2)](http://pubs.opengroup.org/onlinepubs/009695399/functions/rmdir.html).

7546
dist/filer.js vendored

File diff suppressed because it is too large Load Diff

12
dist/filer.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -105,6 +105,83 @@ define(function(require) {
complete();
}
}
/*
* make_node()
*/
// in: file or directory path
// out: new node representing file/directory
function make_node(context, path, mode, callback) {
if(mode !== MODE_DIRECTORY && mode !== MODE_FILE) {
return callback(new Errors.EINVAL('mode must be a directory or file'));
}
path = normalize(path);
var name = basename(path);
var parentPath = dirname(path);
var parentNode;
var parentNodeData;
var node;
// Check if the parent node exists
function create_node_in_parent(error, parentDirectoryNode) {
if(error) {
callback(error);
} else if(parentDirectoryNode.mode !== MODE_DIRECTORY) {
callback(new Errors.ENOTDIR('a component of the path prefix is not a directory'));
} else {
parentNode = parentDirectoryNode;
find_node(context, path, check_if_node_exists);
}
}
// Check if the node to be created already exists
function check_if_node_exists(error, result) {
if(!error && result) {
callback(new Errors.EEXIST('path name already exists'));
} else if(error && !(error instanceof Errors.ENOENT)) {
callback(error);
} else {
context.get(parentNode.data, create_node);
}
}
// Create the new node
function create_node(error, result) {
if(error) {
callback(error);
} else {
parentNodeData = result;
node = new Node(undefined, mode);
node.nlinks += 1;
context.put(node.id, node, update_parent_node_data);
}
}
// Update parent node time
function update_time(error) {
if(error) {
callback(error);
} else {
var now = Date.now();
update_node_times(context, parentPath, node, { mtime: now, ctime: now }, callback);
}
}
// Update the parent nodes data
function update_parent_node_data(error) {
if(error) {
callback(error);
} else {
parentNodeData[name] = new DirectoryEntry(node.id, mode);
context.put(parentNode.data, parentNodeData, update_time);
}
}
// Find the parent node
find_node(context, parentPath, create_node_in_parent);
}
/*
* find_node
@ -1471,6 +1548,11 @@ define(function(require) {
callback(null);
}
}
function mknod(fs, context, path, mode, callback) {
if(!pathCheck(path, callback)) return;
make_node(context, path, mode, callback);
}
function mkdir(fs, context, path, mode, callback) {
// NOTE: we support passing a mode arg, but we ignore it internally for now.
@ -1892,6 +1974,7 @@ define(function(require) {
makeRootDirectory: make_root_directory,
open: open,
close: close,
mknod: mknod,
mkdir: mkdir,
rmdir: rmdir,
unlink: unlink,

View File

@ -226,6 +226,7 @@ define(function(require) {
[
'open',
'close',
'mknod',
'mkdir',
'rmdir',
'stat',

View File

@ -0,0 +1,80 @@
define(["Filer", "util"], function(Filer, util) {
describe('fs.mknod', function() {
beforeEach(util.setup);
afterEach(util.cleanup);
it('should be a function', function(done) {
var fs = util.fs();
expect(fs.mknod).to.be.a('function');
done();
});
it('should return an error if part of the parent path does not exist', function(done) {
var fs = util.fs();
fs.mknod('/dir/mydir', 'DIRECTORY', function(error) {
expect(error.code).to.equal('ENOENT');
done();
});
});
it('should return an error if path already exists', function(done) {
var fs = util.fs();
fs.mknod('/', 'DIRECTORY', function(error) {
expect(error.code).to.equal('EEXIST');
done();
});
});
it('should return an error if the parent node is not a directory', function(done) {
var fs = util.fs();
fs.mknod('/file', 'FILE' , function(error, result) {
if(error) throw error;
fs.mknod('/file/myfile', 'FILE', function(error, result) {
expect(error.code).to.equal('ENOTDIR');
done();
});
});
});
it('should return an error if the mode provided is not DIRECTORY or FILE', function(done) {
var fs = util.fs();
fs.mknod('/symlink', 'SYMLINK', function(error) {
expect(error).to.exist;
expect(error.code).to.equal('EINVAL');
done();
});
});
it('should make a new directory', function(done) {
var fs = util.fs();
fs.mknod('/dir', 'DIRECTORY', function(error) {
if(error) throw error;
fs.stat('/dir', function(error, stats) {
expect(error).not.to.exist;
expect(stats.type).to.equal('DIRECTORY');
done();
});
});
});
it('should make a new file', function(done) {
var fs = util.fs();
fs.mknod('/file', 'FILE' , function(error, result) {
if(error) throw error;
fs.stat('/file', function(error, result) {
expect(error).not.to.exist;
expect(result.type).to.equal('FILE');
done();
});
});
});
});
});

View File

@ -13,6 +13,7 @@ define([
"spec/fs.stat.spec",
"spec/fs.lstat.spec",
"spec/fs.exists.spec",
"spec/fs.mknod.spec",
"spec/fs.mkdir.spec",
"spec/fs.readdir.spec",
"spec/fs.rmdir.spec",