Created
March 29, 2011 23:35
-
-
Save isaacs/893568 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From b528e076cedc7c37a9eaea7c635eebbf7a50f25f Mon Sep 17 00:00:00 2001 | |
From: isaacs <i@izs.me> | |
Date: Tue, 29 Mar 2011 15:31:41 -0700 | |
Subject: [PATCH 1/2] 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 062b4a3..bfa6ebf 100644 | |
--- a/lib/fs.js | |
+++ b/lib/fs.js | |
@@ -422,6 +422,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); | |
}; | |
@@ -430,6 +438,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 8b7f374..4b23c4f 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; | |
@@ -799,7 +801,7 @@ static Handle<Value> Read(const Arguments& args) { | |
} | |
-/* fs.chmod(fd, mode); | |
+/* fs.chmod(path, mode); | |
* Wrapper for chmod(1) / EIO_CHMOD | |
*/ | |
static Handle<Value> Chmod(const Arguments& args) { | |
@@ -815,16 +817,38 @@ static Handle<Value> 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<Value> 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<mode_t>(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<Value> Chown(const Arguments& args) { | |
HandleScope scope; | |
@@ -844,7 +868,37 @@ static Handle<Value> 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<Value> 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<uid_t>(args[1]->Int32Value()); | |
+ gid_t gid = static_cast<gid_t>(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(); | |
} | |
} | |
@@ -955,8 +1009,13 @@ void File::Initialize(Handle<Object> 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 7616c8b..12afc47 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, 'w', 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); | |
}); | |
-- | |
1.7.2.3 | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 84d5deae3798daf3fd7c5560c0c17fada99eb60c Mon Sep 17 00:00:00 2001 | |
From: isaacs <i@izs.me> | |
Date: Tue, 29 Mar 2011 16:34:05 -0700 | |
Subject: [PATCH 2/2] GH-853 fs.lchown and fs.lchmod | |
--- | |
lib/fs.js | 37 +++++++++++++++++++++++++++++++++++++ | |
src/node_constants.cc | 5 +++++ | |
2 files changed, 42 insertions(+), 0 deletions(-) | |
diff --git a/lib/fs.js b/lib/fs.js | |
index bfa6ebf..aba2940 100644 | |
--- a/lib/fs.js | |
+++ b/lib/fs.js | |
@@ -430,6 +430,25 @@ fs.fchmodSync = function(fd, mode) { | |
return binding.fchmod(fd, modeNum(mode)); | |
}; | |
+if (constants.hasOwnProperty('O_SYMLINK')) { | |
+ fs.lchmod = function(path, mode, callback) { | |
+ callback = callback || noop; | |
+ fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function (err, fd) { | |
+ if (err) { | |
+ callback(err); | |
+ return; | |
+ } | |
+ fs.fchmod(fd, mode, callback); | |
+ }); | |
+ }; | |
+ | |
+ fs.lchmodSync = function(path, mode) { | |
+ var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK); | |
+ return fs.fchmodSync(fd, mode); | |
+ }; | |
+} | |
+ | |
+ | |
fs.chmod = function(path, mode, callback) { | |
binding.chmod(path, modeNum(mode), callback || noop); | |
}; | |
@@ -438,6 +457,24 @@ fs.chmodSync = function(path, mode) { | |
return binding.chmod(path, modeNum(mode)); | |
}; | |
+if (constants.hasOwnProperty('O_SYMLINK')) { | |
+ fs.lchown = function(path, uid, gid, callback) { | |
+ callback = callback || noop; | |
+ fs.open(path, constants.O_WRONLY | constants.O_SYMLINK, function (err, fd) { | |
+ if (err) { | |
+ callback(err); | |
+ return; | |
+ } | |
+ fs.fchown(fd, uid, gid, callback); | |
+ }); | |
+ }; | |
+ | |
+ fs.lchownSync = function(path, uid, gid) { | |
+ var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK); | |
+ return fs.fchownSync(fd, uid, gid); | |
+ }; | |
+} | |
+ | |
fs.fchown = function(fd, uid, gid, callback) { | |
binding.fchown(fd, uid, gid, callback || noop); | |
}; | |
diff --git a/src/node_constants.cc b/src/node_constants.cc | |
index ecb34a6..832b9e4 100644 | |
--- a/src/node_constants.cc | |
+++ b/src/node_constants.cc | |
@@ -99,6 +99,11 @@ void DefineConstants(Handle<Object> target) { | |
NODE_DEFINE_CONSTANT(target, O_SYNC); | |
#endif | |
+#ifdef O_SYMLINK | |
+ NODE_DEFINE_CONSTANT(target, O_SYMLINK); | |
+#endif | |
+ | |
+ | |
#ifdef S_IRWXU | |
NODE_DEFINE_CONSTANT(target, S_IRWXU); | |
#endif | |
-- | |
1.7.2.3 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment