Browse Source

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.
v0.7.4-release
isaacs 14 years ago
committed by Ryan Dahl
parent
commit
5f2e90934e
  1. 31
      lib/fs.js
  2. 32
      src/node.cc
  3. 2
      test/simple/test-fs-chmod.js
  4. 4
      test/simple/test-umask.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 || {};

32
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(
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( return ThrowException(Exception::TypeError(
String::New("argument must be an integer."))); String::New("invalid octal string")));
} }
else { oct *= 8;
old = umask((mode_t)args[0]->Uint32Value()); oct += c - '0';
} }
}
old = umask(static_cast<mode_t>(oct));
}
return scope.Close(Uint32::New(old)); return scope.Close(Uint32::New(old));
} }

2
test/simple/test-fs-chmod.js

@ -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 {

4
test/simple/test-umask.js

@ -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…
Cancel
Save