From ca2ad16f1f63a198ee01e74a81e30f8bdd9f114c Mon Sep 17 00:00:00 2001 From: isaacs Date: Tue, 29 Mar 2011 15:31:41 -0700 Subject: [PATCH] GH-853 fs.fchmod and fs.fchown --- lib/fs.js | 16 +++++++++ src/node_file.cc | 69 +++++++++++++++++++++++++++++++++--- test/simple/test-fs-chmod.js | 22 +++++++++++- 3 files changed, 101 insertions(+), 6 deletions(-) diff --git a/lib/fs.js b/lib/fs.js index f73327bc997..2771ae1ab88 100644 --- a/lib/fs.js +++ b/lib/fs.js @@ -432,6 +432,14 @@ fs.unlinkSync = function(path) { return binding.unlink(path); }; +fs.fchmod = function(fd, mode, callback) { + binding.fchmod(fd, modeNum(mode), callback || noop); +}; + +fs.fchmodSync = function(fd, mode) { + return binding.fchmod(fd, modeNum(mode)); +}; + fs.chmod = function(path, mode, callback) { binding.chmod(path, modeNum(mode), callback || noop); }; @@ -440,6 +448,14 @@ fs.chmodSync = function(path, mode) { return binding.chmod(path, modeNum(mode)); }; +fs.fchown = function(fd, uid, gid, callback) { + binding.fchown(fd, uid, gid, callback || noop); +}; + +fs.fchownSync = function(fd, uid, gid) { + return binding.fchown(fd, uid, gid); +}; + fs.chown = function(path, uid, gid, callback) { binding.chown(path, uid, gid, callback || noop); }; diff --git a/src/node_file.cc b/src/node_file.cc index ba24be1c4af..5103691bb71 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -126,7 +126,9 @@ static int After(eio_req *req) { case EIO_LINK: case EIO_SYMLINK: case EIO_CHMOD: + case EIO_FCHMOD: case EIO_CHOWN: + case EIO_FCHOWN: // These, however, don't. argc = 1; break; @@ -792,7 +794,7 @@ static Handle Read(const Arguments& args) { } -/* fs.chmod(fd, mode); +/* fs.chmod(path, mode); * Wrapper for chmod(1) / EIO_CHMOD */ static Handle Chmod(const Arguments& args) { @@ -808,16 +810,38 @@ static Handle Chmod(const Arguments& args) { ASYNC_CALL(chmod, args[2], *path, mode); } else { int ret = chmod(*path, mode); - if (ret != 0) return ThrowException(ErrnoException(errno, NULL, "", *path)); + if (ret != 0) return ThrowException(ErrnoException(errno, "chmod", "", *path)); return Undefined(); } } -/* fs.chown(fd, uid, gid); - * Wrapper for chown(1) / EIO_CHOWN +/* fs.fchmod(fd, mode); + * Wrapper for fchmod(1) / EIO_FCHMOD */ +static Handle FChmod(const Arguments& args) { + HandleScope scope; + + if(args.Length() < 2 || !args[0]->IsInt32() || !args[1]->IsInt32()) { + return THROW_BAD_ARGS; + } + int fd = args[0]->Int32Value(); + mode_t mode = static_cast(args[1]->Int32Value()); + + if(args[2]->IsFunction()) { + ASYNC_CALL(fchmod, args[2], fd, mode); + } else { + int ret = fchmod(fd, mode); + if (ret != 0) return ThrowException(ErrnoException(errno, "fchmod", "", 0)); + return Undefined(); + } +} + + #ifdef __POSIX__ +/* fs.chown(path, uid, gid); + * Wrapper for chown(1) / EIO_CHOWN + */ static Handle Chown(const Arguments& args) { HandleScope scope; @@ -837,7 +861,37 @@ static Handle Chown(const Arguments& args) { ASYNC_CALL(chown, args[3], *path, uid, gid); } else { int ret = chown(*path, uid, gid); - if (ret != 0) return ThrowException(ErrnoException(errno, NULL, "", *path)); + if (ret != 0) return ThrowException(ErrnoException(errno, "chown", "", *path)); + return Undefined(); + } +} +#endif // __POSIX__ + + +#ifdef __POSIX__ +/* fs.fchown(fd, uid, gid); + * Wrapper for fchown(1) / EIO_FCHOWN + */ +static Handle FChown(const Arguments& args) { + HandleScope scope; + + if (args.Length() < 3 || !args[0]->IsInt32()) { + return THROW_BAD_ARGS; + } + + if (!args[1]->IsInt32() || !args[2]->IsInt32()) { + return ThrowException(Exception::Error(String::New("User and Group IDs must be an integer."))); + } + + int fd = args[0]->Int32Value(); + uid_t uid = static_cast(args[1]->Int32Value()); + gid_t gid = static_cast(args[2]->Int32Value()); + + if (args[3]->IsFunction()) { + ASYNC_CALL(fchown, args[3], fd, uid, gid); + } else { + int ret = fchown(fd, uid, gid); + if (ret != 0) return ThrowException(ErrnoException(errno, "fchown", "", 0)); return Undefined(); } } @@ -948,8 +1002,13 @@ void File::Initialize(Handle target) { NODE_SET_METHOD(target, "write", Write); NODE_SET_METHOD(target, "chmod", Chmod); + NODE_SET_METHOD(target, "fchmod", FChmod); #ifdef __POSIX__ + //NODE_SET_METHOD(target, "lchmod", LChmod); + NODE_SET_METHOD(target, "chown", Chown); + NODE_SET_METHOD(target, "fchown", FChown); + //NODE_SET_METHOD(target, "lchown", LChown); #endif // __POSIX__ NODE_SET_METHOD(target, "utimes", UTimes); diff --git a/test/simple/test-fs-chmod.js b/test/simple/test-fs-chmod.js index 7616c8b3f87..f9e7786a88f 100644 --- a/test/simple/test-fs-chmod.js +++ b/test/simple/test-fs-chmod.js @@ -41,8 +41,28 @@ fs.chmod(file, '0777', function(err) { } }); +fs.open(file, 'a', function(err, fd) { + if (err) { + got_error = true; + console.error(err.stack); + return; + } + fs.fchmod(fd, '0777', function(err) { + if (err) { + got_error = true; + } else { + console.log(fs.fstatSync(fd).mode); + assert.equal(0777, fs.fstatSync(fd).mode & 0777); + + fs.fchmodSync(fd, 0644); + assert.equal(0644, fs.fstatSync(fd).mode & 0777); + success_count++; + } + }); +}); + process.addListener('exit', function() { - assert.equal(1, success_count); + assert.equal(2, success_count); assert.equal(false, got_error); });