Browse files

Support octal strings for modes

This allows the various fs utilities and process.umask to be used in
ECMAScript 5 Strict Mode, where the octal literal format is verboten,
without requiring users to litter their code with a bunch of parseInt
calls.
  • Loading branch information...
1 parent 57fa247 commit 5f2e90934e523b2fe102e3e5bae3ea76535ab8b5 @isaacs isaacs committed with ry Jan 25, 2011
Showing with 52 additions and 19 deletions.
  1. +22 −9 lib/fs.js
  2. +27 −7 src/node.cc
  3. +1 −1 test/simple/test-fs-chmod.js
  4. +2 −2 test/simple/test-umask.js
View
31 lib/fs.js
@@ -171,16 +171,29 @@ fs.closeSync = function(fd) {
return binding.close(fd);
};
-fs.open = function(path, flags, mode_, callback) {
- var mode = (typeof(mode_) == 'number' ? mode_ : 0666);
+function modeNum(m, def) {
+ switch(typeof m) {
+ case 'number': return m;
+ case 'string': return parseInt(m, 8);
+ default:
+ if (def) {
+ return modeNum(def);
+ } else {
+ return undefined;
+ }
+ }
+}
+
+fs.open = function(path, flags, mode, callback) {
+ mode = modeNum(mode, '0666');
var callback_ = arguments[arguments.length - 1];
var callback = (typeof(callback_) == 'function' ? callback_ : null);
binding.open(path, stringToFlags(flags), mode, callback || noop);
};
fs.openSync = function(path, flags, mode) {
- if (mode === undefined) { mode = 0666; }
+ mode = modeNum(mode, '0666');
return binding.open(path, stringToFlags(flags), mode);
};
@@ -306,11 +319,11 @@ fs.fsyncSync = function(fd) {
};
fs.mkdir = function(path, mode, callback) {
- binding.mkdir(path, mode, callback || noop);
+ binding.mkdir(path, modeNum(mode), callback || noop);
};
fs.mkdirSync = function(path, mode) {
- return binding.mkdir(path, mode);
+ return binding.mkdir(path, modeNum(mode));
};
fs.sendfile = function(outFd, inFd, inOffset, length, callback) {
@@ -386,11 +399,11 @@ fs.unlinkSync = function(path) {
};
fs.chmod = function(path, mode, callback) {
- binding.chmod(path, mode, callback || noop);
+ binding.chmod(path, modeNum(mode), callback || noop);
};
fs.chmodSync = function(path, mode) {
- return binding.chmod(path, mode);
+ return binding.chmod(path, modeNum(mode));
};
fs.chown = function(path, uid, gid, callback) {
@@ -684,7 +697,7 @@ var ReadStream = fs.ReadStream = function(path, options) {
this.paused = false;
this.flags = 'r';
- this.mode = 0666;
+ this.mode = parseInt('0666', 8);
this.bufferSize = 64 * 1024;
options = options || {};
@@ -871,7 +884,7 @@ var WriteStream = fs.WriteStream = function(path, options) {
this.flags = 'w';
this.encoding = 'binary';
- this.mode = 0666;
+ this.mode = parseInt('0666', 8);
options = options || {};
View
34 src/node.cc
@@ -1329,17 +1329,37 @@ static Handle<Value> Cwd(const Arguments& args) {
static Handle<Value> Umask(const Arguments& args){
HandleScope scope;
unsigned int old;
- if(args.Length() < 1) {
+
+ if(args.Length() < 1 || args[0]->IsUndefined()) {
old = umask(0);
umask((mode_t)old);
- }
- else if(!args[0]->IsInt32()) {
+
+ } else if(!args[0]->IsInt32() && !args[0]->IsString()) {
return ThrowException(Exception::TypeError(
- String::New("argument must be an integer.")));
- }
- else {
- old = umask((mode_t)args[0]->Uint32Value());
+ String::New("argument must be an integer or octal string.")));
+
+ } else {
+ int oct;
+ if(args[0]->IsInt32()) {
+ oct = args[0]->Uint32Value();
+ } else {
+ oct = 0;
+ String::Utf8Value str(args[0]);
+
+ // Parse the octal string.
+ for (int i = 0; i < str.length(); i++) {
+ char c = (*str)[i];
+ if (c > '7' || c < '0') {
+ return ThrowException(Exception::TypeError(
+ String::New("invalid octal string")));
+ }
+ oct *= 8;
+ oct += c - '0';
+ }
+ }
+ old = umask(static_cast<mode_t>(oct));
}
+
return scope.Close(Uint32::New(old));
}
View
2 test/simple/test-fs-chmod.js
@@ -7,7 +7,7 @@ var success_count = 0;
var file = path.join(common.fixturesDir, 'a.js');
-fs.chmod(file, 0777, function(err) {
+fs.chmod(file, '0777', function(err) {
if (err) {
got_error = true;
} else {
View
4 test/simple/test-umask.js
@@ -1,10 +1,10 @@
var common = require('../common');
var assert = require('assert');
-var mask = 0664;
+var mask = '0664';
var old = process.umask(mask);
-assert.equal(mask, process.umask(old));
+assert.equal(parseInt(mask, 8), process.umask(old));
// confirm reading the umask does not modify it.
// 1. If the test fails, this call will succeed, but the mask will be set to 0

0 comments on commit 5f2e909

Please sign in to comment.