src: don't error at startup when cwd doesn't exist
authorBen Noordhuis <info@bnoordhuis.nl>
Wed, 18 Mar 2015 21:11:14 +0000 (22:11 +0100)
committerBen Noordhuis <info@bnoordhuis.nl>
Thu, 19 Mar 2015 01:10:36 +0000 (02:10 +0100)
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 <bugs@bergstroem.nu>
Reviewed-By: Rod Vagg <rod@vagg.org>
src/node.js
test/parallel/test-cwd-enoent.js [new file with mode: 0644]
test/parallel/test-process-argv-0.js

index dc77b53..9366086 100644 (file)
@@ -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
   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);
     };
   };
 
-
-  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 (file)
index 0000000..6e7b02c
--- /dev/null
@@ -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);
+}));
index a543050..daf8cb6 100644 (file)
@@ -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 {