child_process_uv: Handle spawn errors
authorRyan Dahl <ry@tinyclouds.org>
Mon, 1 Aug 2011 17:19:41 +0000 (10:19 -0700)
committerRyan Dahl <ry@tinyclouds.org>
Mon, 1 Aug 2011 17:22:24 +0000 (10:22 -0700)
deps/uv/src/win/process.c
lib/child_process_uv.js

index 81bb430e0ad0dc0992a80b8600e6e2553e620f42..f2943f81a017123134125de05b6c946da2575f5e 100644 (file)
@@ -680,7 +680,9 @@ int uv_spawn(uv_process_t* process, uv_process_options_t options) {
 
   /* Create stdio pipes. */
   if (options.stdin_stream) {
-    err = uv_create_stdio_pipe_pair(options.stdin_stream, &process->stdio_pipes[0].child_pipe, PIPE_ACCESS_OUTBOUND, GENERIC_READ | FILE_WRITE_ATTRIBUTES);
+    err = uv_create_stdio_pipe_pair(options.stdin_stream,
+        &process->stdio_pipes[0].child_pipe, PIPE_ACCESS_OUTBOUND,
+        GENERIC_READ | FILE_WRITE_ATTRIBUTES);
     if (err) {
       goto done;
     }
@@ -689,7 +691,9 @@ int uv_spawn(uv_process_t* process, uv_process_options_t options) {
   }
 
   if (options.stdout_stream) {
-    err = uv_create_stdio_pipe_pair(options.stdout_stream, &process->stdio_pipes[1].child_pipe, PIPE_ACCESS_INBOUND, GENERIC_WRITE);
+    err = uv_create_stdio_pipe_pair(options.stdout_stream,
+        &process->stdio_pipes[1].child_pipe, PIPE_ACCESS_INBOUND,
+        GENERIC_WRITE);
     if (err) {
       goto done;
     }
@@ -698,7 +702,9 @@ int uv_spawn(uv_process_t* process, uv_process_options_t options) {
   }
 
   if (options.stderr_stream) {
-    err = uv_create_stdio_pipe_pair(options.stderr_stream, &process->stdio_pipes[2].child_pipe, PIPE_ACCESS_INBOUND, GENERIC_WRITE);
+    err = uv_create_stdio_pipe_pair(options.stderr_stream,
+        &process->stdio_pipes[2].child_pipe, PIPE_ACCESS_INBOUND,
+        GENERIC_WRITE);
     if (err) {
       goto done;
     }
index 5902ac31bbdb5c1626fe074ca3caf66b7350826b..14b610326e5dc3b484ace699d85b52ee5cdf6792 100644 (file)
@@ -191,6 +191,7 @@ var spawn = exports.spawn = function(file, args, options) {
 
 
 function maybeExit(subprocess) {
+  console.log("maybeExit");
   subprocess._closesGot++;
 
   if (subprocess._closesGot == subprocess._closesNeeded) {
@@ -213,6 +214,8 @@ function ChildProcess() {
     if (signalCode) self.signalCode = signalCode;
     self.exitCode = exitCode;
 
+    console.error("onexit ", exitCode, signalCode);
+
     if (self.stdin) {
       self.stdin.destroy();
     }
@@ -250,8 +253,28 @@ ChildProcess.prototype.spawn = function(options) {
 
   var r = this._internal.spawn(options);
 
+  if (r) {
+    if (options.stdinStream) {
+      options.stdinStream.close();
+    }
+
+    if (options.stdoutStream) {
+      options.stdoutStream.close();
+    }
+
+    if (options.stderrStream) {
+      options.stderrStream.close();
+    }
+
+    this._internal.close();
+    this._internal = null;
+    throw errnoException("spawn", errno)
+  }
+
   this.pid = this._internal.pid;
 
+  console.log("started pid ", this.pid);
+
   if (options.stdinStream) {
     this.stdin = createSocket(options.stdinStream, false);
   }
@@ -275,6 +298,16 @@ ChildProcess.prototype.spawn = function(options) {
   return r;
 };
 
+function errnoException(errorno, syscall) {
+  // TODO make this more compatible with ErrnoException from src/node.cc
+  // Once all of Node is using this function the ErrnoException from
+  // src/node.cc should be removed.
+  var e = new Error(syscall + ' ' + errorno);
+  e.errno = e.code = errorno;
+  e.syscall = syscall;
+  return e;
+}
+
 
 ChildProcess.prototype.kill = function(sig) {
   throw new Error("implement me");