Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

fs: make file paths absolute before operation

Make file paths absolute before starting the fs operation. Avoids chdir() races
like in the test case below:

  // test.js
  for (var i = 0; i < 10; i++) {
    require('fs').open('test.js', function(err, fd) {
      if (err) throw err;
    });
  }
  process.chdir('/');

Before this commit, such code would sometimes fail because the chdir() is
executed inside the main thread while the open() operations run concurrently
in the thread pool.

Fixes #618.
  • Loading branch information...
commit 3cee989b829443525ce20dac014f8dc0813dddcf 1 parent c81dec7
Ben Noordhuis authored
4 lib/path.js
View
@@ -469,7 +469,5 @@ if (isWindows) {
return path;
};
} else {
- exports._makeLong = function(path) {
- return path;
- };
+ exports._makeLong = exports.resolve;
}
42 test/simple/test-domain.js
View
@@ -69,26 +69,6 @@ d.on('error', function(er) {
assert.equal(er.domain_thrown, true);
break;
- case "ENOENT, open 'this file does not exist'":
- assert.equal(er.domain, d);
- assert.equal(er.domain_thrown, false);
- assert.equal(typeof er.domain_bound, 'function');
- assert.ok(!er.domain_emitter);
- assert.equal(er.code, 'ENOENT');
- assert.equal(er_path, 'this file does not exist');
- assert.equal(typeof er.errno, 'number');
- break;
-
- case "ENOENT, open 'stream for nonexistent file'":
- assert.equal(typeof er.errno, 'number');
- assert.equal(er.code, 'ENOENT');
- assert.equal(er_path, 'stream for nonexistent file');
- assert.equal(er.domain, d);
- assert.equal(er.domain_emitter, fst);
- assert.ok(!er.domain_bound);
- assert.equal(er.domain_thrown, false);
- break;
-
case 'implicit':
assert.equal(er.domain_emitter, implicit);
assert.equal(er.domain, d);
@@ -110,6 +90,28 @@ d.on('error', function(er) {
break;
default:
+ if (/ENOENT, open '.*\/this file does not exist'/.test(er_message)) {
+ assert.equal(er.domain, d);
+ assert.equal(er.domain_thrown, false);
+ assert.equal(typeof er.domain_bound, 'function');
+ assert.ok(!er.domain_emitter);
+ assert.equal(er.code, 'ENOENT');
+ assert.equal(/this file does not exist/.test(er_path), true);
+ assert.equal(typeof er.errno, 'number');
+ break;
+ }
+
+ if (/ENOENT, open '.*\/stream for nonexistent file'/.test(er_message)) {
+ assert.equal(typeof er.errno, 'number');
+ assert.equal(er.code, 'ENOENT');
+ assert.equal(/stream for nonexistent file/.test(er_path), true);
+ assert.equal(er.domain, d);
+ assert.equal(er.domain_emitter, fst);
+ assert.ok(!er.domain_bound);
+ assert.equal(er.domain_thrown, false);
+ break;
+ }
+
console.error('unexpected error, throwing %j', er.message);
throw er;
}
38 test/simple/test-fs-chdir-race.js
View
@@ -0,0 +1,38 @@
+// Copyright Joyent, Inc. and other Node contributors.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to permit
+// persons to whom the Software is furnished to do so, subject to the
+// following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+// USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+var common = require('../common');
+var fs = require('fs');
+var path = require('path');
+
+var cwd = process.cwd();
+var filename = path.relative(cwd, __filename);
+
+for (var i = 0; i < 1000; i++) {
+ process.chdir(cwd);
+
+ fs.open(filename, 'r', function(err, fd) {
+ if (err) throw err;
+ fs.close(fd);
+ });
+
+ process.chdir('/');
+}
Please sign in to comment.
Something went wrong with that request. Please try again.