diff --git a/README.md b/README.md
index 04d8da8..2432077 100644
--- a/README.md
+++ b/README.md
@@ -305,6 +305,7 @@ var fs = new Filer.FileSystem();
* [fs.mknod(path, mode, callback)](#mknod)
* [fs.rmdir(path, callback)](#rmdir)
* [fs.mkdir(path, [mode], callback)](#mkdir)
+* [fs.access(path, [mode], callback)](#access)
* [fs.readdir(path, callback)](#readdir)
* [fs.close(fd, callback)](#close)
* [fs.open(path, flags, [mode], callback)](#open)
@@ -672,6 +673,26 @@ fs.mkdir('/home', function(err) {
});
```
+#### fs.access(path, [mode], callback)
+
+Tests a user's permissions for the file or directory supplied in `path` argument. Asynchronous [access(2)](http://pubs.opengroup.org/onlinepubs/009695399/functions/access.html). Callback gets no additional arguments. The `mode` argument can be one of the following (constants are available on `fs.constants`):
+
+* `F_OK`: Test for existence of file.
+* `R_OK`: Test whether the file exists and grants read permission.
+* `W_OK`: Test whether the file exists and grants write permission.
+* `X_OK`: Test whether the file exists and grants execute permission.
+
+NOTE: you can also create a mask consisting of the bitwise OR of two or more values (e.g. `fs.constants.W_OK | fs.constants.R_OK`).
+
+Example:
+
+```javascript
+// Check if the file exists in the current directory.
+fs.access(file, fs.constants.F_OK, function(err) {
+ console.log(`${file} ${err ? 'does not exist' : 'exists'}`);
+});
+```
+
#### fs.readdir(path, callback)
Reads the contents of a directory. Asynchronous [readdir(3)](http://pubs.opengroup.org/onlinepubs/009695399/functions/readdir.html).
diff --git a/src/filesystem/implementation.js b/src/filesystem/implementation.js
index 2511e3f..88fa6c6 100644
--- a/src/filesystem/implementation.js
+++ b/src/filesystem/implementation.js
@@ -441,6 +441,20 @@ function make_directory(context, path, callback) {
find_node(context, path, check_if_directory_exists);
}
+function access_file(context, path, mode, callback) {
+ path = normalize(path);
+ find_node(context, path, function (err) {
+ if (err) {
+ return callback(err);
+ }
+ /*
+ TODO: we currently only support Constants.fsConstants.F_OK
+ Working to fix the issue: https://github.com/filerjs/filer/issues/561
+ */
+ callback(null);
+ });
+}
+
/**
* remove_directory
*/
@@ -1685,6 +1699,17 @@ function mkdir(fs, context, path, mode, callback) {
make_directory(context, path, callback);
}
+function access(fs, context, path, mode, callback) {
+ if (typeof mode === 'function') {
+ callback = mode;
+ mode = Constants.fsConstants.F_OK;
+ }
+
+ if (!pathCheck(path, callback)) return;
+ mode = mode | 0;
+ access_file(context, path, mode, callback);
+}
+
function rmdir(fs, context, path, callback) {
if(!pathCheck(path, callback)) return;
remove_directory(context, path, callback);
@@ -2385,6 +2410,7 @@ module.exports = {
ensureRootDirectory: ensure_root_directory,
open: open,
chmod: chmod,
+ access: access,
fchmod: fchmod,
chown: chown,
fchown: fchown,
diff --git a/src/filesystem/interface.js b/src/filesystem/interface.js
index 0c6b331..98e6d8b 100644
--- a/src/filesystem/interface.js
+++ b/src/filesystem/interface.js
@@ -269,6 +269,7 @@ function FileSystem(options, callback) {
*/
[
'open',
+ 'access',
'chmod',
'fchmod',
'chown',
diff --git a/tests/index.js b/tests/index.js
index 9a6b9dc..3d053d4 100644
--- a/tests/index.js
+++ b/tests/index.js
@@ -9,6 +9,7 @@ require('./spec/filer.spec');
// Filer.FileSystem.*
require('./spec/filer.filesystem.spec');
require('./spec/fs.spec');
+require('./spec/fs.access.spec');
require('./spec/fs.stat.spec');
require('./spec/fs.lstat.spec');
require('./spec/fs.exists.spec');
diff --git a/tests/spec/fs.access.spec.js b/tests/spec/fs.access.spec.js
new file mode 100644
index 0000000..da8ae73
--- /dev/null
+++ b/tests/spec/fs.access.spec.js
@@ -0,0 +1,37 @@
+var util = require('../lib/test-utils.js');
+var expect = require('chai').expect;
+
+describe('fs.access', function () {
+ beforeEach(util.setup);
+ afterEach(util.cleanup);
+
+ it('should be a function', function () {
+ var fs = util.fs();
+ expect(typeof fs.access).to.equal('function');
+ });
+
+ it('should return an error if file does not exist', function (done) {
+ var fs = util.fs();
+
+ fs.access('/tmp', fs.constants.F_OK, function (error) {
+ expect(error).to.exist;
+ expect(error.code).to.equal('ENOENT');
+ done();
+ });
+ });
+
+ it('should return no error if file does exist', function (done) {
+ var fs = util.fs();
+ var contents = 'This is a file.';
+
+ fs.writeFile('/myfile', contents, function (error) {
+ if (error) throw error;
+
+ fs.access('/myfile', fs.constants.F_OK, function (error) {
+ expect(error).not.to.exist;
+ done();
+ });
+ });
+ });
+
+});