From 2c6f79c08cba4e7adee9de2283c7d08cf977adcb Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Wed, 18 Mar 2015 22:11:14 +0100 Subject: [PATCH] src: don't error at startup when cwd doesn't exist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current working directory may not exist when iojs starts up. Don't treat that as an error because it's still possible to do many useful things, like evaluating a command line script or starting a REPL. This commit also fixes an age-old Windows bug where process.argv[0] was not properly expanded, that's why the parallel/test-process-argv-0 test gets an update as well. Fixes: https://github.com/iojs/io.js/issues/1184 PR-URL: https://github.com/iojs/io.js/pull/1194 Reviewed-By: Johan Bergström Reviewed-By: Rod Vagg --- src/node.js | 29 ++++++++++------------------ test/parallel/test-cwd-enoent.js | 24 +++++++++++++++++++++++ test/parallel/test-process-argv-0.js | 7 +------ 3 files changed, 35 insertions(+), 25 deletions(-) create mode 100644 test/parallel/test-cwd-enoent.js diff --git a/src/node.js b/src/node.js index dc77b53dcae955..93660867f30b37 100644 --- a/src/node.js +++ b/src/node.js @@ -43,7 +43,7 @@ startup.processRawDebug(); - startup.resolveArgv0(); + process.argv[0] = process.execPath; // There are various modes that Node can run in. The most common two // are running from a script and running the REPL - but there are a few @@ -459,7 +459,15 @@ function evalScript(name) { var Module = NativeModule.require('module'); var path = NativeModule.require('path'); - var cwd = process.cwd(); + + try { + var cwd = process.cwd(); + } catch (e) { + // getcwd(3) can fail if the current working directory has been deleted. + // Fall back to the directory name of the (absolute) executable path. + // It's not really correct but what are the alternatives? + var cwd = path.dirname(process.execPath); + } var module = new Module(name); module.filename = path.join(cwd, name); @@ -764,23 +772,6 @@ }; }; - - startup.resolveArgv0 = function() { - var cwd = process.cwd(); - var isWindows = process.platform === 'win32'; - - // Make process.argv[0] into a full path, but only touch argv[0] if it's - // not a system $PATH lookup. - // TODO: Make this work on Windows as well. Note that "node" might - // execute cwd\node.exe, or some %PATH%\node.exe on Windows, - // and that every directory has its own cwd, so d:node.exe is valid. - var argv0 = process.argv[0]; - if (!isWindows && argv0.indexOf('/') !== -1 && argv0.charAt(0) !== '/') { - var path = NativeModule.require('path'); - process.argv[0] = path.join(cwd, process.argv[0]); - } - }; - // Below you find a minimal module system, which is used to load the node // core modules found in lib/*.js. All core modules are compiled into the // node binary, so they can be loaded faster. diff --git a/test/parallel/test-cwd-enoent.js b/test/parallel/test-cwd-enoent.js new file mode 100644 index 00000000000000..6e7b02c85d8d12 --- /dev/null +++ b/test/parallel/test-cwd-enoent.js @@ -0,0 +1,24 @@ +var common = require('../common'); +var assert = require('assert'); +var fs = require('fs'); +var spawn = require('child_process').spawn; + +// Fails with EINVAL on SmartOS, EBUSY on Windows. +if (process.platform === 'sunos' || process.platform === 'win32') { + console.log('1..0 # Skipped: cannot rmdir current working directory'); + return; +} + +var dirname = common.tmpDir + '/cwd-does-not-exist-' + process.pid; +fs.mkdirSync(dirname); +process.chdir(dirname); +fs.rmdirSync(dirname); + +var proc = spawn(process.execPath, ['-e', '0']); +proc.stdout.pipe(process.stdout); +proc.stderr.pipe(process.stderr); + +proc.once('exit', common.mustCall(function(exitCode, signalCode) { + assert.equal(exitCode, 0); + assert.equal(signalCode, null); +})); diff --git a/test/parallel/test-process-argv-0.js b/test/parallel/test-process-argv-0.js index a5430509dabcd1..daf8cb60ebff0d 100644 --- a/test/parallel/test-process-argv-0.js +++ b/test/parallel/test-process-argv-0.js @@ -22,12 +22,7 @@ if (process.argv[2] !== "child") { }); child.on('exit', function () { console.error('CHILD: %s', childErr.trim().split('\n').join('\nCHILD: ')); - if (process.platform === 'win32') { - // On Windows argv[0] is not expanded into full path - assert.equal(childArgv0, './iojs'); - } else { - assert.equal(childArgv0, process.execPath); - } + assert.equal(childArgv0, process.execPath); }); } else {