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.
This commit is contained in:
parent
57fa247f53
commit
5f2e90934e
31
lib/fs.js
31
lib/fs.js
@ -171,8 +171,21 @@ 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);
|
||||
|
||||
@ -180,7 +193,7 @@ fs.open = function(path, flags, mode_, callback) {
|
||||
};
|
||||
|
||||
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 || {};
|
||||
|
||||
|
34
src/node.cc
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));
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user