Browse Source

API: Move node.exit() to process.exit().

v0.7.4-release
Ryan Dahl 15 years ago
parent
commit
23c7f472d0
  1. 2
      benchmark/process_loop.js
  2. 89
      doc/api.html
  3. 67
      doc/api.txt
  4. 92
      doc/api.xml
  5. 83
      doc/node.1
  6. 22
      src/node.cc
  7. 19
      src/node.js

2
benchmark/process_loop.js

@ -11,7 +11,7 @@ function next (i) {
}); });
child.addListener("exit", function (code) { child.addListener("exit", function (code) {
if (code != 0) node.exit(-1); if (code != 0) process.exit(-1);
next(i - 1); next(i - 1);
}); });
} }

89
doc/api.html

@ -61,18 +61,10 @@ of the 16bit javascript string characters. Both are relatively fast—use
them if you can. <tt>"utf8"</tt> is slower and should be avoided when possible.</p></div> them if you can. <tt>"utf8"</tt> is slower and should be avoided when possible.</p></div>
<div class="paragraph"><p>Unless otherwise noted, functions are all asynchronous and do not block <div class="paragraph"><p>Unless otherwise noted, functions are all asynchronous and do not block
execution.</p></div> execution.</p></div>
<h3 id="_helpers_and_global_variables">Helpers and Global Variables</h3><div style="clear:left"></div> <h3 id="_helpers">Helpers</h3><div style="clear:left"></div>
<div class="paragraph"><p>These objects are available to all programs.</p></div> <div class="paragraph"><p>These objects are available to all programs.</p></div>
<div class="dlist"><dl> <div class="dlist"><dl>
<dt class="hdlist1"> <dt class="hdlist1">
<tt>node.exit(code)</tt>
</dt>
<dd>
<p>
Immediately ends the process with the specified code.
</p>
</dd>
<dt class="hdlist1">
<tt>node.cwd()</tt> <tt>node.cwd()</tt>
</dt> </dt>
<dd> <dd>
@ -81,36 +73,73 @@ Returns the current working directory of the process.
</p> </p>
</dd> </dd>
<dt class="hdlist1"> <dt class="hdlist1">
<tt>ARGV</tt> <tt>__filename</tt>
</dt> </dt>
<dd> <dd>
<p> <p>
An array containing the command line arguments. The filename of the script being executed.
</p> </p>
</dd> </dd>
</dl></div>
<h3 id="_the_tt_process_tt_object">The <tt>process</tt> Object</h3><div style="clear:left"></div>
<div class="paragraph"><p><tt>process</tt> is the equivalent of <tt>window</tt> in browser-side javascript. It is
the global scope. <tt>process</tt> is an instance of <tt>node.EventEmitter</tt>.</p></div>
<div class="tableblock">
<table rules="all"
width="100%"
frame="border"
cellspacing="0" cellpadding="4">
<col width="7%" />
<col width="15%" />
<col width="76%" />
<thead>
<tr>
<th align="left" valign="top"> Event </th>
<th align="left" valign="top"> Parameters </th>
<th align="left" valign="top"> Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left" valign="top"><p class="table"><tt>"exit"</tt></p></td>
<td align="left" valign="top"><p class="table"><tt>code</tt></p></td>
<td align="left" valign="top"><p class="table">Made when the process exits.
A listener on this event should not try to perform
I/O since the process will forcibly exit in less
than microsecond. However, it is a good hook to
perform constant time checks of the module&#8217;s
state (like for unit tests).
<br />
The parameter <tt>code</tt> is the integer exit code
passed to <tt>process.exit()</tt>.</p></td>
</tr>
</tbody>
</table>
</div>
<div class="dlist"><dl>
<dt class="hdlist1"> <dt class="hdlist1">
<tt>ENV</tt> <tt>process.exit(code=0)</tt>
</dt> </dt>
<dd> <dd>
<p> <p>
An object containing the user environment. See environ(7). Ends the process with the specified code. By default it exits with the
success code 0.
</p> </p>
</dd> </dd>
<dt class="hdlist1"> <dt class="hdlist1">
<tt>__filename</tt> <tt>process.ARGV</tt>
</dt> </dt>
<dd> <dd>
<p> <p>
The filename of the script being executed. An array containing the command line arguments.
</p> </p>
</dd> </dd>
<dt class="hdlist1"> <dt class="hdlist1">
<tt>process</tt> <tt>process.ENV</tt>
</dt> </dt>
<dd> <dd>
<p> <p>
A special global object. The <tt>process</tt> object is like the <tt>window</tt> object of An object containing the user environment. See environ(7).
browser-side javascript.
</p> </p>
</dd> </dd>
</dl></div> </dl></div>
@ -475,28 +504,6 @@ variable (which should be a list of paths, colon separated).</p></div>
is run. These are currently undocumented, but do look them up in your is run. These are currently undocumented, but do look them up in your
system.</p></div> system.</p></div>
<div class="paragraph"><p>(Functions <tt>require_async()</tt> and <tt>include_async()</tt> also exist.)</p></div> <div class="paragraph"><p>(Functions <tt>require_async()</tt> and <tt>include_async()</tt> also exist.)</p></div>
<h4 id="_tt_process_addlistener_exit_function_tt"><tt>process.addListener("exit", function () { })</tt></h4>
<div class="paragraph"><p>When the program exits a special object called <tt>process</tt> will emit an
<tt>"exit"</tt> event.</p></div>
<div class="paragraph"><p>The <tt>"exit"</tt> event cannot perform I/O since the process is going to
forcibly exit in less than microsecond. However, it is a good hook to
perform constant time checks of the module&#8217;s state. E.G. for unit tests:</p></div>
<div class="listingblock">
<div class="content">
<pre><tt>include("asserts.js");
var timer_executed = false;
setTimeout(function () {
timer_executed = true
}, 1000);
process.addListener("exit", function () {
assertTrue(timer_executed);
});</tt></pre>
</div></div>
<div class="paragraph"><p>Just to reiterate: the <tt>"exit"</tt> event, is not the place to close files or
shutdown servers. The process will exit before they get performed.</p></div>
<h3 id="_timers">Timers</h3><div style="clear:left"></div> <h3 id="_timers">Timers</h3><div style="clear:left"></div>
<div class="dlist"><dl> <div class="dlist"><dl>
<dt class="hdlist1"> <dt class="hdlist1">
@ -1948,7 +1955,7 @@ init (Handle&lt;Object&gt; target)
<div id="footer"> <div id="footer">
<div id="footer-text"> <div id="footer-text">
Version 0.1.12<br /> Version 0.1.12<br />
Last updated 2009-09-28 16:05:24 CEST Last updated 2009-09-28 16:33:21 CEST
</div> </div>
</div> </div>
</body> </body>

67
doc/api.txt

@ -47,29 +47,44 @@ Unless otherwise noted, functions are all asynchronous and do not block
execution. execution.
=== Helpers and Global Variables === Helpers
These objects are available to all programs. These objects are available to all programs.
+node.exit(code)+::
Immediately ends the process with the specified code.
+node.cwd()+:: +node.cwd()+::
Returns the current working directory of the process. Returns the current working directory of the process.
+ARGV+ ::
An array containing the command line arguments.
+ENV+ ::
An object containing the user environment. See environ(7).
+__filename+ :: +__filename+ ::
The filename of the script being executed. The filename of the script being executed.
+process+ :: === The +process+ Object
A special global object. The +process+ object is like the +window+ object of
browser-side javascript. +process+ is the equivalent of +window+ in browser-side javascript. It is
the global scope. +process+ is an instance of +node.EventEmitter+.
[cols="1,2,10",options="header"]
|=========================================================
| Event | Parameters | Notes
| +"exit"+ | +code+ | Made when the process exits.
A listener on this event should not try to perform
I/O since the process will forcibly exit in less
than microsecond. However, it is a good hook to
perform constant time checks of the module's
state (like for unit tests).
+
The parameter +code+ is the integer exit code
passed to +process.exit()+.
|=========================================================
+process.exit(code=0)+::
Ends the process with the specified code. By default it exits with the
success code 0.
+process.ARGV+ ::
An array containing the command line arguments.
+process.ENV+ ::
An object containing the user environment. See environ(7).
=== Utilities === Utilities
@ -306,32 +321,6 @@ system.
(Functions +require_async()+ and +include_async()+ also exist.) (Functions +require_async()+ and +include_async()+ also exist.)
==== +process.addListener("exit", function () { })+
When the program exits a special object called +process+ will emit an
+"exit"+ event.
The +"exit"+ event cannot perform I/O since the process is going to
forcibly exit in less than microsecond. However, it is a good hook to
perform constant time checks of the module's state. E.G. for unit tests:
----------------------------------------
include("asserts.js");
var timer_executed = false;
setTimeout(function () {
timer_executed = true
}, 1000);
process.addListener("exit", function () {
assertTrue(timer_executed);
});
----------------------------------------
Just to reiterate: the +"exit"+ event, is not the place to close files or
shutdown servers. The process will exit before they get performed.
=== Timers === Timers

92
doc/api.xml

@ -33,22 +33,12 @@ of the 16bit javascript string characters. Both are relatively fast&#8212;use
them if you can. <literal>"utf8"</literal> is slower and should be avoided when possible.</simpara> them if you can. <literal>"utf8"</literal> is slower and should be avoided when possible.</simpara>
<simpara>Unless otherwise noted, functions are all asynchronous and do not block <simpara>Unless otherwise noted, functions are all asynchronous and do not block
execution.</simpara> execution.</simpara>
<refsect2 id="_helpers_and_global_variables"> <refsect2 id="_helpers">
<title>Helpers and Global Variables</title> <title>Helpers</title>
<simpara>These objects are available to all programs.</simpara> <simpara>These objects are available to all programs.</simpara>
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term> <term>
<literal>node.exit(code)</literal>
</term>
<listitem>
<simpara>
Immediately ends the process with the specified code.
</simpara>
</listitem>
</varlistentry>
<varlistentry>
<term>
<literal>node.cwd()</literal> <literal>node.cwd()</literal>
</term> </term>
<listitem> <listitem>
@ -59,42 +49,81 @@ Returns the current working directory of the process.
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term> <term>
<literal>ARGV</literal> <literal>__filename</literal>
</term> </term>
<listitem> <listitem>
<simpara> <simpara>
An array containing the command line arguments. The filename of the script being executed.
</simpara> </simpara>
</listitem> </listitem>
</varlistentry> </varlistentry>
</variablelist>
</refsect2>
<refsect2 id="_the_literal_process_literal_object">
<title>The <literal>process</literal> Object</title>
<simpara><literal>process</literal> is the equivalent of <literal>window</literal> in browser-side javascript. It is
the global scope. <literal>process</literal> is an instance of <literal>node.EventEmitter</literal>.</simpara>
<informaltable
frame="all"
rowsep="1" colsep="1"
>
<tgroup cols="3">
<colspec colname="col_1" colwidth="7*"/>
<colspec colname="col_2" colwidth="15*"/>
<colspec colname="col_3" colwidth="76*"/>
<thead>
<row>
<entry align="left" valign="top"> Event </entry>
<entry align="left" valign="top"> Parameters </entry>
<entry align="left" valign="top"> Notes</entry>
</row>
</thead>
<tbody>
<row>
<entry align="left" valign="top"><simpara><literal>"exit"</literal></simpara></entry>
<entry align="left" valign="top"><simpara><literal>code</literal></simpara></entry>
<entry align="left" valign="top"><simpara>Made when the process exits.
A listener on this event should not try to perform
I/O since the process will forcibly exit in less
than microsecond. However, it is a good hook to
perform constant time checks of the module&#8217;s
state (like for unit tests).
<?asciidoc-br?>
The parameter <literal>code</literal> is the integer exit code
passed to <literal>process.exit()</literal>.</simpara></entry>
</row>
</tbody>
</tgroup>
</informaltable>
<variablelist>
<varlistentry> <varlistentry>
<term> <term>
<literal>ENV</literal> <literal>process.exit(code=0)</literal>
</term> </term>
<listitem> <listitem>
<simpara> <simpara>
An object containing the user environment. See environ(7). Ends the process with the specified code. By default it exits with the
success code 0.
</simpara> </simpara>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term> <term>
<literal>__filename</literal> <literal>process.ARGV</literal>
</term> </term>
<listitem> <listitem>
<simpara> <simpara>
The filename of the script being executed. An array containing the command line arguments.
</simpara> </simpara>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term> <term>
<literal>process</literal> <literal>process.ENV</literal>
</term> </term>
<listitem> <listitem>
<simpara> <simpara>
A special global object. The <literal>process</literal> object is like the <literal>window</literal> object of An object containing the user environment. See environ(7).
browser-side javascript.
</simpara> </simpara>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -488,27 +517,6 @@ variable (which should be a list of paths, colon separated).</simpara>
is run. These are currently undocumented, but do look them up in your is run. These are currently undocumented, but do look them up in your
system.</simpara> system.</simpara>
<simpara>(Functions <literal>require_async()</literal> and <literal>include_async()</literal> also exist.)</simpara> <simpara>(Functions <literal>require_async()</literal> and <literal>include_async()</literal> also exist.)</simpara>
<refsect3 id="_literal_process_addlistener_exit_function_literal">
<title><literal>process.addListener("exit", function () { })</literal></title>
<simpara>When the program exits a special object called <literal>process</literal> will emit an
<literal>"exit"</literal> event.</simpara>
<simpara>The <literal>"exit"</literal> event cannot perform I/O since the process is going to
forcibly exit in less than microsecond. However, it is a good hook to
perform constant time checks of the module&#8217;s state. E.G. for unit tests:</simpara>
<screen>include("asserts.js");
var timer_executed = false;
setTimeout(function () {
timer_executed = true
}, 1000);
process.addListener("exit", function () {
assertTrue(timer_executed);
});</screen>
<simpara>Just to reiterate: the <literal>"exit"</literal> event, is not the place to close files or
shutdown servers. The process will exit before they get performed.</simpara>
</refsect3>
</refsect2> </refsect2>
<refsect2 id="_timers"> <refsect2 id="_timers">
<title>Timers</title> <title>Timers</title>

83
doc/node.1

@ -42,41 +42,58 @@ Node supports 3 string encodings\. UTF\-8 ("utf8"), ASCII ("ascii"), and Binary
.sp .sp
Unless otherwise noted, functions are all asynchronous and do not block execution\. Unless otherwise noted, functions are all asynchronous and do not block execution\.
.sp .sp
.SS "Helpers and Global Variables" .SS "Helpers"
These objects are available to all programs\. These objects are available to all programs\.
.PP .PP
node\.exit(code)
.RS 4
Immediately ends the process with the specified code\.
.RE
.PP
node\.cwd() node\.cwd()
.RS 4 .RS 4
Returns the current working directory of the process\. Returns the current working directory of the process\.
.RE .RE
.PP .PP
ARGV __filename
.RS 4 .RS 4
An array containing the command line arguments\. The filename of the script being executed\.
.RE .RE
.SS "The process Object"
process is the equivalent of window in browser\-side javascript\. It is the global scope\. process is an instance of node\.EventEmitter\.
.sp
.TS
allbox tab(:);
ltB ltB ltBx.
T{
Event
T}:T{
Parameters
T}:T{
Notes
T}
.T&
lt lt lt.
T{
"exit"
.sp
T}:T{
code
.sp
T}:T{
Made when the process exits\. A listener on this event should not try to perform I/O since the process will forcibly exit in less than microsecond\. However, it is a good hook to perform constant time checks of the module\(cqs state (like for unit tests)\. The parameter code is the integer exit code passed to process\.exit()\.
.sp
T}
.TE
.PP .PP
ENV process\.exit(code=0)
.RS 4 .RS 4
An object containing the user environment\. See environ(7)\. Ends the process with the specified code\. By default it exits with the success code 0\.
.RE .RE
.PP .PP
__filename process\.ARGV
.RS 4 .RS 4
The filename of the script being executed\. An array containing the command line arguments\.
.RE .RE
.PP .PP
process process\.ENV
.RS 4 .RS 4
A special global object\. The An object containing the user environment\. See environ(7)\.
process
object is like the
window
object of browser\-side javascript\.
.RE .RE
.SS "Utilities" .SS "Utilities"
These function are in "/utils\.js"\. Use require("/utils\.js") to access them\. These function are in "/utils\.js"\. Use require("/utils\.js") to access them\.
@ -418,36 +435,6 @@ Node comes with several libraries which are installed when "make install" is run
.sp .sp
(Functions require_async() and include_async() also exist\.) (Functions require_async() and include_async() also exist\.)
.sp .sp
.sp
.it 1 an-trap
.nr an-no-space-flag 1
.nr an-break-flag 1
.br
process.addListener("exit", function () { })
.RS
When the program exits a special object called process will emit an "exit" event\.
.sp
The "exit" event cannot perform I/O since the process is going to forcibly exit in less than microsecond\. However, it is a good hook to perform constant time checks of the module\(cqs state\. E\.G\. for unit tests:
.sp
.sp
.RS 4
.nf
include("asserts\.js");
var timer_executed = false;
setTimeout(function () {
timer_executed = true
}, 1000);
process\.addListener("exit", function () {
assertTrue(timer_executed);
});
.fi
.RE
Just to reiterate: the "exit" event, is not the place to close files or shutdown servers\. The process will exit before they get performed\.
.sp
.RE
.SS "Timers" .SS "Timers"
.PP .PP
setTimeout(callback, delay) setTimeout(callback, delay)

22
src/node.cc

@ -408,15 +408,23 @@ static Local<Object> Load(int argc, char *argv[]) {
return scope.Close(node_obj); return scope.Close(node_obj);
} }
static void CallExitHandler(Handle<Object> node_obj) { static void CallExitHandler() {
HandleScope scope; HandleScope scope;
Local<Value> exit_v = node_obj->Get(String::New("exit")); Local<Object> process = Context::GetCurrent()->Global();
assert(exit_v->IsFunction()); Local<Value> emit_v = process->Get(String::NewSymbol("emit"));
Handle<Function> exit_f = Handle<Function>::Cast(exit_v); if (!emit_v->IsFunction()) {
exit(10); // could not emit exit event so exit with error code 10.
}
Local<Function> emit = Local<Function>::Cast(emit_v);
TryCatch try_catch; TryCatch try_catch;
exit_f->Call(Context::GetCurrent()->Global(), 0, NULL);
if (try_catch.HasCaught()) Local<Value> argv[2] = { String::New("exit"), Integer::New(0) };
emit->Call(process, 2, argv);
if (try_catch.HasCaught()) {
node::FatalException(try_catch); node::FatalException(try_catch);
}
} }
static void PrintHelp() { static void PrintHelp() {
@ -494,7 +502,7 @@ int main(int argc, char *argv[]) {
ev_loop(EV_DEFAULT_UC_ 0); // main event loop ev_loop(EV_DEFAULT_UC_ 0); // main event loop
node::CallExitHandler(node_obj); node::CallExitHandler();
context.Dispose(); context.Dispose();
V8::Dispose(); V8::Dispose();

19
src/node.js

@ -202,7 +202,7 @@ node.Module.prototype.loadObject = function (loadPromise) {
loadPromise.emitSuccess(self.target); loadPromise.emitSuccess(self.target);
} else { } else {
loadPromise.emitError(new Error("Error reading " + self.filename)); loadPromise.emitError(new Error("Error reading " + self.filename));
node.exit(1); process.exit(1);
} }
}); });
}; };
@ -213,7 +213,7 @@ node.Module.prototype.loadScript = function (loadPromise) {
catPromise.addErrback(function () { catPromise.addErrback(function () {
loadPromise.emitError(new Error("Error reading " + self.filename)); loadPromise.emitError(new Error("Error reading " + self.filename));
node.exit(1); process.exit(1);
}); });
catPromise.addCallback(function (content) { catPromise.addCallback(function (content) {
@ -256,6 +256,16 @@ node.Module.prototype.waitChildrenLoad = function (callback) {
if (children.length == nloaded && callback) callback(); if (children.length == nloaded && callback) callback();
}; };
process.exit = function (code) {
process.emit("exit");
node.reallyExit(code);
};
node.exit = function (code) {
throw new Error("process.exit() has been renamed to process.exit().");
};
(function () { (function () {
var cwd = node.cwd(); var cwd = node.cwd();
@ -270,9 +280,4 @@ node.Module.prototype.waitChildrenLoad = function (callback) {
// Load the root module--the command line argument. // Load the root module--the command line argument.
node.loadModule(ARGV[1], process); node.loadModule(ARGV[1], process);
node.exit = function (code) {
process.emit("exit");
node.reallyExit(code);
};
}()); }());

Loading…
Cancel
Save