Merge branch 'v0.6'
Conflicts: deps/uv/include/uv-private/uv-unix.h deps/uv/include/uv-private/uv-win.h deps/uv/src/uv-common.c deps/uv/src/win/fs.c src/process_wrap.cc
This commit is contained in:
commit
c8a10e97c8
@ -32,7 +32,7 @@
|
||||
'VCCLCompilerTool': {
|
||||
'RuntimeLibrary': 1, # static debug
|
||||
'Optimization': 0, # /Od, no optimization
|
||||
'MinimalRebuild': 'true',
|
||||
'MinimalRebuild': 'false',
|
||||
'OmitFramePointers': 'false',
|
||||
'BasicRuntimeChecks': 3, # /RTC1
|
||||
},
|
||||
|
@ -329,10 +329,6 @@ leaner than `child_process.exec`. It has the same options.
|
||||
* `setsid` {Boolean}
|
||||
* `encoding` {String} (Default: 'utf8')
|
||||
* `timeout` {Number} (Default: 0)
|
||||
* `callback` {Function} called with the output when process terminates
|
||||
* `code` {Integer} Exit code
|
||||
* `stdout` {Buffer}
|
||||
* `stderr` {Buffer}
|
||||
* Return: ChildProcess object
|
||||
|
||||
This is a special case of the `spawn()` functionality for spawning Node
|
||||
|
@ -32,6 +32,8 @@
|
||||
<a href="#download" class="button" id="downloadbutton">Download</a>
|
||||
<a href="api/" class="button" id="docsbutton">Docs</a>
|
||||
<p class="version">__VERSION__</p>
|
||||
|
||||
<a href="http://github.com/joyent/node"><img class="forkme" src="https://a248.e.akamai.net/camo.github.com/abad93f42020b733148435e2cd92ce15c542d320/687474703a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677265656e5f3030373230302e706e67" alt="Fork me on GitHub"></a>
|
||||
</div>
|
||||
<div id="quotes" class="clearfix">
|
||||
<h2>Node.js in the Industry</h2>
|
||||
|
17
doc/pipe.css
17
doc/pipe.css
@ -99,10 +99,19 @@ h1 a, h2 a, h3 a, h4 a
|
||||
border-radius: 4px;
|
||||
margin: 0 1px;
|
||||
color: #46483e;
|
||||
background-color: #9a9f8b;
|
||||
}
|
||||
|
||||
#intro .forkme {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
#intro .button:hover {
|
||||
text-decoration: none;
|
||||
background-color: #aab293;
|
||||
}
|
||||
|
||||
#intro #downloadbutton {
|
||||
@ -113,14 +122,6 @@ h1 a, h2 a, h3 a, h4 a
|
||||
background-color: #73a53e;
|
||||
}
|
||||
|
||||
#intro #docsbutton {
|
||||
background-color: #9a9f8b;
|
||||
}
|
||||
|
||||
#intro #docsbutton:hover {
|
||||
background-color: #aab293;
|
||||
}
|
||||
|
||||
#quotes {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
|
@ -370,7 +370,9 @@ var spawn = exports.spawn = function(file, args, options) {
|
||||
windowsVerbatimArguments: !!(options && options.windowsVerbatimArguments),
|
||||
envPairs: envPairs,
|
||||
customFds: options ? options.customFds : null,
|
||||
stdinStream: options ? options.stdinStream : null
|
||||
stdinStream: options ? options.stdinStream : null,
|
||||
uid: options ? options.uid : null,
|
||||
gid: options ? options.gid : null
|
||||
});
|
||||
|
||||
return child;
|
||||
|
@ -53,6 +53,8 @@ using v8::TryCatch;
|
||||
using v8::Context;
|
||||
using v8::Arguments;
|
||||
using v8::Integer;
|
||||
using v8::Exception;
|
||||
using v8::ThrowException;
|
||||
|
||||
static Persistent<String> onexit_sym;
|
||||
|
||||
@ -99,22 +101,54 @@ class ProcessWrap : public HandleWrap {
|
||||
|
||||
Local<Object> js_options = args[0]->ToObject();
|
||||
|
||||
uv_process_options_t options;
|
||||
uv_process_options2_t options;
|
||||
memset(&options, 0, sizeof(uv_process_options_t));
|
||||
|
||||
options.exit_cb = OnExit;
|
||||
|
||||
// options.uid
|
||||
Local<Value> uid_v = js_options->Get(String::NewSymbol("uid"));
|
||||
if (uid_v->IsInt32()) {
|
||||
int32_t uid = uid_v->Int32Value();
|
||||
if (uid & ~((uv_uid_t) ~0)) {
|
||||
return ThrowException(Exception::RangeError(
|
||||
String::New("options.uid is out of range")));
|
||||
}
|
||||
options.flags |= UV_PROCESS_SETUID;
|
||||
options.uid = (uv_uid_t) uid;
|
||||
} else if (!uid_v->IsUndefined() && !uid_v->IsNull()) {
|
||||
return ThrowException(Exception::TypeError(
|
||||
String::New("options.uid should be a number")));
|
||||
}
|
||||
|
||||
// options.gid
|
||||
Local<Value> gid_v = js_options->Get(String::NewSymbol("gid"));
|
||||
if (gid_v->IsInt32()) {
|
||||
int32_t gid = gid_v->Int32Value();
|
||||
if (gid & ~((uv_gid_t) ~0)) {
|
||||
return ThrowException(Exception::RangeError(
|
||||
String::New("options.gid is out of range")));
|
||||
}
|
||||
options.flags |= UV_PROCESS_SETGID;
|
||||
options.gid = (uv_gid_t) gid;
|
||||
} else if (!gid_v->IsUndefined() && !gid_v->IsNull()) {
|
||||
return ThrowException(Exception::TypeError(
|
||||
String::New("options.gid should be a number")));
|
||||
}
|
||||
|
||||
// TODO is this possible to do without mallocing ?
|
||||
|
||||
// options.file
|
||||
Local<Value> file_v = js_options->Get(String::New("file"));
|
||||
Local<Value> file_v = js_options->Get(String::NewSymbol("file"));
|
||||
String::Utf8Value file(file_v->IsString() ? file_v : Local<Value>());
|
||||
if (file.length() > 0) {
|
||||
options.file = *file;
|
||||
} else {
|
||||
return ThrowException(Exception::TypeError(String::New("Bad argument")));
|
||||
}
|
||||
|
||||
// options.args
|
||||
Local<Value> argv_v = js_options->Get(String::New("args"));
|
||||
Local<Value> argv_v = js_options->Get(String::NewSymbol("args"));
|
||||
if (!argv_v.IsEmpty() && argv_v->IsArray()) {
|
||||
Local<Array> js_argv = Local<Array>::Cast(argv_v);
|
||||
int argc = js_argv->Length();
|
||||
@ -128,14 +162,14 @@ class ProcessWrap : public HandleWrap {
|
||||
}
|
||||
|
||||
// options.cwd
|
||||
Local<Value> cwd_v = js_options->Get(String::New("cwd"));
|
||||
Local<Value> cwd_v = js_options->Get(String::NewSymbol("cwd"));
|
||||
String::Utf8Value cwd(cwd_v->IsString() ? cwd_v : Local<Value>());
|
||||
if (cwd.length() > 0) {
|
||||
options.cwd = *cwd;
|
||||
}
|
||||
|
||||
// options.env
|
||||
Local<Value> env_v = js_options->Get(String::New("envPairs"));
|
||||
Local<Value> env_v = js_options->Get(String::NewSymbol("envPairs"));
|
||||
if (!env_v.IsEmpty() && env_v->IsArray()) {
|
||||
Local<Array> env = Local<Array>::Cast(env_v);
|
||||
int envc = env->Length();
|
||||
@ -148,33 +182,36 @@ class ProcessWrap : public HandleWrap {
|
||||
}
|
||||
|
||||
// options.stdin_stream
|
||||
Local<Value> stdin_stream_v = js_options->Get(String::New("stdinStream"));
|
||||
Local<Value> stdin_stream_v = js_options->Get(
|
||||
String::NewSymbol("stdinStream"));
|
||||
if (!stdin_stream_v.IsEmpty() && stdin_stream_v->IsObject()) {
|
||||
PipeWrap* stdin_wrap = PipeWrap::Unwrap(stdin_stream_v->ToObject());
|
||||
options.stdin_stream = stdin_wrap->UVHandle();
|
||||
}
|
||||
|
||||
// options.stdout_stream
|
||||
Local<Value> stdout_stream_v = js_options->Get(String::New("stdoutStream"));
|
||||
Local<Value> stdout_stream_v = js_options->Get(
|
||||
String::NewSymbol("stdoutStream"));
|
||||
if (!stdout_stream_v.IsEmpty() && stdout_stream_v->IsObject()) {
|
||||
PipeWrap* stdout_wrap = PipeWrap::Unwrap(stdout_stream_v->ToObject());
|
||||
options.stdout_stream = stdout_wrap->UVHandle();
|
||||
}
|
||||
|
||||
// options.stderr_stream
|
||||
Local<Value> stderr_stream_v = js_options->Get(String::New("stderrStream"));
|
||||
Local<Value> stderr_stream_v = js_options->Get(
|
||||
String::NewSymbol("stderrStream"));
|
||||
if (!stderr_stream_v.IsEmpty() && stderr_stream_v->IsObject()) {
|
||||
PipeWrap* stderr_wrap = PipeWrap::Unwrap(stderr_stream_v->ToObject());
|
||||
options.stderr_stream = stderr_wrap->UVHandle();
|
||||
}
|
||||
|
||||
// options.windows_verbatim_arguments
|
||||
#if defined(_WIN32)
|
||||
options.windows_verbatim_arguments = js_options->
|
||||
Get(String::NewSymbol("windowsVerbatimArguments"))->IsTrue();
|
||||
#endif
|
||||
if (js_options->Get(String::NewSymbol("windowsVerbatimArguments"))->
|
||||
IsTrue()) {
|
||||
options.flags |= UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS;
|
||||
}
|
||||
|
||||
int r = uv_spawn(uv_default_loop(), &wrap->process_, options);
|
||||
int r = uv_spawn2(uv_default_loop(), &wrap->process_, options);
|
||||
|
||||
if (r) {
|
||||
SetErrno(uv_last_error(uv_default_loop()));
|
||||
|
45
test/simple/test-cluster-worker-death.js
Normal file
45
test/simple/test-cluster-worker-death.js
Normal file
@ -0,0 +1,45 @@
|
||||
// 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 assert = require('assert');
|
||||
var cluster = require('cluster');
|
||||
|
||||
if (!cluster.isMaster) {
|
||||
process.exit(42);
|
||||
}
|
||||
else {
|
||||
var seenExit = 0;
|
||||
var seenDeath = 0;
|
||||
var worker = cluster.fork();
|
||||
worker.on('exit', function(statusCode) {
|
||||
assert.equal(statusCode, 42);
|
||||
seenExit++;
|
||||
});
|
||||
cluster.on('death', function(worker_) {
|
||||
assert.equal(worker_, worker);
|
||||
seenDeath++;
|
||||
});
|
||||
process.on('exit', function() {
|
||||
assert.equal(seenExit, 1);
|
||||
assert.equal(seenDeath, 1);
|
||||
});
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user