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);
|
return binding.close(fd);
|
||||||
};
|
};
|
||||||
|
|
||||||
fs.open = function(path, flags, mode_, callback) {
|
function modeNum(m, def) {
|
||||||
var mode = (typeof(mode_) == 'number' ? mode_ : 0666);
|
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_ = arguments[arguments.length - 1];
|
||||||
var callback = (typeof(callback_) == 'function' ? callback_ : null);
|
var callback = (typeof(callback_) == 'function' ? callback_ : null);
|
||||||
|
|
||||||
@ -180,7 +193,7 @@ fs.open = function(path, flags, mode_, callback) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
fs.openSync = function(path, flags, mode) {
|
fs.openSync = function(path, flags, mode) {
|
||||||
if (mode === undefined) { mode = 0666; }
|
mode = modeNum(mode, '0666');
|
||||||
return binding.open(path, stringToFlags(flags), mode);
|
return binding.open(path, stringToFlags(flags), mode);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -306,11 +319,11 @@ fs.fsyncSync = function(fd) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
fs.mkdir = function(path, mode, callback) {
|
fs.mkdir = function(path, mode, callback) {
|
||||||
binding.mkdir(path, mode, callback || noop);
|
binding.mkdir(path, modeNum(mode), callback || noop);
|
||||||
};
|
};
|
||||||
|
|
||||||
fs.mkdirSync = function(path, mode) {
|
fs.mkdirSync = function(path, mode) {
|
||||||
return binding.mkdir(path, mode);
|
return binding.mkdir(path, modeNum(mode));
|
||||||
};
|
};
|
||||||
|
|
||||||
fs.sendfile = function(outFd, inFd, inOffset, length, callback) {
|
fs.sendfile = function(outFd, inFd, inOffset, length, callback) {
|
||||||
@ -386,11 +399,11 @@ fs.unlinkSync = function(path) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
fs.chmod = function(path, mode, callback) {
|
fs.chmod = function(path, mode, callback) {
|
||||||
binding.chmod(path, mode, callback || noop);
|
binding.chmod(path, modeNum(mode), callback || noop);
|
||||||
};
|
};
|
||||||
|
|
||||||
fs.chmodSync = function(path, mode) {
|
fs.chmodSync = function(path, mode) {
|
||||||
return binding.chmod(path, mode);
|
return binding.chmod(path, modeNum(mode));
|
||||||
};
|
};
|
||||||
|
|
||||||
fs.chown = function(path, uid, gid, callback) {
|
fs.chown = function(path, uid, gid, callback) {
|
||||||
@ -684,7 +697,7 @@ var ReadStream = fs.ReadStream = function(path, options) {
|
|||||||
this.paused = false;
|
this.paused = false;
|
||||||
|
|
||||||
this.flags = 'r';
|
this.flags = 'r';
|
||||||
this.mode = 0666;
|
this.mode = parseInt('0666', 8);
|
||||||
this.bufferSize = 64 * 1024;
|
this.bufferSize = 64 * 1024;
|
||||||
|
|
||||||
options = options || {};
|
options = options || {};
|
||||||
@ -871,7 +884,7 @@ var WriteStream = fs.WriteStream = function(path, options) {
|
|||||||
|
|
||||||
this.flags = 'w';
|
this.flags = 'w';
|
||||||
this.encoding = 'binary';
|
this.encoding = 'binary';
|
||||||
this.mode = 0666;
|
this.mode = parseInt('0666', 8);
|
||||||
|
|
||||||
options = options || {};
|
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){
|
static Handle<Value> Umask(const Arguments& args){
|
||||||
HandleScope scope;
|
HandleScope scope;
|
||||||
unsigned int old;
|
unsigned int old;
|
||||||
if(args.Length() < 1) {
|
|
||||||
|
if(args.Length() < 1 || args[0]->IsUndefined()) {
|
||||||
old = umask(0);
|
old = umask(0);
|
||||||
umask((mode_t)old);
|
umask((mode_t)old);
|
||||||
}
|
|
||||||
else if(!args[0]->IsInt32()) {
|
} else if(!args[0]->IsInt32() && !args[0]->IsString()) {
|
||||||
return ThrowException(Exception::TypeError(
|
return ThrowException(Exception::TypeError(
|
||||||
String::New("argument must be an integer.")));
|
String::New("argument must be an integer or octal string.")));
|
||||||
}
|
|
||||||
else {
|
} else {
|
||||||
old = umask((mode_t)args[0]->Uint32Value());
|
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));
|
return scope.Close(Uint32::New(old));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ var success_count = 0;
|
|||||||
|
|
||||||
var file = path.join(common.fixturesDir, 'a.js');
|
var file = path.join(common.fixturesDir, 'a.js');
|
||||||
|
|
||||||
fs.chmod(file, 0777, function(err) {
|
fs.chmod(file, '0777', function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
got_error = true;
|
got_error = true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
var common = require('../common');
|
var common = require('../common');
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
|
|
||||||
var mask = 0664;
|
var mask = '0664';
|
||||||
var old = process.umask(mask);
|
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.
|
// 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
|
// 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