mirror of
https://github.com/nodejs/node-v0.x-archive.git
synced 2026-04-28 03:01:10 -04:00
Compare commits
82 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7bf46bc980 | ||
|
|
bcbc52e257 | ||
|
|
c00a6a7169 | ||
|
|
1d8b154e14 | ||
|
|
84f4ce742f | ||
|
|
f9cc35fa57 | ||
|
|
d506a42765 | ||
|
|
09a41a7f9c | ||
|
|
8dcd6dccab | ||
|
|
1375b8ed39 | ||
|
|
a3333e7393 | ||
|
|
d965640662 | ||
|
|
ee253b374d | ||
|
|
b17b28531b | ||
|
|
10af67714b | ||
|
|
180a04805b | ||
|
|
ee21920571 | ||
|
|
66bce65d33 | ||
|
|
2005ef9e37 | ||
|
|
3816ebc85f | ||
|
|
4c5520a37e | ||
|
|
0ddad3fbc7 | ||
|
|
db6a1788b2 | ||
|
|
1d17874a7d | ||
|
|
3191802605 | ||
|
|
da235fa12c | ||
|
|
92fb664bfc | ||
|
|
7704fb9711 | ||
|
|
c099e274d2 | ||
|
|
c86f3c5d5c | ||
|
|
9b8577230f | ||
|
|
9f6f26028f | ||
|
|
44f8756aab | ||
|
|
ae2f566fec | ||
|
|
2f071ac7d1 | ||
|
|
bd8ea2bb85 | ||
|
|
35682ac88e | ||
|
|
5bbebf3593 | ||
|
|
0b9dab650e | ||
|
|
a6659e7612 | ||
|
|
727843eea1 | ||
|
|
7e9a0173d7 | ||
|
|
74b70c3cb1 | ||
|
|
d5deb4c4a3 | ||
|
|
cc0164bc12 | ||
|
|
ccd1304c5b | ||
|
|
3d3d00d524 | ||
|
|
dffa9e76a1 | ||
|
|
90374797f0 | ||
|
|
c1a4e10156 | ||
|
|
b655ce5c08 | ||
|
|
b30b60717d | ||
|
|
b2dfea0361 | ||
|
|
610743daee | ||
|
|
df891c36a4 | ||
|
|
f35a8298b1 | ||
|
|
294c455678 | ||
|
|
14f16ec592 | ||
|
|
cdee88051d | ||
|
|
b39b15d53f | ||
|
|
b895568800 | ||
|
|
ead58b9a93 | ||
|
|
c306fa241c | ||
|
|
22f67f8585 | ||
|
|
416aa73946 | ||
|
|
6a39a7ed83 | ||
|
|
ad960f4462 | ||
|
|
f78691e45c | ||
|
|
3d8137c582 | ||
|
|
c14c445cb6 | ||
|
|
b9ca8435f5 | ||
|
|
baa24bd40e | ||
|
|
7a836ef813 | ||
|
|
a2b9e02d83 | ||
|
|
3f7c791b13 | ||
|
|
53dac7c341 | ||
|
|
c43ddf7acd | ||
|
|
699fdfaa43 | ||
|
|
8d2e79451e | ||
|
|
760efc0758 | ||
|
|
1b1ad1d363 | ||
|
|
c3eafdd3a4 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -12,3 +12,4 @@ test/fixtures/hello.txt
|
||||
tmp/
|
||||
node
|
||||
node_g
|
||||
*.swp
|
||||
|
||||
7
AUTHORS
7
AUTHORS
@@ -109,8 +109,15 @@ Chandra Sekar S <chandru.in@gmail.com>
|
||||
Andrew Naylor <argon@mkbot.net>
|
||||
Benjamin Kramer <benny.kra@gmail.com>
|
||||
Danny Coates <dannycoates@gmail.com>
|
||||
Samuel Shull <brickysam26@gmail.com>
|
||||
Nick Stenning <nick@whiteink.com>
|
||||
Bert Belder <bertbelder@gmail.com>
|
||||
Trent Mick <trentm@gmail.com>
|
||||
Fedor Indutny <fedor.indutny@gmail.com>
|
||||
Illarionov Oleg <oleg@emby.ru>
|
||||
Aria Stewart <aredridel@nbtsc.org>
|
||||
Johan Euphrosine <proppy@aminche.com>
|
||||
Russell Haering <russellhaering@gmail.com>
|
||||
Bradley Meck <bradley.meck@gmail.com>
|
||||
Tobie Langel <tobie.langel@gmail.com>
|
||||
Tony Metzidis <tonym@tonym.us>
|
||||
|
||||
36
ChangeLog
36
ChangeLog
@@ -1,4 +1,38 @@
|
||||
2010.08.20, Version 0.2.0
|
||||
2010.09.17, Version 0.2.2
|
||||
|
||||
* REPL improvements (Trent Mick)
|
||||
|
||||
* Fix bug in fs.realpath (Isaac Schlueter)
|
||||
|
||||
* sys.pump catches errors (Russell Haering)
|
||||
|
||||
|
||||
2010.09.10, Version 0.2.1, da235fa12c208fc8243600e128db2c9b55624c5c
|
||||
|
||||
* REPL improvements (Johan Euphrosine, Brian White)
|
||||
|
||||
* nextTick bug fixes (Benjamin Thomas, Felix Geisendörfer,
|
||||
Trent Mick)
|
||||
|
||||
* fs module bug fixes (Russell Haering, Marco Rogers, Tobie Langel,
|
||||
Isaac Schlueter)
|
||||
|
||||
* Build script change for OpenEmbedded.
|
||||
|
||||
* Most constrctuors work without 'new' now.
|
||||
|
||||
* Allow Strings for ports on net.Server.listen (Bradley Meck)
|
||||
|
||||
* setInterval(cb, 0) loops infinitely
|
||||
|
||||
* Fixes for NODE_MODULE_CONTEXTS=1 (Herbert Vojčík)
|
||||
|
||||
* Expose fingerproint from getPeerCertificate (Paul Querna)
|
||||
|
||||
* API: forceClose -> destroy for WriteStreams
|
||||
|
||||
|
||||
2010.08.20, Version 0.2.0, 9283e134e558900ba89d9a33c18a9bdedab07cb9
|
||||
|
||||
* process.title support for FreeBSD, Macintosh, Linux
|
||||
|
||||
|
||||
4
TODO
4
TODO
@@ -16,3 +16,7 @@
|
||||
the maximum is reached it stops accepting new connections.
|
||||
- compile under clang
|
||||
- Use C++ style casts everywhere.
|
||||
- fs.readFile[Sync] should not call stat() and use the length.
|
||||
Test on Linux's /proc/sys/kernel/hostname
|
||||
- Ruby-like Process#detach (is that possible?)
|
||||
- stderr isn't flushing on exit
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
|
||||
for (var i = 0; i < 9000000; i++) {
|
||||
for (var i = 0; i < 9e7; i++) {
|
||||
b = new Buffer(10);
|
||||
b[1] = 2
|
||||
}
|
||||
|
||||
26
benchmark/startup.js
Normal file
26
benchmark/startup.js
Normal file
@@ -0,0 +1,26 @@
|
||||
var spawn = require('child_process').spawn,
|
||||
path = require('path'),
|
||||
emptyJsFile = path.join(__dirname, '../test/fixtures/semicolon.js'),
|
||||
starts = 100,
|
||||
i = 0,
|
||||
start;
|
||||
|
||||
function startNode() {
|
||||
var node = spawn(process.execPath || process.argv[0], [emptyJsFile]);
|
||||
node.on('exit', function(exitCode) {
|
||||
if (exitCode !== 0) {
|
||||
throw new Error('Error during node startup');
|
||||
}
|
||||
|
||||
i++;
|
||||
if (i < starts) {
|
||||
startNode();
|
||||
} else{
|
||||
var duration = +new Date - start;
|
||||
console.log('Started node %d times in %s ms. %d ms / start.', starts, duration, duration / starts);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
start = +new Date;
|
||||
startNode();
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
|
||||
for (var i = 0; i < 9000000; i++) {
|
||||
for (var i = 0; i < 9e7; i++) {
|
||||
s = '01234567890';
|
||||
s[1] = "a";
|
||||
}
|
||||
|
||||
@@ -860,8 +860,9 @@ Experimental
|
||||
|
||||
Read the data from `readableStream` and send it to the `writableStream`.
|
||||
When `writeableStream.write(data)` returns `false` `readableStream` will be
|
||||
paused until the `drain` event occurs on the `writableStream`. `callback` is
|
||||
called when `writableStream` is closed.
|
||||
paused until the `drain` event occurs on the `writableStream`. `callback` gets
|
||||
an error as its only argument and is called when `writableStream` is closed or
|
||||
when an error occurs.
|
||||
|
||||
|
||||
## Timers
|
||||
@@ -1447,19 +1448,6 @@ See pwrite(2).
|
||||
The callback will be given two arguments `(err, written)` where `written`
|
||||
specifies how many _bytes_ were written.
|
||||
|
||||
### fs.write(fd, str, position, encoding='utf8', [callback])
|
||||
|
||||
Write the entire string `str` using the given `encoding` to the file specified
|
||||
by `fd`.
|
||||
|
||||
`position` refers to the offset from the beginning of the file where this data
|
||||
should be written. If `position` is `null`, the data will be written at the
|
||||
current position.
|
||||
See pwrite(2).
|
||||
|
||||
The callback will be given two arguments `(err, written)` where `written`
|
||||
specifies how many _bytes_ were written.
|
||||
|
||||
### fs.writeSync(fd, buffer, offset, length, position)
|
||||
|
||||
Synchronous version of buffer-based `fs.write()`. Returns the number of bytes written.
|
||||
@@ -1483,19 +1471,6 @@ If `position` is `null`, data will be read from the current file position.
|
||||
|
||||
The callback is given the two arguments, `(err, bytesRead)`.
|
||||
|
||||
### fs.read(fd, length, position, encoding, [callback])
|
||||
|
||||
Read data from the file specified by `fd`.
|
||||
|
||||
`length` is an integer specifying the number of bytes to read.
|
||||
|
||||
`position` is an integer specifying where to begin reading from in the file.
|
||||
If `position` is `null`, data will be read from the current file position.
|
||||
|
||||
`encoding` is the desired encoding of the string of data read in from `fd`.
|
||||
|
||||
The callback is given the three arguments, `(err, str, bytesRead)`.
|
||||
|
||||
### fs.readSync(fd, buffer, offset, length, position)
|
||||
|
||||
Synchronous version of buffer-based `fs.read`. Returns the number of `bytesRead`.
|
||||
@@ -1607,6 +1582,12 @@ An example to read the last 10 bytes of a file which is 100 bytes long:
|
||||
|
||||
`WriteStream` is a `Writable Stream`.
|
||||
|
||||
### Event: 'open'
|
||||
|
||||
`function (fd) { }`
|
||||
|
||||
`fd` is the file descriptor used by the WriteStream.
|
||||
|
||||
### fs.createWriteStream(path, [options])
|
||||
|
||||
Returns a new WriteStream object (See `Writable Stream`).
|
||||
@@ -2225,7 +2206,7 @@ See `connect()`.
|
||||
|
||||
`function () { }`
|
||||
|
||||
Emitted when a stream connection successfully establishes a HTTPS handshake with its peer.
|
||||
Emitted when a stream connection successfully establishes an SSL handshake with its peer.
|
||||
|
||||
|
||||
### Event: 'data'
|
||||
@@ -2314,9 +2295,9 @@ received.
|
||||
|
||||
### stream.setSecure([credentials])
|
||||
|
||||
Enables HTTPS support for the stream, with the crypto module credentials specifying the private key and certificate of the stream, and optionally the CA certificates for use in peer authentication.
|
||||
Enables SSL support for the stream, with the crypto module credentials specifying the private key and certificate of the stream, and optionally the CA certificates for use in peer authentication.
|
||||
|
||||
If the credentials hold one ore more CA certificates, then the stream will request for the peer to submit a client certificate as part of the HTTPS connection handshake. The validity and content of this can be accessed via verifyPeer() and getPeerCertificate().
|
||||
If the credentials hold one ore more CA certificates, then the stream will request for the peer to submit a client certificate as part of the SSL connection handshake. The validity and content of this can be accessed via verifyPeer() and getPeerCertificate().
|
||||
|
||||
### stream.verifyPeer()
|
||||
|
||||
@@ -3284,3 +3265,49 @@ All Node addons must export a function called `init` with this signature:
|
||||
|
||||
For the moment, that is all the documentation on addons. Please see
|
||||
<http://github.com/ry/node_postgres> for a real example.
|
||||
|
||||
|
||||
## Appendix - Third Party Modules
|
||||
|
||||
There are many third party modules for Node. At the time of writing, August
|
||||
2010, the master repository of modules is
|
||||
http://github.com/ry/node/wiki/modules[the wiki page].
|
||||
|
||||
This appendix is intended as a SMALL guide to new-comers to help them
|
||||
quickly find what are considered to be quality modules. It is not intended
|
||||
to be a complete list. There may be better more complete modules found
|
||||
elsewhere.
|
||||
|
||||
- Module Installer: [npm](http://github.com/isaacs/npm)
|
||||
|
||||
- HTTP Middleware: [Connect](http://github.com/senchalabs/connect)
|
||||
|
||||
- Web Framework: [Express](http://github.com/visionmedia/express)
|
||||
|
||||
- Web Sockets: [Socket.IO](http://github.com/LearnBoost/Socket.IO-node)
|
||||
|
||||
- HTML Parsing: [HTML5](http://github.com/aredridel/html5)
|
||||
|
||||
- [mDNS/Zeroconf/Bonjour](http://github.com/agnat/node_mdns)
|
||||
|
||||
- [RabbitMQ, AMQP](http://github.com/ry/node-amqp)
|
||||
|
||||
- [mysql](http://github.com/felixge/node-mysql)
|
||||
|
||||
- Serialization: [msgpack](http://github.com/pgriess/node-msgpack)
|
||||
|
||||
- Scraping: [Apricot](http://github.com/silentrob/Apricot)
|
||||
|
||||
- Debugger: [ndb](http://github.com/smtlaissezfaire/ndb) is a CLI debugger
|
||||
[inspector](http://github.com/dannycoates/node-inspector) is a web based
|
||||
tool.
|
||||
|
||||
- [pcap binding](http://github.com/mranney/node_pcap)
|
||||
|
||||
- [ncurses](http://github.com/mscdex/node-ncurses)
|
||||
|
||||
- Testing/TDD/BDD: [vows](http://vowsjs.org/),
|
||||
[expresso](http://github.com/visionmedia/expresso),
|
||||
[mjsunit.runner](http://github.com/tmpvar/mjsunit.runner)
|
||||
|
||||
Patches to this list are welcome.
|
||||
|
||||
@@ -295,7 +295,7 @@
|
||||
<body>
|
||||
|
||||
<div id="toc">
|
||||
<div id="toctitle">Node v0.2.0</div>
|
||||
<div id="toctitle">Node v0.2.2</div>
|
||||
<noscript>JavaScript must be enabled in your browser to display the table of contents.</noscript>
|
||||
</div>
|
||||
<div id='man'>
|
||||
|
||||
12
doc/doc.js
12
doc/doc.js
@@ -23,6 +23,10 @@ NodeDoc.generateToc = function()
|
||||
|
||||
cur_level = this.tagName.substr(1, 1);
|
||||
|
||||
if (last_level != 0 && cur_level <= last_level) {
|
||||
html.push("</li>")
|
||||
}
|
||||
|
||||
if (cur_level > last_level)
|
||||
{
|
||||
html.push('<ul><li>');
|
||||
@@ -38,15 +42,11 @@ NodeDoc.generateToc = function()
|
||||
}
|
||||
|
||||
html.push('<a href="#' + $this.attr('id') + '">' + $this.text().replace(/\(.*\)$/gi, '') + '</a>');
|
||||
if (cur_level == last_level || cur_level > last_level)
|
||||
{
|
||||
html.push('</li>');
|
||||
}
|
||||
|
||||
last_level = cur_level;
|
||||
});
|
||||
|
||||
html.push('</ul>');
|
||||
html.push('</li></ul>');
|
||||
|
||||
var $toc = $('#toc').append(html.join('')).find('ul li ul').each(function()
|
||||
{
|
||||
@@ -175,4 +175,4 @@ NodeDoc.setupSmoothScrolling = function()
|
||||
}
|
||||
});
|
||||
};
|
||||
NodeDoc.init();
|
||||
NodeDoc.init();
|
||||
|
||||
@@ -89,8 +89,8 @@ net.createServer(function (socket) {
|
||||
<a href="http://github.com/ry/node/tree/master">git repo</a>
|
||||
</p>
|
||||
<p>
|
||||
2010.08.20
|
||||
<a href="http://nodejs.org/dist/node-v0.2.0.tar.gz">node-v0.2.0.tar.gz</a>
|
||||
2010.09.17
|
||||
<a href="http://nodejs.org/dist/node-v0.2.2.tar.gz">node-v0.2.2.tar.gz</a>
|
||||
</p>
|
||||
|
||||
<p>Historical: <a href="http://nodejs.org/dist">versions</a>, <a href="http://nodejs.org/docs">docs</a></p>
|
||||
|
||||
@@ -131,6 +131,15 @@ function _deepEqual(actual, expected) {
|
||||
if (actual === expected) {
|
||||
return true;
|
||||
|
||||
} else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) {
|
||||
if (actual.length != expected.length) return false;
|
||||
|
||||
for (var i = 0; i < actual.length; i++) {
|
||||
if (actual[i] !== expected[i]) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
// 7.2. If the expected value is a Date object, the actual value is
|
||||
// equivalent if it is also a Date object that refers to the same time.
|
||||
} else if (actual instanceof Date && expected instanceof Date) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
exports.EventEmitter = process.EventEmitter;
|
||||
var EventEmitter = exports.EventEmitter = process.EventEmitter;
|
||||
|
||||
var isArray = Array.isArray;
|
||||
|
||||
process.EventEmitter.prototype.emit = function (type) {
|
||||
EventEmitter.prototype.emit = function (type) {
|
||||
// If there is no 'error' event listener then throw.
|
||||
if (type === 'error') {
|
||||
if (!this._events || !this._events.error ||
|
||||
@@ -18,27 +18,25 @@ process.EventEmitter.prototype.emit = function (type) {
|
||||
}
|
||||
|
||||
if (!this._events) return false;
|
||||
if (!this._events[type]) return false;
|
||||
var handler = this._events[type];
|
||||
if (!handler) return false;
|
||||
|
||||
if (typeof this._events[type] == 'function') {
|
||||
if (arguments.length < 3) {
|
||||
if (typeof handler == 'function') {
|
||||
if (arguments.length <= 3) {
|
||||
// fast case
|
||||
this._events[type].call( this
|
||||
, arguments[1]
|
||||
, arguments[2]
|
||||
);
|
||||
handler.call(this, arguments[1], arguments[2]);
|
||||
} else {
|
||||
// slower
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
this._events[type].apply(this, args);
|
||||
handler.apply(this, args);
|
||||
}
|
||||
return true;
|
||||
|
||||
} else if (isArray(this._events[type])) {
|
||||
} else if (isArray(handler)) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
|
||||
|
||||
var listeners = this._events[type].slice(0);
|
||||
var listeners = handler.slice();
|
||||
for (var i = 0, l = listeners.length; i < l; i++) {
|
||||
listeners[i].apply(this, args);
|
||||
}
|
||||
@@ -49,9 +47,9 @@ process.EventEmitter.prototype.emit = function (type) {
|
||||
}
|
||||
};
|
||||
|
||||
// process.EventEmitter is defined in src/node_events.cc
|
||||
// process.EventEmitter.prototype.emit() is also defined there.
|
||||
process.EventEmitter.prototype.addListener = function (type, listener) {
|
||||
// EventEmitter is defined in src/node_events.cc
|
||||
// EventEmitter.prototype.emit() is also defined there.
|
||||
EventEmitter.prototype.addListener = function (type, listener) {
|
||||
if ('function' !== typeof listener) {
|
||||
throw new Error('addListener only takes instances of Function');
|
||||
}
|
||||
@@ -76,9 +74,9 @@ process.EventEmitter.prototype.addListener = function (type, listener) {
|
||||
return this;
|
||||
};
|
||||
|
||||
process.EventEmitter.prototype.on = process.EventEmitter.prototype.addListener;
|
||||
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
|
||||
|
||||
process.EventEmitter.prototype.removeListener = function (type, listener) {
|
||||
EventEmitter.prototype.removeListener = function (type, listener) {
|
||||
if ('function' !== typeof listener) {
|
||||
throw new Error('removeListener only takes instances of Function');
|
||||
}
|
||||
@@ -101,13 +99,13 @@ process.EventEmitter.prototype.removeListener = function (type, listener) {
|
||||
return this;
|
||||
};
|
||||
|
||||
process.EventEmitter.prototype.removeAllListeners = function (type) {
|
||||
EventEmitter.prototype.removeAllListeners = function (type) {
|
||||
// does not use listeners(), so no side effect of creating _events[type]
|
||||
if (type && this._events && this._events[type]) this._events[type] = null;
|
||||
return this;
|
||||
};
|
||||
|
||||
process.EventEmitter.prototype.listeners = function (type) {
|
||||
EventEmitter.prototype.listeners = function (type) {
|
||||
if (!this._events) this._events = {};
|
||||
if (!this._events[type]) this._events[type] = [];
|
||||
if (!isArray(this._events[type])) {
|
||||
|
||||
300
lib/fs.js
300
lib/fs.js
@@ -6,7 +6,7 @@ var binding = process.binding('fs');
|
||||
var fs = exports;
|
||||
|
||||
var kMinPoolSpace = 128;
|
||||
var kPoolSize = 40*1024;
|
||||
var kPoolSize = 40 * 1024;
|
||||
|
||||
fs.Stats = binding.Stats;
|
||||
|
||||
@@ -56,7 +56,7 @@ fs.readFile = function (path, encoding_, callback) {
|
||||
function doRead() {
|
||||
if (size < 1) {
|
||||
binding.close(fd);
|
||||
callback(null, buffer);
|
||||
callback(null, encoding ? '' : buffer);
|
||||
return;
|
||||
}
|
||||
// position is offset or null so we can read files on unseekable mediums
|
||||
@@ -140,8 +140,11 @@ fs.closeSync = function (fd) {
|
||||
return binding.close(fd);
|
||||
};
|
||||
|
||||
fs.open = function (path, flags, mode, callback) {
|
||||
if (mode === undefined) { mode = 0666; }
|
||||
fs.open = function (path, flags, mode_, callback) {
|
||||
var mode = (typeof(mode_) == 'number' ? mode_ : 0666);
|
||||
var callback_ = arguments[arguments.length - 1];
|
||||
var callback = (typeof(callback_) == 'function' ? callback_ : null);
|
||||
|
||||
binding.open(path, stringToFlags(flags), mode, callback || noop);
|
||||
};
|
||||
|
||||
@@ -208,7 +211,15 @@ fs.write = function (fd, buffer, offset, length, position, callback) {
|
||||
offset = 0;
|
||||
length = buffer.length;
|
||||
}
|
||||
if(!length) return;
|
||||
|
||||
if (!length) {
|
||||
if (typeof callback == 'function') {
|
||||
process.nextTick(function() {
|
||||
callback(undefined, 0);
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
binding.write(fd, buffer, offset, length, position, callback || noop);
|
||||
};
|
||||
@@ -458,132 +469,121 @@ var path = require('path');
|
||||
var normalize = path.normalize;
|
||||
var normalizeArray = path.normalizeArray;
|
||||
|
||||
fs.realpathSync = function (path) {
|
||||
var seen_links = {}, knownHards = {}, buf, i = 0, part, x, stats;
|
||||
if (path.charAt(0) !== '/') {
|
||||
var cwd = process.cwd().split('/');
|
||||
path = cwd.concat(path.split('/'));
|
||||
path = normalizeArray(path);
|
||||
i = cwd.length;
|
||||
buf = [].concat(cwd);
|
||||
} else {
|
||||
path = normalizeArray(path.split('/'));
|
||||
// realpath
|
||||
// Not using realpath(2) because it's bad.
|
||||
// See: http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
|
||||
fs.realpathSync = realpathSync;
|
||||
fs.realpath = realpath;
|
||||
function realpathSync (p) {
|
||||
if (p.charAt(0) !== '/') {
|
||||
p = path.join(process.cwd(), p);
|
||||
}
|
||||
p = p.split('/');
|
||||
var buf = [ '' ];
|
||||
var seenLinks = {};
|
||||
var knownHard = {};
|
||||
// walk down the path, swapping out linked pathparts for their real
|
||||
// values, and pushing non-link path bits onto the buffer.
|
||||
// then return the buffer.
|
||||
// NB: path.length changes.
|
||||
for (var i = 0; i < p.length; i ++) {
|
||||
// skip over empty path parts.
|
||||
if (p[i] === '') continue;
|
||||
var part = buf.join('/')+'/'+p[i];
|
||||
if (knownHard[part]) {
|
||||
buf.push( p[i] );
|
||||
continue;
|
||||
}
|
||||
var stat = fs.lstatSync(part);
|
||||
if (!stat.isSymbolicLink()) {
|
||||
// not a symlink. easy.
|
||||
knownHard[ part ] = true;
|
||||
buf.push(p[i]);
|
||||
continue;
|
||||
}
|
||||
var id = stat.dev.toString(32)+':'+stat.ino.toString(32);
|
||||
if (seenLinks[id]) throw new Error("cyclic link at "+part);
|
||||
seenLinks[id] = true;
|
||||
var target = fs.readlinkSync(part);
|
||||
if (target.charAt(0) === '/') {
|
||||
// absolute. Start over.
|
||||
buf = [''];
|
||||
p = path.normalizeArray(target.split('/').concat(p.slice(i + 1)));
|
||||
i = 0;
|
||||
continue;
|
||||
}
|
||||
// not absolute. join and splice.
|
||||
target = target.split('/');
|
||||
Array.prototype.splice.apply(p, [i, 1].concat(target));
|
||||
p = path.normalizeArray(p);
|
||||
i = 0;
|
||||
buf = [''];
|
||||
}
|
||||
for (; i<path.length; i++) {
|
||||
part = path.slice(0, i+1).join('/');
|
||||
if (part.length !== 0) {
|
||||
if (part in knownHards) {
|
||||
buf.push(path[i]);
|
||||
} else {
|
||||
stats = fs.lstatSync(part);
|
||||
if (stats.isSymbolicLink()) {
|
||||
x = stats.dev.toString(32)+":"+stats.ino.toString(32);
|
||||
if (x in seen_links)
|
||||
throw new Error("cyclic link at "+part);
|
||||
seen_links[x] = true;
|
||||
part = fs.readlinkSync(part);
|
||||
if (part.charAt(0) === '/') {
|
||||
// absolute
|
||||
path = normalizeArray(part.split('/'));
|
||||
buf = [''];
|
||||
i = 0;
|
||||
} else {
|
||||
// relative
|
||||
Array.prototype.splice.apply(path, [i, 1].concat(part.split('/')));
|
||||
part = normalizeArray(path);
|
||||
var y = 0, L = Math.max(path.length, part.length), delta;
|
||||
for (; y<L && path[y] === part[y]; y++);
|
||||
if (y !== L) {
|
||||
path = part;
|
||||
delta = i-y;
|
||||
i = y-1;
|
||||
if (delta > 0) buf.splice(y, delta);
|
||||
} else {
|
||||
i--;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
buf.push(path[i]);
|
||||
knownHards[buf.join('/')] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return buf.join('/');
|
||||
return buf.join('/') || '/';
|
||||
}
|
||||
|
||||
|
||||
fs.realpath = function (path, callback) {
|
||||
var seen_links = {}, knownHards = {}, buf = [''], i = 0, part, x;
|
||||
if (path.charAt(0) !== '/') {
|
||||
// assumes cwd is canonical
|
||||
var cwd = process.cwd().split('/');
|
||||
path = cwd.concat(path.split('/'));
|
||||
path = normalizeArray(path);
|
||||
i = cwd.length-1;
|
||||
buf = [].concat(cwd);
|
||||
} else {
|
||||
path = normalizeArray(path.split('/'));
|
||||
function realpath (p, cb) {
|
||||
if (p.charAt(0) !== '/') {
|
||||
p = path.join(process.cwd(), p);
|
||||
}
|
||||
function done(err) {
|
||||
if (callback) {
|
||||
if (!err) callback(err, buf.join('/'));
|
||||
else callback(err);
|
||||
p = p.split('/');
|
||||
var buf = [ '' ];
|
||||
var seenLinks = {};
|
||||
var knownHard = {};
|
||||
// walk down the path, swapping out linked pathparts for their real
|
||||
// values, and pushing non-link path bits onto the buffer.
|
||||
// then return the buffer.
|
||||
// NB: path.length changes.
|
||||
var i = 0;
|
||||
var part;
|
||||
LOOP();
|
||||
function LOOP () {
|
||||
i ++;
|
||||
if (!(i < p.length)) return exit();
|
||||
// skip over empty path parts.
|
||||
if (p[i] === '') return process.nextTick(LOOP);
|
||||
part = buf.join('/')+'/'+p[i];
|
||||
if (knownHard[part]) {
|
||||
buf.push( p[i] );
|
||||
return process.nextTick(LOOP);
|
||||
}
|
||||
return fs.lstat(part, gotStat);
|
||||
}
|
||||
function next() {
|
||||
if (++i === path.length) return done();
|
||||
part = path.slice(0, i+1).join('/');
|
||||
if (part.length === 0) return next();
|
||||
if (part in knownHards) {
|
||||
buf.push(path[i]);
|
||||
next();
|
||||
} else {
|
||||
fs.lstat(part, function(err, stats){
|
||||
if (err) return done(err);
|
||||
if (stats.isSymbolicLink()) {
|
||||
x = stats.dev.toString(32)+":"+stats.ino.toString(32);
|
||||
if (x in seen_links)
|
||||
return done(new Error("cyclic link at "+part));
|
||||
seen_links[x] = true;
|
||||
fs.readlink(part, function(err, npart){
|
||||
if (err) return done(err);
|
||||
part = npart;
|
||||
if (part.charAt(0) === '/') {
|
||||
// absolute
|
||||
path = normalizeArray(part.split('/'));
|
||||
buf = [''];
|
||||
i = 0;
|
||||
} else {
|
||||
// relative
|
||||
Array.prototype.splice.apply(path, [i, 1].concat(part.split('/')));
|
||||
part = normalizeArray(path);
|
||||
var y = 0, L = Math.max(path.length, part.length), delta;
|
||||
for (; y<L && path[y] === part[y]; y++);
|
||||
if (y !== L) {
|
||||
path = part;
|
||||
delta = i-y;
|
||||
i = y-1; // resolve new node if needed
|
||||
if (delta > 0) buf.splice(y, delta);
|
||||
}
|
||||
else {
|
||||
i--; // resolve new node if needed
|
||||
}
|
||||
}
|
||||
next();
|
||||
}); // binding.readlink
|
||||
}
|
||||
else {
|
||||
buf.push(path[i]);
|
||||
knownHards[buf.join('/')] = true;
|
||||
next();
|
||||
}
|
||||
}); // binding.lstat
|
||||
function gotStat (er, stat) {
|
||||
if (er) return cb(er);
|
||||
if (!stat.isSymbolicLink()) {
|
||||
// not a symlink. easy.
|
||||
knownHard[ part ] = true;
|
||||
buf.push(p[i]);
|
||||
return process.nextTick(LOOP);
|
||||
}
|
||||
var id = stat.dev.toString(32)+':'+stat.ino.toString(32);
|
||||
if (seenLinks[id]) return cb(new Error("cyclic link at "+part));
|
||||
seenLinks[id] = true;
|
||||
fs.readlink(part, gotTarget);
|
||||
}
|
||||
next();
|
||||
};
|
||||
function gotTarget (er, target) {
|
||||
if (er) return cb(er);
|
||||
if (target.charAt(0) === '/') {
|
||||
// absolute. Start over.
|
||||
buf = [''];
|
||||
p = path.normalizeArray(target.split('/').concat(p.slice(i + 1)));
|
||||
i = 0;
|
||||
return process.nextTick(LOOP);
|
||||
}
|
||||
// not absolute. join and splice.
|
||||
target = target.split('/');
|
||||
Array.prototype.splice.apply(p, [i, 1].concat(target));
|
||||
p = path.normalizeArray(p);
|
||||
i = 0;
|
||||
buf = [''];
|
||||
return process.nextTick(LOOP);
|
||||
}
|
||||
function exit () {
|
||||
cb(null, buf.join('/') || '/');
|
||||
}
|
||||
}
|
||||
|
||||
var pool;
|
||||
function allocNewPool () {
|
||||
@@ -598,8 +598,12 @@ fs.createReadStream = function(path, options) {
|
||||
};
|
||||
|
||||
var ReadStream = fs.ReadStream = function(path, options) {
|
||||
if (!(this instanceof ReadStream)) return new ReadStream(path, options);
|
||||
|
||||
events.EventEmitter.call(this);
|
||||
|
||||
var self = this;
|
||||
|
||||
this.path = path;
|
||||
this.fd = null;
|
||||
this.readable = true;
|
||||
@@ -607,7 +611,7 @@ var ReadStream = fs.ReadStream = function(path, options) {
|
||||
|
||||
this.flags = 'r';
|
||||
this.mode = 0666;
|
||||
this.bufferSize = 4 * 1024;
|
||||
this.bufferSize = 64 * 1024;
|
||||
|
||||
options = options || {};
|
||||
|
||||
@@ -618,11 +622,12 @@ var ReadStream = fs.ReadStream = function(path, options) {
|
||||
this[key] = options[key];
|
||||
}
|
||||
|
||||
if(this.start || this.end) {
|
||||
if(this.start === undefined || this.end === undefined) {
|
||||
self.emit('error', new Error('Both start and end are needed for range streaming.'));
|
||||
} else if(this.start > this.end) {
|
||||
self.emit('error', new Error('start must be <= end'));
|
||||
if (this.start || this.end) {
|
||||
if (this.start === undefined || this.end === undefined) {
|
||||
this.emit('error',
|
||||
new Error('Both start and end are needed for range streaming.'));
|
||||
} else if (this.start > this.end) {
|
||||
this.emit('error', new Error('start must be <= end'));
|
||||
} else {
|
||||
this.firstRead = true;
|
||||
}
|
||||
@@ -632,7 +637,6 @@ var ReadStream = fs.ReadStream = function(path, options) {
|
||||
return;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
fs.open(this.path, this.flags, this.mode, function(err, fd) {
|
||||
if (err) {
|
||||
self.emit('error', err);
|
||||
@@ -792,6 +796,8 @@ fs.createWriteStream = function(path, options) {
|
||||
};
|
||||
|
||||
var WriteStream = fs.WriteStream = function(path, options) {
|
||||
if (!(this instanceof WriteStream)) return new WriteStream(path, options);
|
||||
|
||||
events.EventEmitter.call(this);
|
||||
|
||||
this.path = path;
|
||||
@@ -829,7 +835,10 @@ WriteStream.prototype.flush = function () {
|
||||
var self = this;
|
||||
|
||||
var args = this._queue.shift();
|
||||
if (!args) return self.emit('drain');
|
||||
if (!args) {
|
||||
if (this.drainable) { self.emit('drain'); }
|
||||
return;
|
||||
}
|
||||
|
||||
this.busy = true;
|
||||
|
||||
@@ -885,6 +894,8 @@ WriteStream.prototype.write = function (data) {
|
||||
throw new Error('stream not writeable');
|
||||
}
|
||||
|
||||
this.drainable = true;
|
||||
|
||||
var cb;
|
||||
if (typeof(arguments[arguments.length-1]) == 'function') {
|
||||
cb = arguments[arguments.length-1];
|
||||
@@ -934,22 +945,27 @@ WriteStream.prototype.forceClose = function (cb) {
|
||||
};
|
||||
|
||||
|
||||
WriteStream.prototype.forceClose = function (cb) {
|
||||
WriteStream.prototype.destroy = function (cb) {
|
||||
var self = this;
|
||||
this.writeable = false;
|
||||
fs.close(self.fd, function(err) {
|
||||
if (err) {
|
||||
if (cb) {
|
||||
cb(err);
|
||||
|
||||
function close() {
|
||||
fs.close(self.fd, function(err) {
|
||||
if (err) {
|
||||
if (cb) { cb(err); }
|
||||
self.emit('error', err);
|
||||
return;
|
||||
}
|
||||
|
||||
self.emit('error', err);
|
||||
return;
|
||||
}
|
||||
if (cb) { cb(null); }
|
||||
self.emit('close');
|
||||
});
|
||||
}
|
||||
|
||||
if (cb) {
|
||||
cb(null);
|
||||
}
|
||||
self.emit('close');
|
||||
});
|
||||
if (this.fd) {
|
||||
close();
|
||||
} else {
|
||||
this.addListener('open', close);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -713,6 +713,7 @@ function httpSocketSetup (socket) {
|
||||
|
||||
|
||||
function Server (requestListener) {
|
||||
if (!(this instanceof Server)) return new Server(requestListener);
|
||||
net.Server.call(this);
|
||||
|
||||
if(requestListener){
|
||||
@@ -834,6 +835,7 @@ function connectionListener (socket) {
|
||||
|
||||
|
||||
function Client ( ) {
|
||||
if (!(this instanceof Client)) return new Client();
|
||||
net.Stream.call(this);
|
||||
var self = this;
|
||||
|
||||
|
||||
28
lib/net.js
28
lib/net.js
@@ -513,6 +513,7 @@ function initStream (self) {
|
||||
}
|
||||
|
||||
function Stream (fd, type) {
|
||||
if (!(this instanceof Stream)) return new Stream(fd, type);
|
||||
events.EventEmitter.call(this);
|
||||
|
||||
this.fd = null;
|
||||
@@ -855,7 +856,7 @@ function doConnect (socket, port, host) {
|
||||
};
|
||||
}
|
||||
|
||||
function isPort (x) { return parseInt(x) >= 0; }
|
||||
function toPort (x) { return (x = Number(x)) >= 0 ? x : false }
|
||||
|
||||
|
||||
// var stream = new Stream();
|
||||
@@ -872,9 +873,16 @@ Stream.prototype.connect = function () {
|
||||
|
||||
self._connecting = true; // set false in doConnect
|
||||
|
||||
if (isPort(arguments[0])) {
|
||||
var port = toPort(arguments[0])
|
||||
if (port === false) {
|
||||
// UNIX
|
||||
self.fd = socket('unix');
|
||||
self.type = 'unix';
|
||||
|
||||
setImplmentationMethods(this);
|
||||
doConnect(self, arguments[0]);
|
||||
} else {
|
||||
// TCP
|
||||
var port = arguments[0];
|
||||
dns.lookup(arguments[1], function (err, ip, addressType) {
|
||||
if (err) {
|
||||
self.emit('error', err);
|
||||
@@ -884,13 +892,6 @@ Stream.prototype.connect = function () {
|
||||
doConnect(self, port, ip);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// UNIX
|
||||
self.fd = socket('unix');
|
||||
self.type = 'unix';
|
||||
|
||||
setImplmentationMethods(this);
|
||||
doConnect(self, arguments[0]);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1032,6 +1033,7 @@ Stream.prototype.end = function (data, encoding) {
|
||||
|
||||
|
||||
function Server (listener) {
|
||||
if (!(this instanceof Server)) return new Server(listener);
|
||||
events.EventEmitter.call(this);
|
||||
var self = this;
|
||||
|
||||
@@ -1107,7 +1109,8 @@ Server.prototype.listen = function () {
|
||||
self.addListener('listening', lastArg);
|
||||
}
|
||||
|
||||
if (!isPort(arguments[0])) {
|
||||
var port = toPort(arguments[0])
|
||||
if (port === false) {
|
||||
// the first argument specifies a path
|
||||
self.fd = socket('unix');
|
||||
self.type = 'unix';
|
||||
@@ -1142,13 +1145,12 @@ Server.prototype.listen = function () {
|
||||
// The port can be found with server.address()
|
||||
self.type = 'tcp4';
|
||||
self.fd = socket(self.type);
|
||||
bind(self.fd, arguments[0]);
|
||||
bind(self.fd, port);
|
||||
process.nextTick(function () {
|
||||
self._doListen();
|
||||
});
|
||||
} else {
|
||||
// the first argument is the port, the second an IP
|
||||
var port = arguments[0];
|
||||
dns.lookup(arguments[1], function (err, ip, addressType) {
|
||||
if (err) {
|
||||
self.emit('error', err);
|
||||
|
||||
138
lib/readline.js
138
lib/readline.js
@@ -15,24 +15,26 @@ var EventEmitter = require('events').EventEmitter;
|
||||
var stdio = process.binding('stdio');
|
||||
|
||||
|
||||
|
||||
exports.createInterface = function (output, completer) {
|
||||
return new Interface(output, completer);
|
||||
};
|
||||
|
||||
function Interface (output, completer) {
|
||||
if (!(this instanceof Interface)) return new Interface(output, completer);
|
||||
EventEmitter.call(this);
|
||||
|
||||
this.output = output;
|
||||
this.completer = completer;
|
||||
|
||||
this.setPrompt("node> ");
|
||||
this.setPrompt("> ");
|
||||
|
||||
this._tty = output.fd < 3;
|
||||
this.enabled = output.fd < 3; // Looks like a TTY.
|
||||
|
||||
if (parseInt(process.env['NODE_NO_READLINE'])) {
|
||||
this._tty = false;
|
||||
this.enabled = false;
|
||||
}
|
||||
|
||||
if (this._tty) {
|
||||
if (this.enabled) {
|
||||
// input refers to stdin
|
||||
|
||||
// Current line
|
||||
@@ -40,22 +42,28 @@ function Interface (output, completer) {
|
||||
|
||||
// Check process.env.TERM ?
|
||||
stdio.setRawMode(true);
|
||||
this._tty = true;
|
||||
this.enabled = true;
|
||||
|
||||
// Cursor position on the line.
|
||||
this.cursor = 0;
|
||||
|
||||
this.history = [];
|
||||
this.historyIndex = -1;
|
||||
|
||||
exports.columns = process.binding('stdio').getColumns();
|
||||
|
||||
if (process.listeners("SIGWINCH").length === 0) {
|
||||
process.on("SIGWINCH", function () {
|
||||
exports.columns = process.binding('stdio').getColumns();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inherits(Interface, EventEmitter);
|
||||
|
||||
Interface.prototype.__defineGetter__("columns", function () {
|
||||
if (this._tty) {
|
||||
return stdio.getColumns();
|
||||
}
|
||||
return exports.columns;
|
||||
});
|
||||
|
||||
Interface.prototype.setPrompt = function (prompt, length) {
|
||||
@@ -65,7 +73,7 @@ Interface.prototype.setPrompt = function (prompt, length) {
|
||||
|
||||
|
||||
Interface.prototype.prompt = function () {
|
||||
if (this._tty) {
|
||||
if (this.enabled) {
|
||||
this.cursor = 0;
|
||||
this._refreshLine();
|
||||
} else {
|
||||
@@ -111,7 +119,7 @@ Interface.prototype._refreshLine = function () {
|
||||
|
||||
|
||||
Interface.prototype.close = function (d) {
|
||||
if (this._tty) {
|
||||
if (this.enabled) {
|
||||
stdio.setRawMode(false);
|
||||
}
|
||||
this.emit('close');
|
||||
@@ -121,7 +129,7 @@ Interface.prototype.close = function (d) {
|
||||
|
||||
Interface.prototype.write = function (d) {
|
||||
if (this._closed) return;
|
||||
return this._tty ? this._ttyWrite(d) : this._normalWrite(d);
|
||||
return this.enabled ? this._ttyWrite(d) : this._normalWrite(d);
|
||||
};
|
||||
|
||||
|
||||
@@ -261,7 +269,12 @@ Interface.prototype._ttyWrite = function (b) {
|
||||
/* ctrl+c */
|
||||
case 3:
|
||||
//process.kill(process.pid, "SIGINT");
|
||||
this.close();
|
||||
if (this.listeners('SIGINT').length) {
|
||||
this.emit('SIGINT');
|
||||
} else {
|
||||
// default behavior, end the readline
|
||||
this.close();
|
||||
}
|
||||
break;
|
||||
|
||||
case 4: // control-d, delete right or EOF
|
||||
@@ -332,6 +345,17 @@ Interface.prototype._ttyWrite = function (b) {
|
||||
this._historyNext();
|
||||
break;
|
||||
|
||||
case 23: // control-w, delete backwards to a word boundary
|
||||
if (this.cursor !== 0) {
|
||||
var leading = this.line.slice(0, this.cursor);
|
||||
var match = leading.match(/\s?((\W+|\w+)\s*)$/);
|
||||
leading = leading.slice(0, leading.length - match[1].length);
|
||||
this.line = leading + this.line.slice(this.cursor, this.line.length);
|
||||
this.cursor = leading.length;
|
||||
this._refreshLine();
|
||||
}
|
||||
break;
|
||||
|
||||
case 9: // tab, completion
|
||||
if (this.completer) {
|
||||
this._tabComplete();
|
||||
@@ -347,34 +371,104 @@ Interface.prototype._ttyWrite = function (b) {
|
||||
return;
|
||||
|
||||
case 27: /* escape sequence */
|
||||
if (b[1] === 98 && this.cursor > 0) { // meta-b - backward word
|
||||
var next_word, next_non_word, previous_word, previous_non_word;
|
||||
|
||||
} else if (b[1] === 102 && this.cursor < this.line.length) { // meta-f - forward word
|
||||
if (b[1] === 98 && this.cursor > 0) {
|
||||
// meta-b - backward word
|
||||
previous_word = this.line.slice(0, this.cursor)
|
||||
.split('').reverse().join('')
|
||||
.search(/\w/);
|
||||
if (previous_word !== -1) {
|
||||
previous_non_word = this.line.slice(0, this.cursor - previous_word)
|
||||
.split('').reverse().join('')
|
||||
.search(/\W/);
|
||||
if (previous_non_word !== -1) {
|
||||
this.cursor -= previous_word + previous_non_word;
|
||||
this._refreshLine();
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.cursor = 0;
|
||||
this._refreshLine();
|
||||
|
||||
} else if (b[1] === 91 && b[2] === 68) { // left arrow
|
||||
} else if (b[1] === 102 && this.cursor < this.line.length) {
|
||||
// meta-f - forward word
|
||||
next_word = this.line.slice(this.cursor, this.line.length).search(/\w/);
|
||||
if (next_word !== -1) {
|
||||
next_non_word =
|
||||
this.line.slice(this.cursor + next_word, this.line.length)
|
||||
.search(/\W/);
|
||||
if (next_non_word !== -1) {
|
||||
this.cursor += next_word + next_non_word;
|
||||
this._refreshLine();
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.cursor = this.line.length;
|
||||
this._refreshLine();
|
||||
|
||||
} else if (b[1] === 100 && this.cursor < this.line.length) {
|
||||
// meta-d delete forward word
|
||||
next_word = this.line.slice(this.cursor, this.line.length).search(/\w/);
|
||||
if (next_word !== -1) {
|
||||
next_non_word =
|
||||
this.line.slice(this.cursor + next_word, this.line.length)
|
||||
.search(/\W/);
|
||||
if (next_non_word !== -1) {
|
||||
this.line =
|
||||
this.line.slice(this.cursor + next_word + next_non_word);
|
||||
this.cursor = 0;
|
||||
this._refreshLine();
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.line = '';
|
||||
this.cursor = 0;
|
||||
this._refreshLine();
|
||||
|
||||
} else if (b[1] === 91 && b[2] === 68) {
|
||||
// left arrow
|
||||
if (this.cursor > 0) {
|
||||
this.cursor--;
|
||||
this.output.write('\x1b[0D');
|
||||
}
|
||||
} else if (b[1] === 91 && b[2] === 67) { // right arrow
|
||||
|
||||
} else if (b[1] === 91 && b[2] === 67) {
|
||||
// right arrow
|
||||
if (this.cursor != this.line.length) {
|
||||
this.cursor++;
|
||||
this.output.write('\x1b[0C');
|
||||
}
|
||||
} else if (b[1] === 91 && b[2] === 72) { // home
|
||||
|
||||
} else if ((b[1] === 91 && b[2] === 72) ||
|
||||
(b[1] === 79 && b[2] === 72) ||
|
||||
(b[1] === 91 && b[2] === 55) ||
|
||||
(b[1] === 91 && b[2] === 49 && (b[3] && b[3] === 126))) {
|
||||
// home
|
||||
this.cursor = 0;
|
||||
this._refreshLine();
|
||||
} else if (b[1] === 91 && b[2] === 70) { // end
|
||||
} else if ((b[1] === 91 && b[2] === 70) ||
|
||||
(b[1] === 79 && b[2] === 70) ||
|
||||
(b[1] === 91 && b[2] === 56) ||
|
||||
(b[1] === 91 && b[2] === 52 && (b[3] && b[3] === 126))) {
|
||||
// end
|
||||
this.cursor = this.line.length;
|
||||
this._refreshLine();
|
||||
} else if (b[1] === 91 && b[2] === 65) { // up arrow
|
||||
|
||||
} else if (b[1] === 91 && b[2] === 65) {
|
||||
// up arrow
|
||||
this._historyPrev();
|
||||
} else if (b[1] === 91 && b[2] === 66) { // down arrow
|
||||
|
||||
} else if (b[1] === 91 && b[2] === 66) {
|
||||
// down arrow
|
||||
this._historyNext();
|
||||
} else if (b[1] === 91 && b[2] === 51 && this.cursor < this.line.length) { // delete right
|
||||
|
||||
} else if (b[1] === 91 && b[2] === 51 && this.cursor < this.line.length) {
|
||||
// delete right
|
||||
this.line = this.line.slice(0, this.cursor) +
|
||||
this.line.slice(this.cursor+1, this.line.length);
|
||||
this._refreshLine();
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
26
lib/repl.js
26
lib/repl.js
@@ -48,13 +48,31 @@ function REPLServer(prompt, stream) {
|
||||
self.buffered_cmd = '';
|
||||
|
||||
self.stream = stream || process.openStdin();
|
||||
self.prompt = prompt || "node> ";
|
||||
self.prompt = prompt || "> ";
|
||||
|
||||
var rli = self.rli = rl.createInterface(self.stream, function (text) {
|
||||
return self.complete(text);
|
||||
});
|
||||
|
||||
if (rli.enabled) {
|
||||
// Turn on ANSI coloring.
|
||||
exports.writer = function(obj, showHidden, depth) {
|
||||
return sys.inspect(obj, showHidden, depth, true);
|
||||
}
|
||||
}
|
||||
|
||||
rli.setPrompt(self.prompt);
|
||||
|
||||
rli.on("SIGINT", function () {
|
||||
if (self.buffered_cmd && self.buffered_cmd.length > 0) {
|
||||
rli.write("\n");
|
||||
self.buffered_cmd = '';
|
||||
self.displayPrompt();
|
||||
} else {
|
||||
rli.close();
|
||||
}
|
||||
});
|
||||
|
||||
self.stream.addListener("data", function (chunk) {
|
||||
rli.write(chunk);
|
||||
});
|
||||
@@ -130,7 +148,7 @@ exports.start = function (prompt, source) {
|
||||
};
|
||||
|
||||
REPLServer.prototype.displayPrompt = function () {
|
||||
this.rli.setPrompt(this.buffered_cmd.length ? '... ' : this.prompt);
|
||||
this.rli.setPrompt(this.buffered_cmd.length ? '... ' : this.prompt);
|
||||
this.rli.prompt();
|
||||
};
|
||||
|
||||
@@ -380,7 +398,8 @@ REPLServer.prototype.parseREPLKeyword = function (cmd) {
|
||||
var self = this;
|
||||
|
||||
switch (cmd) {
|
||||
case ".break":
|
||||
case ".break":
|
||||
// TODO remove me after 0.3.x
|
||||
self.buffered_cmd = '';
|
||||
self.displayPrompt();
|
||||
return true;
|
||||
@@ -394,7 +413,6 @@ REPLServer.prototype.parseREPLKeyword = function (cmd) {
|
||||
self.stream.destroy();
|
||||
return true;
|
||||
case ".help":
|
||||
self.stream.write(".break\tSometimes you get stuck in a place you can't get out... This will get you out.\n");
|
||||
self.stream.write(".clear\tBreak, and also clear the local context.\n");
|
||||
self.stream.write(".exit\tExit the prompt\n");
|
||||
self.stream.write(".help\tShow repl options\n");
|
||||
|
||||
104
lib/sys.js
104
lib/sys.js
@@ -33,10 +33,51 @@ var error = exports.error = function (x) {
|
||||
*
|
||||
* @param {Object} value The object to print out
|
||||
* @param {Boolean} showHidden Flag that shows hidden (not enumerable)
|
||||
* properties of objects.
|
||||
* properties of objects.
|
||||
* @param {Number} depth Depth in which to descend in object. Default is 2.
|
||||
* @param {Boolean} colors Flag to turn on ANSI escape codes to color the
|
||||
* output. Default is false (no coloring).
|
||||
*/
|
||||
exports.inspect = function (obj, showHidden, depth) {
|
||||
exports.inspect = function (obj, showHidden, depth, colors) {
|
||||
var seen = [];
|
||||
|
||||
var stylize = function (str, styleType) {
|
||||
// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
|
||||
var styles = { 'bold' : [1, 22]
|
||||
, 'italic' : [3, 23]
|
||||
, 'underline' : [4, 24]
|
||||
, 'inverse' : [7, 27]
|
||||
, 'white' : [37, 39]
|
||||
, 'grey' : [90, 39]
|
||||
, 'black' : [30, 39]
|
||||
, 'blue' : [34, 39]
|
||||
, 'cyan' : [36, 39]
|
||||
, 'green' : [32, 39]
|
||||
, 'magenta' : [35, 39]
|
||||
, 'red' : [31, 39]
|
||||
, 'yellow' : [33, 39]
|
||||
};
|
||||
var style = { "special": "grey"
|
||||
, "number": "blue"
|
||||
, "boolean": "blue"
|
||||
, "undefined": "red"
|
||||
, "null": "red"
|
||||
, "string": "green"
|
||||
, "date": "magenta"
|
||||
//, "name": intentionally not styling
|
||||
, "regexp": "cyan"
|
||||
}[styleType];
|
||||
if (style) {
|
||||
return '\033[' + styles[style][0] + 'm' + str +
|
||||
'\033[' + styles[style][1] + 'm';
|
||||
} else {
|
||||
return str;
|
||||
}
|
||||
};
|
||||
if (! colors) {
|
||||
stylize = function(str, styleType) { return str; };
|
||||
}
|
||||
|
||||
function format(value, recurseTimes) {
|
||||
// Provide a hook for user-specified inspect functions.
|
||||
// Check that value is an object with an inspect function on it
|
||||
@@ -50,16 +91,18 @@ exports.inspect = function (obj, showHidden, depth) {
|
||||
|
||||
// Primitive types cannot have properties
|
||||
switch (typeof value) {
|
||||
case 'undefined': return 'undefined';
|
||||
case 'string': return JSON.stringify(value).replace(/'/g, "\\'")
|
||||
.replace(/\\"/g, '"')
|
||||
.replace(/(^"|"$)/g, "'");
|
||||
case 'number': return '' + value;
|
||||
case 'boolean': return '' + value;
|
||||
case 'undefined': return stylize('undefined', 'undefined');
|
||||
case 'string': return stylize(
|
||||
JSON.stringify(value).replace(/'/g, "\\'")
|
||||
.replace(/\\"/g, '"')
|
||||
.replace(/(^"|"$)/g, "'"),
|
||||
'string');
|
||||
case 'number': return stylize('' + value, 'number');
|
||||
case 'boolean': return stylize('' + value, 'boolean');
|
||||
}
|
||||
// For some reason typeof null is "object", so special case here.
|
||||
if (value === null) {
|
||||
return 'null';
|
||||
return stylize('null', 'null');
|
||||
}
|
||||
|
||||
// Look up the keys of the object.
|
||||
@@ -74,15 +117,15 @@ exports.inspect = function (obj, showHidden, depth) {
|
||||
// Functions without properties can be shortcutted.
|
||||
if (typeof value === 'function' && keys.length === 0) {
|
||||
if (isRegExp(value)) {
|
||||
return '' + value;
|
||||
return stylize('' + value, 'regexp');
|
||||
} else {
|
||||
return '[Function]';
|
||||
return stylize('[Function]', 'special');
|
||||
}
|
||||
}
|
||||
|
||||
// Dates without properties can be shortcutted
|
||||
if (isDate(value) && keys.length === 0) {
|
||||
return value.toUTCString();
|
||||
return stylize(value.toUTCString(), 'date');
|
||||
}
|
||||
|
||||
var base, type, braces;
|
||||
@@ -115,24 +158,24 @@ exports.inspect = function (obj, showHidden, depth) {
|
||||
|
||||
if (recurseTimes < 0) {
|
||||
if (isRegExp(value)) {
|
||||
return '' + value;
|
||||
return stylize('' + value, "regexp");
|
||||
} else {
|
||||
return "[Object]";
|
||||
return stylize("[Object]", "special");
|
||||
}
|
||||
}
|
||||
|
||||
output = keys.map(function (key) {
|
||||
var output = keys.map(function (key) {
|
||||
var name, str;
|
||||
if (value.__lookupGetter__) {
|
||||
if (value.__lookupGetter__(key)) {
|
||||
if (value.__lookupSetter__(key)) {
|
||||
str = "[Getter/Setter]";
|
||||
str = stylize("[Getter/Setter]", "special");
|
||||
} else {
|
||||
str = "[Getter]";
|
||||
str = stylize("[Getter]", "special");
|
||||
}
|
||||
} else {
|
||||
if (value.__lookupSetter__(key)) {
|
||||
str = "[Setter]";
|
||||
str = stylize("[Setter]", "special");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -160,7 +203,7 @@ exports.inspect = function (obj, showHidden, depth) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
str = '[Circular]';
|
||||
str = stylize('[Circular]', 'special');
|
||||
}
|
||||
}
|
||||
if (typeof name === 'undefined') {
|
||||
@@ -170,11 +213,13 @@ exports.inspect = function (obj, showHidden, depth) {
|
||||
name = JSON.stringify('' + key);
|
||||
if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
|
||||
name = name.substr(1, name.length-2);
|
||||
name = stylize(name, "name");
|
||||
}
|
||||
else {
|
||||
name = name.replace(/'/g, "\\'")
|
||||
.replace(/\\"/g, '"')
|
||||
.replace(/(^"|"$)/g, "'");
|
||||
name = stylize(name, "string");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,6 +328,15 @@ exports.exec = function () {
|
||||
|
||||
|
||||
exports.pump = function (readStream, writeStream, callback) {
|
||||
var callbackCalled = false;
|
||||
|
||||
function call (a, b, c) {
|
||||
if (callback && !callbackCalled) {
|
||||
callback(a, b, c);
|
||||
callbackCalled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!readStream.pause) readStream.pause = function () {readStream.emit("pause")};
|
||||
if (!readStream.resume) readStream.resume = function () {readStream.emit("resume")};
|
||||
|
||||
@@ -307,7 +361,17 @@ exports.pump = function (readStream, writeStream, callback) {
|
||||
});
|
||||
|
||||
readStream.addListener("close", function () {
|
||||
if (callback) callback();
|
||||
call();
|
||||
});
|
||||
|
||||
readStream.addListener("error", function (err) {
|
||||
writeStream.end();
|
||||
call(err);
|
||||
});
|
||||
|
||||
writeStream.addListener("error", function (err) {
|
||||
readStream.destroy();
|
||||
call(err);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
19
lib/url.js
19
lib/url.js
@@ -18,7 +18,7 @@ var protocolPattern = /^([a-z0-9]+:)/,
|
||||
path = require("path"), // internal module, guaranteed to be loaded already.
|
||||
querystring = require('querystring');
|
||||
|
||||
function urlParse (url, parseQueryString) {
|
||||
function urlParse (url, parseQueryString, slashesDenoteHost) {
|
||||
if (url && typeof(url) === "object" && url.href) return url;
|
||||
|
||||
var out = { href : url },
|
||||
@@ -32,10 +32,15 @@ function urlParse (url, parseQueryString) {
|
||||
}
|
||||
|
||||
// figure out if it's got a host
|
||||
var slashes = rest.substr(0, 2) === "//";
|
||||
if (slashes && !(proto && hostlessProtocol[proto])) {
|
||||
rest = rest.substr(2);
|
||||
out.slashes = true;
|
||||
// user@server is *always* interpreted as a hostname, and url
|
||||
// resolution will treat //foo/bar as host=foo,path=bar because that's
|
||||
// how the browser resolves relative URLs.
|
||||
if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) {
|
||||
var slashes = rest.substr(0, 2) === "//";
|
||||
if (slashes && !(proto && hostlessProtocol[proto])) {
|
||||
rest = rest.substr(2);
|
||||
out.slashes = true;
|
||||
}
|
||||
}
|
||||
if (!hostlessProtocol[proto] && (slashes || (proto && !slashedProtocol[proto]))) {
|
||||
// there's a hostname.
|
||||
@@ -133,8 +138,8 @@ function urlResolve (source, relative) {
|
||||
function urlResolveObject (source, relative) {
|
||||
if (!source) return relative;
|
||||
|
||||
source = urlParse(urlFormat(source));
|
||||
relative = urlParse(urlFormat(relative));
|
||||
source = urlParse(urlFormat(source), false, true);
|
||||
relative = urlParse(urlFormat(relative), false, true);
|
||||
|
||||
// hash is always overridden, no matter what.
|
||||
source.hash = relative.hash;
|
||||
|
||||
37
src/node.cc
37
src/node.cc
@@ -73,7 +73,8 @@ static bool use_debug_agent = false;
|
||||
static bool debug_wait_connect = false;
|
||||
static int debug_port=5858;
|
||||
|
||||
static ev_prepare next_tick_watcher;
|
||||
static ev_check check_tick_watcher;
|
||||
static ev_prepare prepare_tick_watcher;
|
||||
static ev_idle tick_spinner;
|
||||
static bool need_tick_cb;
|
||||
static Persistent<String> tick_callback_sym;
|
||||
@@ -164,6 +165,11 @@ static void Check(EV_P_ ev_check *watcher, int revents) {
|
||||
static Handle<Value> NeedTickCallback(const Arguments& args) {
|
||||
HandleScope scope;
|
||||
need_tick_cb = true;
|
||||
// TODO: this tick_spinner shouldn't be necessary. An ev_prepare should be
|
||||
// sufficent, the problem is only in the case of the very last "tick" -
|
||||
// there is nothing left to do in the event loop and libev will exit. The
|
||||
// ev_prepare callback isn't called before exiting. Thus we start this
|
||||
// tick_spinner to keep the event loop alive long enough to handle it.
|
||||
ev_idle_start(EV_DEFAULT_UC_ &tick_spinner);
|
||||
return Undefined();
|
||||
}
|
||||
@@ -175,10 +181,7 @@ static void Spin(EV_P_ ev_idle *watcher, int revents) {
|
||||
}
|
||||
|
||||
|
||||
static void Tick(EV_P_ ev_prepare *watcher, int revents) {
|
||||
assert(watcher == &next_tick_watcher);
|
||||
assert(revents == EV_PREPARE);
|
||||
|
||||
static void Tick(void) {
|
||||
// Avoid entering a V8 scope.
|
||||
if (!need_tick_cb) return;
|
||||
|
||||
@@ -207,6 +210,20 @@ static void Tick(EV_P_ ev_prepare *watcher, int revents) {
|
||||
}
|
||||
|
||||
|
||||
static void PrepareTick(EV_P_ ev_prepare *watcher, int revents) {
|
||||
assert(watcher == &prepare_tick_watcher);
|
||||
assert(revents == EV_PREPARE);
|
||||
Tick();
|
||||
}
|
||||
|
||||
|
||||
static void CheckTick(EV_P_ ev_check *watcher, int revents) {
|
||||
assert(watcher == &check_tick_watcher);
|
||||
assert(revents == EV_CHECK);
|
||||
Tick();
|
||||
}
|
||||
|
||||
|
||||
static void DoPoll(EV_P_ ev_idle *watcher, int revents) {
|
||||
assert(watcher == &eio_poller);
|
||||
assert(revents == EV_IDLE);
|
||||
@@ -1802,14 +1819,18 @@ int main(int argc, char *argv[]) {
|
||||
// TODO(Ryan) I'm experiencing abnormally high load using Solaris's
|
||||
// EVBACKEND_PORT. Temporarally forcing select() until I debug.
|
||||
ev_default_loop(EVBACKEND_POLL);
|
||||
#elif defined(__APPLE_CC__) && __APPLE_CC__ >= 5659
|
||||
#elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
|
||||
ev_default_loop(EVBACKEND_KQUEUE);
|
||||
#else
|
||||
ev_default_loop(EVFLAG_AUTO);
|
||||
#endif
|
||||
|
||||
ev_prepare_init(&node::next_tick_watcher, node::Tick);
|
||||
ev_prepare_start(EV_DEFAULT_UC_ &node::next_tick_watcher);
|
||||
ev_prepare_init(&node::prepare_tick_watcher, node::PrepareTick);
|
||||
ev_prepare_start(EV_DEFAULT_UC_ &node::prepare_tick_watcher);
|
||||
ev_unref(EV_DEFAULT_UC);
|
||||
|
||||
ev_check_init(&node::check_tick_watcher, node::CheckTick);
|
||||
ev_check_start(EV_DEFAULT_UC_ &node::check_tick_watcher);
|
||||
ev_unref(EV_DEFAULT_UC);
|
||||
|
||||
ev_idle_init(&node::tick_spinner, node::Spin);
|
||||
|
||||
@@ -25,7 +25,8 @@ namespace node {
|
||||
|
||||
#define NODE_DEFINE_CONSTANT(target, constant) \
|
||||
(target)->Set(v8::String::NewSymbol(#constant), \
|
||||
v8::Integer::New(constant))
|
||||
v8::Integer::New(constant), \
|
||||
static_cast<v8::PropertyAttribute>(v8::ReadOnly|v8::DontDelete))
|
||||
|
||||
#define NODE_SET_METHOD(obj, name, callback) \
|
||||
obj->Set(v8::String::NewSymbol(name), \
|
||||
|
||||
535
src/node.js
535
src/node.js
@@ -49,9 +49,20 @@ var nextTickQueue = [];
|
||||
process._tickCallback = function () {
|
||||
var l = nextTickQueue.length;
|
||||
if (l === 0) return;
|
||||
for (var i = 0; i < l; i++) {
|
||||
nextTickQueue[i]();
|
||||
|
||||
try {
|
||||
for (var i = 0; i < l; i++) {
|
||||
nextTickQueue[i]();
|
||||
}
|
||||
}
|
||||
catch(e) {
|
||||
nextTickQueue.splice(0, i+1);
|
||||
if (i+1 < l) {
|
||||
process._needTickCallback();
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
nextTickQueue.splice(0, l);
|
||||
};
|
||||
|
||||
@@ -60,6 +71,244 @@ process.nextTick = function (callback) {
|
||||
process._needTickCallback();
|
||||
};
|
||||
|
||||
// Native module system
|
||||
|
||||
var internalModuleCache = {},
|
||||
// This contains the source code for the files in lib/
|
||||
// Like, natives.fs is the contents of lib/fs.js
|
||||
nativeSource = process.binding('natives');
|
||||
|
||||
function requireNative (id) {
|
||||
if (internalModuleCache[id]) return internalModuleCache[id].exports;
|
||||
if (!nativeSource[id]) throw new Error('No such native module ' + id);
|
||||
|
||||
var m = { id: id, exports: {} };
|
||||
internalModuleCache[id] = m;
|
||||
|
||||
// Compile the native module. Create wrapper function
|
||||
var wrapper = "(function (exports, require, module) { "
|
||||
+ nativeSource[id]
|
||||
+ "\n});";
|
||||
|
||||
var compiledWrapper = process.compile(wrapper, id);
|
||||
compiledWrapper.apply(m.exports, [m.exports, requireNative, m]);
|
||||
|
||||
m.loaded = true;
|
||||
|
||||
return m.exports;
|
||||
}
|
||||
|
||||
|
||||
// Load events module in order to access prototype elements on process like
|
||||
// process.addListener.
|
||||
var events = requireNative('events');
|
||||
|
||||
|
||||
// Signal Handlers
|
||||
(function() {
|
||||
var signalWatchers = {};
|
||||
var addListener = process.addListener;
|
||||
var removeListener = process.removeListener;
|
||||
|
||||
function isSignal (event) {
|
||||
return event.slice(0, 3) === 'SIG' && process.hasOwnProperty(event);
|
||||
};
|
||||
|
||||
// Wrap addListener for the special signal types
|
||||
process.on = process.addListener = function (type, listener) {
|
||||
var ret = addListener.apply(this, arguments);
|
||||
if (isSignal(type)) {
|
||||
if (!signalWatchers.hasOwnProperty(type)) {
|
||||
var b = process.binding('signal_watcher'),
|
||||
w = new b.SignalWatcher(process[type]);
|
||||
w.callback = function () {
|
||||
process.emit(type);
|
||||
}
|
||||
signalWatchers[type] = w;
|
||||
w.start();
|
||||
} else if (this.listeners(type).length === 1) {
|
||||
signalWatchers[event].start();
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
process.removeListener = function (type, listener) {
|
||||
var ret = removeListener.apply(this, arguments);
|
||||
if (isSignal(type)) {
|
||||
process.assert(signalWatchers.hasOwnProperty(type));
|
||||
|
||||
if (this.listeners(type).length === 0) {
|
||||
signalWatchers[type].stop();
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
})();
|
||||
|
||||
// Timers
|
||||
function addTimerListener (callback) {
|
||||
var timer = this;
|
||||
// Special case the no param case to avoid the extra object creation.
|
||||
if (arguments.length > 2) {
|
||||
var args = Array.prototype.slice.call(arguments, 2);
|
||||
timer.callback = function () { callback.apply(timer, args); };
|
||||
} else {
|
||||
timer.callback = callback;
|
||||
}
|
||||
}
|
||||
|
||||
global.setTimeout = function (callback, after) {
|
||||
var timer = new process.Timer();
|
||||
addTimerListener.apply(timer, arguments);
|
||||
timer.start(after, 0);
|
||||
return timer;
|
||||
};
|
||||
|
||||
global.setInterval = function (callback, repeat) {
|
||||
var timer = new process.Timer();
|
||||
addTimerListener.apply(timer, arguments);
|
||||
timer.start(repeat, repeat ? repeat : 1);
|
||||
return timer;
|
||||
};
|
||||
|
||||
global.clearTimeout = function (timer) {
|
||||
if (timer instanceof process.Timer) {
|
||||
timer.stop();
|
||||
}
|
||||
};
|
||||
|
||||
global.clearInterval = global.clearTimeout;
|
||||
|
||||
var stdout;
|
||||
process.__defineGetter__('stdout', function () {
|
||||
if (stdout) return stdout;
|
||||
|
||||
var binding = process.binding('stdio'),
|
||||
net = requireNative('net'),
|
||||
fs = requireNative('fs'),
|
||||
fd = binding.stdoutFD;
|
||||
|
||||
if (binding.isStdoutBlocking()) {
|
||||
stdout = new fs.WriteStream(null, {fd: fd});
|
||||
} else {
|
||||
stdout = new net.Stream(fd);
|
||||
// FIXME Should probably have an option in net.Stream to create a stream from
|
||||
// an existing fd which is writable only. But for now we'll just add
|
||||
// this hack and set the `readable` member to false.
|
||||
// Test: ./node test/fixtures/echo.js < /etc/passwd
|
||||
stdout.readable = false;
|
||||
}
|
||||
|
||||
return stdout;
|
||||
});
|
||||
|
||||
var stdin;
|
||||
process.openStdin = function () {
|
||||
if (stdin) return stdin;
|
||||
|
||||
var binding = process.binding('stdio'),
|
||||
net = requireNative('net'),
|
||||
fs = requireNative('fs'),
|
||||
fd = binding.openStdin();
|
||||
|
||||
if (binding.isStdinBlocking()) {
|
||||
stdin = new fs.ReadStream(null, {fd: fd});
|
||||
} else {
|
||||
stdin = new net.Stream(fd);
|
||||
stdin.readable = true;
|
||||
}
|
||||
|
||||
stdin.resume();
|
||||
|
||||
return stdin;
|
||||
};
|
||||
|
||||
|
||||
// console object
|
||||
var formatRegExp = /%[sdj]/g;
|
||||
function format (f) {
|
||||
if (typeof f !== 'string') {
|
||||
var objects = [], sys = requireNative('sys');
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
objects.push(sys.inspect(arguments[i]));
|
||||
}
|
||||
return objects.join(' ');
|
||||
}
|
||||
|
||||
|
||||
var i = 1;
|
||||
var args = arguments;
|
||||
var str = String(f).replace(formatRegExp, function (x) {
|
||||
switch (x) {
|
||||
case '%s': return args[i++];
|
||||
case '%d': return +args[i++];
|
||||
case '%j': return JSON.stringify(args[i++]);
|
||||
default:
|
||||
return x;
|
||||
}
|
||||
});
|
||||
for (var len = args.length; i < len; ++i) {
|
||||
str += ' ' + args[i];
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
global.console = {};
|
||||
|
||||
global.console.log = function () {
|
||||
process.stdout.write(format.apply(this, arguments) + '\n');
|
||||
};
|
||||
|
||||
global.console.info = global.console.log;
|
||||
|
||||
global.console.warn = function () {
|
||||
writeError(format.apply(this, arguments) + '\n');
|
||||
};
|
||||
|
||||
global.console.error = global.console.warn;
|
||||
|
||||
global.console.dir = function(object){
|
||||
var sys = requireNative('sys');
|
||||
process.stdout.write(sys.inspect(object) + '\n');
|
||||
};
|
||||
|
||||
var times = {};
|
||||
global.console.time = function(label){
|
||||
times[label] = Date.now();
|
||||
};
|
||||
|
||||
global.console.timeEnd = function(label){
|
||||
var duration = Date.now() - times[label];
|
||||
global.console.log('%s: %dms', label, duration);
|
||||
};
|
||||
|
||||
global.console.trace = function(label){
|
||||
// TODO probably can to do this better with V8's debug object once that is
|
||||
// exposed.
|
||||
var err = new Error;
|
||||
err.name = 'Trace';
|
||||
err.message = label || '';
|
||||
Error.captureStackTrace(err, arguments.callee);
|
||||
console.error(err.stack);
|
||||
};
|
||||
|
||||
global.console.assert = function(expression){
|
||||
if(!expression){
|
||||
var arr = Array.prototype.slice.call(arguments, 1);
|
||||
process.assert(false, format.apply(this, arr));
|
||||
}
|
||||
}
|
||||
|
||||
global.Buffer = requireNative('buffer').Buffer;
|
||||
|
||||
process.exit = function (code) {
|
||||
process.emit("exit");
|
||||
process.reallyExit(code);
|
||||
};
|
||||
|
||||
|
||||
// Module System
|
||||
var module = (function () {
|
||||
@@ -70,7 +319,6 @@ var module = (function () {
|
||||
if (parseInt(process.env["NODE_MODULE_CONTEXTS"]) > 0) contextLoad = true;
|
||||
var Script;
|
||||
|
||||
var internalModuleCache = {};
|
||||
var extensionCache = {};
|
||||
|
||||
function Module (id, parent) {
|
||||
@@ -90,36 +338,6 @@ var module = (function () {
|
||||
this.children = [];
|
||||
};
|
||||
|
||||
function createInternalModule (id, constructor) {
|
||||
var m = new Module(id);
|
||||
constructor(m.exports);
|
||||
m.loaded = true;
|
||||
internalModuleCache[id] = m;
|
||||
return m;
|
||||
};
|
||||
|
||||
|
||||
// This contains the source code for the files in lib/
|
||||
// Like, natives.fs is the contents of lib/fs.js
|
||||
var natives = process.binding('natives');
|
||||
|
||||
function loadNative (id) {
|
||||
var m = new Module(id);
|
||||
internalModuleCache[id] = m;
|
||||
var e = m._compile(natives[id], id);
|
||||
if (e) throw e;
|
||||
m.loaded = true;
|
||||
return m;
|
||||
}
|
||||
|
||||
exports.requireNative = requireNative;
|
||||
|
||||
function requireNative (id) {
|
||||
if (internalModuleCache[id]) return internalModuleCache[id].exports;
|
||||
if (!natives[id]) throw new Error('No such native module ' + id);
|
||||
return loadNative(id).exports;
|
||||
}
|
||||
|
||||
|
||||
// Modules
|
||||
|
||||
@@ -130,10 +348,7 @@ var module = (function () {
|
||||
}
|
||||
}
|
||||
|
||||
var pathFn = process.compile("(function (exports) {" + natives.path + "\n})",
|
||||
"path");
|
||||
var pathModule = createInternalModule('path', pathFn);
|
||||
var path = pathModule.exports;
|
||||
var path = requireNative("path");
|
||||
|
||||
var modulePaths = [path.join(process.execPath, "..", "..", "lib", "node")];
|
||||
|
||||
@@ -187,17 +402,6 @@ var module = (function () {
|
||||
return;
|
||||
}
|
||||
|
||||
/* if (dirs.length == 0) {
|
||||
if (callback) {
|
||||
callback();
|
||||
} else {
|
||||
return; // sync returns null
|
||||
}
|
||||
} //no need for this, eventually move simpler if to traverser
|
||||
// question: what with /absolute/id when dirs.length is 0?
|
||||
// if "load it anyway", then this ^^^ code is wrong, but omitting it
|
||||
// makes it right*/
|
||||
|
||||
var nextLoc = traverser(id, id.charAt(0) === '/' ? [''] : dirs);
|
||||
|
||||
var fs = requireNative('fs');
|
||||
@@ -256,14 +460,10 @@ var module = (function () {
|
||||
debug("loadModule REQUEST " + (request) + " parent: " + parent.id);
|
||||
|
||||
// native modules always take precedence.
|
||||
var cachedNative = internalModuleCache[id];
|
||||
if (cachedNative) {
|
||||
return callback ? callback(null, cachedNative.exports) : cachedNative.exports;
|
||||
}
|
||||
if (natives[id]) {
|
||||
debug('load native module ' + id);
|
||||
var nativeMod = loadNative(id);
|
||||
return callback ? callback(null, nativeMod.exports) : nativeMod.exports;
|
||||
if (nativeSource[id]) {
|
||||
//debug('load native module ' + id);
|
||||
var nativeMod = requireNative(id);
|
||||
return callback ? callback(null, nativeMod) : nativeMod;
|
||||
}
|
||||
|
||||
// look up the filename first, since that's the cache key.
|
||||
@@ -433,6 +633,7 @@ var module = (function () {
|
||||
sandbox.__filename = filename;
|
||||
sandbox.__dirname = dirname;
|
||||
sandbox.module = self;
|
||||
sandbox.global = sandbox;
|
||||
sandbox.root = root;
|
||||
|
||||
Script.runInNewContext(content, sandbox, filename);
|
||||
@@ -525,218 +726,8 @@ var module = (function () {
|
||||
})();
|
||||
|
||||
|
||||
// Load events module in order to access prototype elements on process like
|
||||
// process.addListener.
|
||||
var events = module.requireNative('events');
|
||||
|
||||
|
||||
// Signal Handlers
|
||||
(function() {
|
||||
var signalWatchers = {};
|
||||
addListener = process.addListener,
|
||||
removeListener = process.removeListener;
|
||||
|
||||
function isSignal (event) {
|
||||
return event.slice(0, 3) === 'SIG' && process.hasOwnProperty(event);
|
||||
};
|
||||
|
||||
// Wrap addListener for the special signal types
|
||||
process.on = process.addListener = function (type, listener) {
|
||||
var ret = addListener.apply(this, arguments);
|
||||
if (isSignal(type)) {
|
||||
if (!signalWatchers.hasOwnProperty(type)) {
|
||||
var b = process.binding('signal_watcher'),
|
||||
w = new b.SignalWatcher(process[type]);
|
||||
w.callback = function () {
|
||||
process.emit(type);
|
||||
}
|
||||
signalWatchers[type] = w;
|
||||
w.start();
|
||||
} else if (this.listeners(type).length === 1) {
|
||||
signalWatchers[event].start();
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
process.removeListener = function (type, listener) {
|
||||
var ret = removeListener.apply(this, arguments);
|
||||
if (isSignal(type)) {
|
||||
process.assert(signalWatchers.hasOwnProperty(type));
|
||||
|
||||
if (this.listeners(type).length === 0) {
|
||||
signalWatchers[type].stop();
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
})();
|
||||
|
||||
// Timers
|
||||
function addTimerListener (callback) {
|
||||
var timer = this;
|
||||
// Special case the no param case to avoid the extra object creation.
|
||||
if (arguments.length > 2) {
|
||||
var args = Array.prototype.slice.call(arguments, 2);
|
||||
timer.callback = function () { callback.apply(timer, args); };
|
||||
} else {
|
||||
timer.callback = callback;
|
||||
}
|
||||
}
|
||||
|
||||
global.setTimeout = function (callback, after) {
|
||||
var timer = new process.Timer();
|
||||
addTimerListener.apply(timer, arguments);
|
||||
timer.start(after, 0);
|
||||
return timer;
|
||||
};
|
||||
|
||||
global.setInterval = function (callback, repeat) {
|
||||
var timer = new process.Timer();
|
||||
addTimerListener.apply(timer, arguments);
|
||||
timer.start(repeat, repeat);
|
||||
return timer;
|
||||
};
|
||||
|
||||
global.clearTimeout = function (timer) {
|
||||
if (timer instanceof process.Timer) {
|
||||
timer.stop();
|
||||
}
|
||||
};
|
||||
|
||||
global.clearInterval = global.clearTimeout;
|
||||
|
||||
var stdout;
|
||||
process.__defineGetter__('stdout', function () {
|
||||
if (stdout) return stdout;
|
||||
|
||||
var binding = process.binding('stdio'),
|
||||
net = module.requireNative('net'),
|
||||
fs = module.requireNative('fs'),
|
||||
fd = binding.stdoutFD;
|
||||
|
||||
if (binding.isStdoutBlocking()) {
|
||||
stdout = new fs.WriteStream(null, {fd: fd});
|
||||
} else {
|
||||
stdout = new net.Stream(fd);
|
||||
// FIXME Should probably have an option in net.Stream to create a stream from
|
||||
// an existing fd which is writable only. But for now we'll just add
|
||||
// this hack and set the `readable` member to false.
|
||||
// Test: ./node test/fixtures/echo.js < /etc/passwd
|
||||
stdout.readable = false;
|
||||
}
|
||||
|
||||
return stdout;
|
||||
});
|
||||
|
||||
var stdin;
|
||||
process.openStdin = function () {
|
||||
if (stdin) return stdin;
|
||||
|
||||
var binding = process.binding('stdio'),
|
||||
net = module.requireNative('net'),
|
||||
fs = module.requireNative('fs'),
|
||||
fd = binding.openStdin();
|
||||
|
||||
if (binding.isStdinBlocking()) {
|
||||
stdin = new fs.ReadStream(null, {fd: fd});
|
||||
} else {
|
||||
stdin = new net.Stream(fd);
|
||||
stdin.readable = true;
|
||||
}
|
||||
|
||||
stdin.resume();
|
||||
|
||||
return stdin;
|
||||
};
|
||||
|
||||
|
||||
// console object
|
||||
var formatRegExp = /%[sdj]/g;
|
||||
function format (f) {
|
||||
if (typeof f !== 'string') {
|
||||
var objects = [], sys = module.requireNative('sys');
|
||||
for (var i = 0; i < arguments.length; i++) {
|
||||
objects.push(sys.inspect(arguments[i]));
|
||||
}
|
||||
return objects.join(' ');
|
||||
}
|
||||
|
||||
|
||||
var i = 1;
|
||||
var args = arguments;
|
||||
var str = String(f).replace(formatRegExp, function (x) {
|
||||
switch (x) {
|
||||
case '%s': return args[i++];
|
||||
case '%d': return +args[i++];
|
||||
case '%j': return JSON.stringify(args[i++]);
|
||||
default:
|
||||
return x;
|
||||
}
|
||||
});
|
||||
for (var len = args.length; i < len; ++i) {
|
||||
str += ' ' + args[i];
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
global.console = {};
|
||||
|
||||
global.console.log = function () {
|
||||
process.stdout.write(format.apply(this, arguments) + '\n');
|
||||
};
|
||||
|
||||
global.console.info = global.console.log;
|
||||
|
||||
global.console.warn = function () {
|
||||
writeError(format.apply(this, arguments) + '\n');
|
||||
};
|
||||
|
||||
global.console.error = global.console.warn;
|
||||
|
||||
global.console.dir = function(object){
|
||||
var sys = module.requireNative('sys');
|
||||
process.stdout.write(sys.inspect(object) + '\n');
|
||||
};
|
||||
|
||||
var times = {};
|
||||
global.console.time = function(label){
|
||||
times[label] = Date.now();
|
||||
};
|
||||
|
||||
global.console.timeEnd = function(label){
|
||||
var duration = Date.now() - times[label];
|
||||
global.console.log('%s: %dms', label, duration);
|
||||
};
|
||||
|
||||
global.console.trace = function(label){
|
||||
// TODO probably can to do this better with V8's debug object once that is
|
||||
// exposed.
|
||||
var err = new Error;
|
||||
err.name = 'Trace';
|
||||
err.message = label || '';
|
||||
Error.captureStackTrace(err, arguments.callee);
|
||||
console.error(err.stack);
|
||||
};
|
||||
|
||||
global.console.assert = function(expression){
|
||||
if(!expression){
|
||||
var arr = Array.prototype.slice.call(arguments, 1);
|
||||
process.assert(false, format.apply(this, arr));
|
||||
}
|
||||
}
|
||||
|
||||
global.Buffer = module.requireNative('buffer').Buffer;
|
||||
|
||||
process.exit = function (code) {
|
||||
process.emit("exit");
|
||||
process.reallyExit(code);
|
||||
};
|
||||
|
||||
var cwd = process.cwd();
|
||||
var path = module.requireNative('path');
|
||||
var path = requireNative('path');
|
||||
|
||||
// Make process.argv[0] and process.argv[1] into full paths.
|
||||
if (process.argv[0].indexOf('/') > 0) {
|
||||
@@ -748,12 +739,14 @@ if (process.argv[1]) {
|
||||
process.argv[1] = path.join(cwd, process.argv[1]);
|
||||
}
|
||||
|
||||
module.runMain();
|
||||
// REMOVEME: nextTick should not be necessary. This hack to get
|
||||
// test/simple/test-exception-handler2.js working.
|
||||
process.nextTick(function() {
|
||||
module.runMain();
|
||||
});
|
||||
} else {
|
||||
// No arguments, run the repl
|
||||
var repl = module.requireNative('repl');
|
||||
console.log("Type '.help' for options.");
|
||||
repl.start();
|
||||
requireNative('repl').start();
|
||||
}
|
||||
|
||||
// All our arguments are loaded. We've evaluated all of the scripts. We
|
||||
|
||||
@@ -156,6 +156,16 @@ Buffer* Buffer::New(size_t size) {
|
||||
Handle<Value> Buffer::New(const Arguments &args) {
|
||||
HandleScope scope;
|
||||
|
||||
if (!args.IsConstructCall()) {
|
||||
Local<Value> argv[10];
|
||||
for (int i = 0; i < MIN(args.Length(), 10); i++) {
|
||||
argv[i] = args[i];
|
||||
}
|
||||
Local<Object> instance =
|
||||
constructor_template->GetFunction()->NewInstance(args.Length(), argv);
|
||||
return scope.Close(instance);
|
||||
}
|
||||
|
||||
Buffer *buffer;
|
||||
if (args[0]->IsInt32()) {
|
||||
// var buffer = new Buffer(1024);
|
||||
@@ -701,6 +711,22 @@ Handle<Value> Buffer::ByteLength(const Arguments &args) {
|
||||
}
|
||||
|
||||
|
||||
Handle<Value> Buffer::MakeFastBuffer(const Arguments &args) {
|
||||
HandleScope scope;
|
||||
|
||||
Buffer *buffer = ObjectWrap::Unwrap<Buffer>(args[0]->ToObject());
|
||||
Local<Object> fast_buffer = args[1]->ToObject();;
|
||||
uint32_t offset = args[2]->Uint32Value();
|
||||
uint32_t length = args[3]->Uint32Value();
|
||||
|
||||
fast_buffer->SetIndexedPropertiesToPixelData((uint8_t*)buffer->data() + offset,
|
||||
length);
|
||||
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Buffer::Initialize(Handle<Object> target) {
|
||||
HandleScope scope;
|
||||
|
||||
@@ -731,6 +757,9 @@ void Buffer::Initialize(Handle<Object> target) {
|
||||
NODE_SET_METHOD(constructor_template->GetFunction(),
|
||||
"byteLength",
|
||||
Buffer::ByteLength);
|
||||
NODE_SET_METHOD(constructor_template->GetFunction(),
|
||||
"makeFastBuffer",
|
||||
Buffer::MakeFastBuffer);
|
||||
|
||||
target->Set(String::NewSymbol("Buffer"), constructor_template->GetFunction());
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ class Buffer : public ObjectWrap {
|
||||
static v8::Handle<v8::Value> AsciiWrite(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> Utf8Write(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> ByteLength(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> MakeFastBuffer(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> Unpack(const v8::Arguments &args);
|
||||
static v8::Handle<v8::Value> Copy(const v8::Arguments &args);
|
||||
|
||||
|
||||
@@ -286,8 +286,7 @@ int ChildProcess::Spawn(const char *file,
|
||||
close(stdin_pipe[0]);
|
||||
stdio_fds[0] = stdin_pipe[1];
|
||||
SetNonBlocking(stdin_pipe[1]);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
stdio_fds[0] = custom_fds[0];
|
||||
}
|
||||
|
||||
@@ -295,8 +294,7 @@ int ChildProcess::Spawn(const char *file,
|
||||
close(stdout_pipe[1]);
|
||||
stdio_fds[1] = stdout_pipe[0];
|
||||
SetNonBlocking(stdout_pipe[0]);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
stdio_fds[1] = custom_fds[1];
|
||||
}
|
||||
|
||||
@@ -304,8 +302,7 @@ int ChildProcess::Spawn(const char *file,
|
||||
close(stderr_pipe[1]);
|
||||
stdio_fds[2] = stderr_pipe[0];
|
||||
SetNonBlocking(stderr_pipe[0]);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
stdio_fds[2] = custom_fds[2];
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ static Persistent<String> subject_symbol;
|
||||
static Persistent<String> issuer_symbol;
|
||||
static Persistent<String> valid_from_symbol;
|
||||
static Persistent<String> valid_to_symbol;
|
||||
static Persistent<String> fingerprint_symbol;
|
||||
static Persistent<String> name_symbol;
|
||||
static Persistent<String> version_symbol;
|
||||
|
||||
@@ -540,6 +541,28 @@ Handle<Value> SecureStream::GetPeerCertificate(const Arguments& args) {
|
||||
BIO_free(bio);
|
||||
info->Set(valid_to_symbol, String::New(buf));
|
||||
|
||||
unsigned int md_size, i;
|
||||
unsigned char md[EVP_MAX_MD_SIZE];
|
||||
if (X509_digest(peer_cert, EVP_sha1(), md, &md_size)) {
|
||||
const char hex[] = "0123456789ABCDEF";
|
||||
char fingerprint[EVP_MAX_MD_SIZE * 3];
|
||||
|
||||
for (i=0; i<md_size; i++) {
|
||||
fingerprint[3*i] = hex[(md[i] & 0xf0) >> 4];
|
||||
fingerprint[(3*i)+1] = hex[(md[i] & 0x0f)];
|
||||
fingerprint[(3*i)+2] = ':';
|
||||
}
|
||||
|
||||
if (md_size > 0) {
|
||||
fingerprint[(3*(md_size-1))+2] = '\0';
|
||||
}
|
||||
else {
|
||||
fingerprint[0] = '\0';
|
||||
}
|
||||
|
||||
info->Set(fingerprint_symbol, String::New(fingerprint));
|
||||
}
|
||||
|
||||
X509_free(peer_cert);
|
||||
}
|
||||
return scope.Close(info);
|
||||
@@ -2296,6 +2319,7 @@ void InitCrypto(Handle<Object> target) {
|
||||
issuer_symbol = NODE_PSYMBOL("issuer");
|
||||
valid_from_symbol = NODE_PSYMBOL("valid_from");
|
||||
valid_to_symbol = NODE_PSYMBOL("valid_to");
|
||||
fingerprint_symbol = NODE_PSYMBOL("fingerprint");
|
||||
name_symbol = NODE_PSYMBOL("name");
|
||||
version_symbol = NODE_PSYMBOL("version");
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ class ObjectWrap {
|
||||
refs_ = 0;
|
||||
}
|
||||
|
||||
|
||||
virtual ~ObjectWrap ( ) {
|
||||
if (!handle_.IsEmpty()) {
|
||||
assert(handle_.IsNearDeath());
|
||||
@@ -21,29 +22,28 @@ class ObjectWrap {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
static inline T* Unwrap (v8::Handle<v8::Object> handle)
|
||||
{
|
||||
static inline T* Unwrap (v8::Handle<v8::Object> handle) {
|
||||
assert(!handle.IsEmpty());
|
||||
assert(handle->InternalFieldCount() > 0);
|
||||
return static_cast<T*>(v8::Handle<v8::External>::Cast(
|
||||
handle->GetInternalField(0))->Value());
|
||||
return static_cast<T*>(handle->GetPointerFromInternalField(0));
|
||||
}
|
||||
|
||||
|
||||
v8::Persistent<v8::Object> handle_; // ro
|
||||
|
||||
protected:
|
||||
inline void Wrap (v8::Handle<v8::Object> handle)
|
||||
{
|
||||
inline void Wrap (v8::Handle<v8::Object> handle) {
|
||||
assert(handle_.IsEmpty());
|
||||
assert(handle->InternalFieldCount() > 0);
|
||||
handle_ = v8::Persistent<v8::Object>::New(handle);
|
||||
handle_->SetInternalField(0, v8::External::New(this));
|
||||
handle_->SetPointerInInternalField(0, this);
|
||||
MakeWeak();
|
||||
}
|
||||
|
||||
inline void MakeWeak (void)
|
||||
{
|
||||
|
||||
inline void MakeWeak (void) {
|
||||
handle_.MakeWeak(this, WeakCallback);
|
||||
}
|
||||
|
||||
@@ -73,11 +73,12 @@ class ObjectWrap {
|
||||
if (--refs_ == 0) { MakeWeak(); }
|
||||
}
|
||||
|
||||
|
||||
int refs_; // ro
|
||||
|
||||
|
||||
private:
|
||||
static void WeakCallback (v8::Persistent<v8::Value> value, void *data)
|
||||
{
|
||||
static void WeakCallback (v8::Persistent<v8::Value> value, void *data) {
|
||||
ObjectWrap *obj = static_cast<ObjectWrap*>(data);
|
||||
assert(value == obj->handle_);
|
||||
assert(!obj->refs_);
|
||||
|
||||
@@ -212,6 +212,7 @@ template <node::Script::EvalInputFlags iFlag,
|
||||
for (i = 0; i < keys->Length(); i++) {
|
||||
Handle<String> key = keys->Get(Integer::New(i))->ToString();
|
||||
Handle<Value> value = sandbox->Get(key);
|
||||
if (value == sandbox) { value = context->Global(); }
|
||||
context->Global()->Set(key, value);
|
||||
}
|
||||
}
|
||||
@@ -264,6 +265,7 @@ template <node::Script::EvalInputFlags iFlag,
|
||||
for (i = 0; i < keys->Length(); i++) {
|
||||
Handle<String> key = keys->Get(Integer::New(i))->ToString();
|
||||
Handle<Value> value = context->Global()->Get(key);
|
||||
if (value == context->Global()) { value = sandbox; }
|
||||
sandbox->Set(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#define NODE_MAJOR_VERSION 0
|
||||
#define NODE_MINOR_VERSION 2
|
||||
#define NODE_PATCH_VERSION 0
|
||||
#define NODE_PATCH_VERSION 2
|
||||
|
||||
#ifndef NODE_STRINGIFY
|
||||
#define NODE_STRINGIFY(n) NODE_STRINGIFY_HELPER(n)
|
||||
|
||||
@@ -3,6 +3,7 @@ var path = require("path");
|
||||
exports.testDir = path.dirname(__filename);
|
||||
exports.fixturesDir = path.join(exports.testDir, "fixtures");
|
||||
exports.libDir = path.join(exports.testDir, "../lib");
|
||||
exports.tmpDir = path.join(exports.testDir, "tmp");
|
||||
exports.PORT = 12346;
|
||||
|
||||
exports.assert = require('assert');
|
||||
|
||||
@@ -12,7 +12,12 @@ var client = net.createConnection(443, "www.microsoft.com");
|
||||
var caPem = fs.readFileSync(common.fixturesDir+"/msca.pem");
|
||||
//var caPem = fs.readFileSync("ca.pem");
|
||||
|
||||
var credentials = crypto.createCredentials({ca:caPem});
|
||||
try{
|
||||
var credentials = crypto.createCredentials({ca:caPem});
|
||||
} catch (e) {
|
||||
console.log("Not compiled with OPENSSL support.");
|
||||
process.exit();
|
||||
}
|
||||
|
||||
client.setEncoding("UTF8");
|
||||
client.addListener("connect", function () {
|
||||
|
||||
@@ -9,7 +9,12 @@ var crypto=require('crypto');
|
||||
var keyPem = fs.readFileSync(common.fixturesDir + "/cert.pem");
|
||||
var certPem = fs.readFileSync(common.fixturesDir + "/cert.pem");
|
||||
|
||||
var credentials = crypto.createCredentials({key:keyPem, cert:certPem});
|
||||
try{
|
||||
var credentials = crypto.createCredentials({key:keyPem, cert:certPem});
|
||||
} catch (e) {
|
||||
console.log("Not compiled with OPENSSL support.");
|
||||
process.exit();
|
||||
}
|
||||
var i = 0;
|
||||
var server = net.createServer(function (connection) {
|
||||
connection.setSecure(credentials);
|
||||
|
||||
4
test/fixtures/global/plain.js
vendored
4
test/fixtures/global/plain.js
vendored
@@ -1,6 +1,4 @@
|
||||
foo = "foo";
|
||||
global.bar = "bar";
|
||||
|
||||
exports.fooBar = function () {
|
||||
return {foo: global.foo, bar: bar};
|
||||
};
|
||||
exports.fooBar = {foo: global.foo, bar:bar};
|
||||
13
test/fixtures/global/sub1.js
vendored
13
test/fixtures/global/sub1.js
vendored
@@ -1,13 +0,0 @@
|
||||
foo1 = "foo1";
|
||||
global.bar1 = "bar1";
|
||||
|
||||
var sub2 = require('./sub2');
|
||||
|
||||
|
||||
exports.subGlobalKeys = function () {
|
||||
return sub2.globalKeys();
|
||||
};
|
||||
|
||||
exports.subAllFooBars = function () {
|
||||
return sub2.allFooBars();
|
||||
};
|
||||
18
test/fixtures/global/sub2.js
vendored
18
test/fixtures/global/sub2.js
vendored
@@ -1,18 +0,0 @@
|
||||
foo2 = "foo2";
|
||||
global.bar2 = "bar2";
|
||||
|
||||
|
||||
exports.globalKeys = function () {
|
||||
return Object.getOwnPropertyNames(global);
|
||||
};
|
||||
|
||||
exports.allFooBars = function () {
|
||||
return {
|
||||
foo0: global.foo0,
|
||||
bar0: bar0,
|
||||
foo1: global.foo1,
|
||||
bar1: bar1,
|
||||
foo2: global.foo2,
|
||||
bar2: bar2
|
||||
};
|
||||
};
|
||||
1
test/fixtures/semicolon.js
vendored
Normal file
1
test/fixtures/semicolon.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
;
|
||||
@@ -1,9 +1,8 @@
|
||||
before
|
||||
|
||||
|
||||
*.js:*
|
||||
*cript.runIn*Context(*);
|
||||
*^
|
||||
node.js:*
|
||||
throw e;
|
||||
^
|
||||
ReferenceError: foo is not defined
|
||||
at evalmachine.<anonymous>:*
|
||||
at *test/message/undefined_reference_in_new_context.js:*
|
||||
@@ -11,4 +10,6 @@ ReferenceError: foo is not defined
|
||||
at Module._loadScriptSync (node.js:*)
|
||||
at Module.loadSync (node.js:*)
|
||||
at Object.runMain (node.js:*)
|
||||
at Array.<anonymous> (node.js:*)
|
||||
at EventEmitter._tickCallback (node.js:*)
|
||||
at node.js:*
|
||||
|
||||
@@ -74,7 +74,14 @@ setInterval(function(param1, param2){
|
||||
clearInterval(this);
|
||||
}, 1000, "param1", "param2");
|
||||
|
||||
// setInterval(cb, 0) should be called multiple times.
|
||||
count4 = 0;
|
||||
interval4 = setInterval(function () {
|
||||
if (++count4 > 10) clearInterval(interval4);
|
||||
}, 0);
|
||||
|
||||
process.addListener("exit", function () {
|
||||
assert.equal(true, setTimeout_called);
|
||||
assert.equal(3, interval_count);
|
||||
assert.equal(11, count4);
|
||||
});
|
||||
|
||||
@@ -4,7 +4,7 @@ assert = require("assert");
|
||||
|
||||
var Buffer = require('buffer').Buffer;
|
||||
|
||||
var b = new Buffer(1024);
|
||||
var b = Buffer(1024); // safe constructor
|
||||
|
||||
console.log("b.length == " + b.length);
|
||||
assert.strictEqual(1024, b.length);
|
||||
|
||||
17
test/simple/test-console.js
Normal file
17
test/simple/test-console.js
Normal file
@@ -0,0 +1,17 @@
|
||||
common = require("../common");
|
||||
assert = common.assert;
|
||||
|
||||
var stdout_write = global.process.stdout.write;
|
||||
var strings = [];
|
||||
global.process.stdout.write = function(string) {
|
||||
strings.push(string);
|
||||
};
|
||||
|
||||
console.log('foo');
|
||||
console.log('foo', 'bar');
|
||||
console.log('%s %s', 'foo', 'bar', 'hop');
|
||||
|
||||
global.process.stdout.write = stdout_write;
|
||||
assert.equal('foo\n', strings.shift());
|
||||
assert.equal('foo bar\n', strings.shift());
|
||||
assert.equal('foo bar hop\n', strings.shift());
|
||||
@@ -17,7 +17,12 @@ var caPem = fs.readFileSync(common.fixturesDir+"/test_ca.pem", 'ascii');
|
||||
var certPem = fs.readFileSync(common.fixturesDir+"/test_cert.pem", 'ascii');
|
||||
var keyPem = fs.readFileSync(common.fixturesDir+"/test_key.pem", 'ascii');
|
||||
|
||||
var credentials = crypto.createCredentials({key:keyPem, cert:certPem, ca:caPem});
|
||||
try{
|
||||
var credentials = crypto.createCredentials({key:keyPem, cert:certPem, ca:caPem});
|
||||
} catch (e) {
|
||||
console.log("Not compiled with OPENSSL support.");
|
||||
process.exit();
|
||||
}
|
||||
|
||||
// Test HMAC
|
||||
//var h1 = (new crypto.Hmac).init("sha1", "Node").update("some data").update("to hmac").digest("hex");
|
||||
|
||||
@@ -1,56 +1,48 @@
|
||||
common = require("../common");
|
||||
assert = common.assert
|
||||
|
||||
var Buffer = require("buffer").Buffer,
|
||||
fs = require("fs"),
|
||||
dgram = require("dgram"), server, client,
|
||||
server_path = "/tmp/dgram_server_sock",
|
||||
client_path = "/tmp/dgram_client_sock",
|
||||
message_to_send = new Buffer("A message to send"),
|
||||
timer;
|
||||
fs = require("fs");
|
||||
dgram = require("dgram");
|
||||
|
||||
serverPath = "/tmp/dgram_server_sock";
|
||||
clientPath = "/tmp/dgram_client_sock";
|
||||
msgToSend = new Buffer("A message to send");
|
||||
|
||||
server = dgram.createSocket("unix_dgram");
|
||||
server.on("message", function (msg, rinfo) {
|
||||
console.log("server got: " + msg + " from " + rinfo.address);
|
||||
assert.strictEqual(rinfo.address, client_path);
|
||||
assert.strictEqual(msg.toString(), message_to_send.toString());
|
||||
assert.strictEqual(rinfo.address, clientPath);
|
||||
assert.strictEqual(msg.toString(), msgToSend.toString());
|
||||
server.send(msg, 0, msg.length, rinfo.address);
|
||||
});
|
||||
|
||||
server.on("listening", function () {
|
||||
console.log("server is listening");
|
||||
|
||||
client = dgram.createSocket("unix_dgram");
|
||||
|
||||
client.on("message", function (msg, rinfo) {
|
||||
console.log("client got: " + msg + " from " + rinfo.address);
|
||||
assert.strictEqual(rinfo.address, server_path);
|
||||
assert.strictEqual(msg.toString(), message_to_send.toString());
|
||||
assert.strictEqual(rinfo.address, serverPath);
|
||||
assert.strictEqual(msg.toString(), msgToSend.toString());
|
||||
client.close();
|
||||
server.close();
|
||||
});
|
||||
|
||||
client.on("listening", function () {
|
||||
console.log("client is listening");
|
||||
client.send(message_to_send, 0, message_to_send.length, server_path, function (err, bytes) {
|
||||
client.send(msgToSend, 0, msgToSend.length, serverPath, function (err, bytes) {
|
||||
if (err) {
|
||||
console.log("Caught error in client send.");
|
||||
throw err;
|
||||
}
|
||||
console.log("client wrote " + bytes + " bytes.");
|
||||
assert.strictEqual(bytes, message_to_send.length);
|
||||
assert.strictEqual(bytes, msgToSend.length);
|
||||
});
|
||||
});
|
||||
client.on("close", function () {
|
||||
if (server.fd === null) {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
});
|
||||
client.bind(client_path);
|
||||
});
|
||||
server.on("close", function () {
|
||||
if (client.fd === null) {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
});
|
||||
server.bind(server_path);
|
||||
|
||||
timer = setTimeout(function () {
|
||||
throw new Error("Timeout");
|
||||
}, 200);
|
||||
|
||||
client.bind(clientPath);
|
||||
});
|
||||
|
||||
server.bind(serverPath);
|
||||
|
||||
21
test/simple/test-exception-handler2.js
Normal file
21
test/simple/test-exception-handler2.js
Normal file
@@ -0,0 +1,21 @@
|
||||
common = require("../common");
|
||||
assert = common.assert
|
||||
|
||||
process.on('uncaughtException', function (err) {
|
||||
console.log('Caught exception: ' + err);
|
||||
});
|
||||
|
||||
var timeoutFired = false;
|
||||
setTimeout(function () {
|
||||
console.log('This will still run.');
|
||||
timeoutFired = true;
|
||||
}, 500);
|
||||
|
||||
process.on('exit', function() {
|
||||
assert.ok(timeoutFired);
|
||||
});
|
||||
|
||||
// Intentionally cause an exception, but don't catch it.
|
||||
nonexistentFunc();
|
||||
console.log('This will not run.');
|
||||
|
||||
@@ -15,7 +15,7 @@ callbacks = { open: 0, end: 0, close: 0, destroy: 0 };
|
||||
|
||||
paused = false;
|
||||
|
||||
file = fs.createReadStream(fn);
|
||||
file = fs.ReadStream(fn);
|
||||
|
||||
file.addListener('open', function(fd) {
|
||||
file.length = 0;
|
||||
@@ -96,3 +96,17 @@ file4.addListener('data', function(data) {
|
||||
file4.addListener('end', function(data) {
|
||||
assert.equal(contentRead, 'yz');
|
||||
});
|
||||
|
||||
try {
|
||||
fs.createReadStream(rangeFile, {start: 10, end: 2});
|
||||
assert.fail('Creating a ReadStream with incorrect range limits must throw.');
|
||||
} catch(e) {
|
||||
assert.equal(e.message, 'start must be <= end');
|
||||
}
|
||||
|
||||
try {
|
||||
fs.createReadStream(rangeFile, {start: 2});
|
||||
assert.fail('Creating a ReadStream with a only one range limits must throw.');
|
||||
} catch(e) {
|
||||
assert.equal(e.message, 'Both start and end are needed for range streaming.');
|
||||
}
|
||||
|
||||
@@ -9,3 +9,7 @@ var
|
||||
fs.readFile(fn, function(err, data) {
|
||||
assert.ok(data);
|
||||
});
|
||||
|
||||
fs.readFile(fn, 'utf8', function(err, data) {
|
||||
assert.strictEqual('', data);
|
||||
});
|
||||
@@ -2,16 +2,16 @@ common = require("../common");
|
||||
assert = common.assert
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var exec = require('child_process').exec;
|
||||
var async_completed = 0, async_expected = 0, unlink = [];
|
||||
|
||||
function asynctest(testBlock, args, callback, assertBlock) {
|
||||
async_expected++;
|
||||
testBlock.apply(testBlock, args.concat([function(err){
|
||||
testBlock.apply(testBlock, args.concat(function(err){
|
||||
var ignoreError = false;
|
||||
if (assertBlock) {
|
||||
try {
|
||||
ignoreError = assertBlock.apply(assertBlock,
|
||||
Array.prototype.slice.call(arguments));
|
||||
ignoreError = assertBlock.apply(assertBlock, arguments);
|
||||
}
|
||||
catch (e) {
|
||||
err = e;
|
||||
@@ -19,11 +19,11 @@ function asynctest(testBlock, args, callback, assertBlock) {
|
||||
}
|
||||
async_completed++;
|
||||
callback(ignoreError ? null : err);
|
||||
}]));
|
||||
}));
|
||||
}
|
||||
|
||||
function bashRealpath(path, callback) {
|
||||
common.exec("cd '"+path.replace("'","\\'")+"' && pwd -P",function
|
||||
exec("cd '"+path.replace("'","\\'")+"' && pwd -P",function
|
||||
(err, o) {
|
||||
callback(err, o.trim());
|
||||
});
|
||||
@@ -227,6 +227,69 @@ function test_non_symlinks(callback) {
|
||||
});
|
||||
}
|
||||
|
||||
var upone = path.join(process.cwd(), "..");
|
||||
function test_escape_cwd (cb) {
|
||||
asynctest(fs.realpath, [".."], cb, function(er, uponeActual){
|
||||
assert.equal(upone, uponeActual,
|
||||
"realpath('..') expected: "+upone+" actual:"+uponeActual);
|
||||
})
|
||||
}
|
||||
var uponeActual = fs.realpathSync("..");
|
||||
assert.equal(upone, uponeActual,
|
||||
"realpathSync('..') expected: "+upone+" actual:"+uponeActual);
|
||||
|
||||
// absolute symlinks with children.
|
||||
// .
|
||||
// `-- a/
|
||||
// |-- b/
|
||||
// | `-- c/
|
||||
// | `-- x.txt
|
||||
// `-- link -> /tmp/node-test-realpath-abs-kids/a/b/
|
||||
// realpath(root+'/a/link/c/x.txt') ==> root+'/a/b/c/x.txt'
|
||||
function test_abs_with_kids (cb) {
|
||||
bashRealpath(common.fixturesDir, function(err, fixturesAbsDir) {
|
||||
var root = fixturesAbsDir+'/node-test-realpath-abs-kids';
|
||||
function cleanup () {
|
||||
;['/a/b/c/x.txt'
|
||||
, '/a/link'
|
||||
].forEach(function (file) {
|
||||
try {fs.unlinkSync(root+file)} catch (ex) {}
|
||||
});
|
||||
;['/a/b/c'
|
||||
, '/a/b'
|
||||
, '/a'
|
||||
, ''
|
||||
].forEach(function (folder) {
|
||||
try {fs.rmdirSync(root+folder)} catch (ex) {}
|
||||
});
|
||||
}
|
||||
function setup () {
|
||||
cleanup()
|
||||
;[''
|
||||
, '/a'
|
||||
, '/a/b'
|
||||
, '/a/b/c'
|
||||
].forEach(function (folder) {
|
||||
console.log("mkdir "+root+folder)
|
||||
fs.mkdirSync(root+folder, 0700);
|
||||
});
|
||||
fs.writeFileSync(root+'/a/b/c/x.txt', 'foo');
|
||||
fs.symlinkSync(root+'/a/b', root+'/a/link');
|
||||
}
|
||||
setup();
|
||||
var linkPath = root+'/a/link/c/x.txt';
|
||||
var expectPath = root+'/a/b/c/x.txt';
|
||||
var actual = fs.realpathSync(linkPath);
|
||||
// console.log({link:linkPath,expect:expectPath,actual:actual},'sync');
|
||||
assert.equal(actual, expectPath);
|
||||
asynctest(fs.realpath, [linkPath], cb, function (er, actual) {
|
||||
// console.log({link:linkPath,expect:expectPath,actual:actual},'async');
|
||||
assert.equal(actual, expectPath);
|
||||
cleanup();
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
var tests = [
|
||||
@@ -238,6 +301,8 @@ var tests = [
|
||||
test_relative_input_cwd,
|
||||
test_deep_symlink_mix,
|
||||
test_non_symlinks,
|
||||
test_escape_cwd,
|
||||
test_abs_with_kids
|
||||
];
|
||||
var numtests = tests.length;
|
||||
function runNextTest(err) {
|
||||
@@ -248,6 +313,15 @@ function runNextTest(err) {
|
||||
}
|
||||
runNextTest();
|
||||
|
||||
|
||||
assert.equal('/', fs.realpathSync('/'));
|
||||
fs.realpath('/', function (err, result) {
|
||||
assert.equal(null, err);
|
||||
assert.equal('/', result);
|
||||
});
|
||||
|
||||
|
||||
|
||||
process.addListener("exit", function () {
|
||||
unlink.forEach(function(path){ try {fs.unlinkSync(path);}catch(e){} });
|
||||
assert.equal(async_completed, async_expected);
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
common = require("../common");
|
||||
assert = common.assert
|
||||
var assert = common.assert;
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var completed = 0;
|
||||
|
||||
// test creating and reading symbolic link
|
||||
var linkData = "../../cycles/root.js";
|
||||
var linkPath = path.join(common.fixturesDir, "nested-index", 'one', 'symlink1.js');
|
||||
try {fs.unlinkSync(linkPath);}catch(e){}
|
||||
var linkData = path.join(common.fixturesDir, "/cycles/root.js");
|
||||
var linkPath = path.join(common.tmpDir, 'symlink1.js');
|
||||
fs.symlink(linkData, linkPath, function(err){
|
||||
if (err) throw err;
|
||||
console.log('symlink done');
|
||||
@@ -21,8 +20,7 @@ fs.symlink(linkData, linkPath, function(err){
|
||||
|
||||
// test creating and reading hard link
|
||||
var srcPath = path.join(common.fixturesDir, "cycles", 'root.js');
|
||||
var dstPath = path.join(common.fixturesDir, "nested-index", 'one', 'link1.js');
|
||||
try {fs.unlinkSync(dstPath);}catch(e){}
|
||||
var dstPath = path.join(common.tmpDir, 'link1.js');
|
||||
fs.link(srcPath, dstPath, function(err){
|
||||
if (err) throw err;
|
||||
console.log('hard link done');
|
||||
@@ -33,8 +31,6 @@ fs.link(srcPath, dstPath, function(err){
|
||||
});
|
||||
|
||||
process.addListener("exit", function () {
|
||||
try {fs.unlinkSync(linkPath);}catch(e){}
|
||||
try {fs.unlinkSync(dstPath);}catch(e){}
|
||||
assert.equal(completed, 2);
|
||||
});
|
||||
|
||||
|
||||
28
test/simple/test-fs-write-stream.js
Normal file
28
test/simple/test-fs-write-stream.js
Normal file
@@ -0,0 +1,28 @@
|
||||
common = require("../common");
|
||||
assert = common.assert
|
||||
|
||||
var path = require('path'),
|
||||
fs = require('fs');
|
||||
|
||||
var file = path.join(common.fixturesDir, "write.txt");
|
||||
|
||||
(function() {
|
||||
var stream = fs.WriteStream(file),
|
||||
_fs_close = fs.close;
|
||||
|
||||
fs.close = function(fd) {
|
||||
assert.ok(fd, "fs.close must not be called without an undefined fd.")
|
||||
fs.close = _fs_close;
|
||||
}
|
||||
stream.destroy();
|
||||
})();
|
||||
|
||||
(function() {
|
||||
var stream = fs.createWriteStream(file);
|
||||
|
||||
stream.addListener('drain', function () {
|
||||
assert.fail('"drain" event must not be emitted before stream.write() has been called at least once.')
|
||||
});
|
||||
stream.destroy();
|
||||
})();
|
||||
|
||||
@@ -11,7 +11,7 @@ fs.open(fn, 'w', 0644, function (err, fd) {
|
||||
if (err) throw err;
|
||||
console.log('open done');
|
||||
fs.write(fd, '', 0, 'utf8', function(err, written) {
|
||||
assert.fail('zero length write should not go through to callback');
|
||||
assert.equal(0, written);
|
||||
});
|
||||
fs.write(fd, expected, 0, "utf8", function (err, written) {
|
||||
console.log('write done');
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
common = require("../common");
|
||||
assert = common.assert
|
||||
|
||||
foo0 = "foo0";
|
||||
global.bar0 = "bar0";
|
||||
|
||||
var module = require("../fixtures/global/sub1"),
|
||||
keys = module.subGlobalKeys();
|
||||
|
||||
var fooBarKeys = keys.filter(
|
||||
function (x) { return x.match(/^foo/) || x.match(/^bar/); }
|
||||
);
|
||||
fooBarKeys.sort();
|
||||
assert.equal("bar0,bar1,bar2,foo0,foo1,foo2", fooBarKeys.join(), "global keys not as expected: "+JSON.stringify(keys));
|
||||
|
||||
var fooBars = module.subAllFooBars();
|
||||
|
||||
assert.equal("foo0", fooBars.foo0, "x from base level not visible in deeper levels.");
|
||||
assert.equal("bar0", fooBars.bar0, "global.x from base level not visible in deeper levels.");
|
||||
assert.equal("foo1", fooBars.foo1, "x from medium level not visible in deeper levels.");
|
||||
assert.equal("bar1", fooBars.bar1, "global.x from medium level not visible in deeper levels.");
|
||||
32
test/simple/test-global-leak.js
Normal file
32
test/simple/test-global-leak.js
Normal file
@@ -0,0 +1,32 @@
|
||||
var assert = require('assert');
|
||||
|
||||
var knownGlobals = [ setTimeout
|
||||
, setInterval
|
||||
, clearTimeout
|
||||
, clearInterval
|
||||
, console
|
||||
, Buffer
|
||||
, process
|
||||
, global
|
||||
, __module
|
||||
, include
|
||||
, puts
|
||||
, print
|
||||
, p
|
||||
];
|
||||
|
||||
for (var x in global) {
|
||||
var found = false;
|
||||
|
||||
for (var y in knownGlobals) {
|
||||
if (global[x] === knownGlobals[y]) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
console.error("Unknown global: %s", x);
|
||||
assert.ok(false);
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ assert.equal("foo", global.baseFoo, "x -> global.x in base level not working");
|
||||
assert.equal("bar", baseBar, "global.x -> x in base level not working");
|
||||
|
||||
var module = require("../fixtures/global/plain"),
|
||||
fooBar = module.fooBar();
|
||||
fooBar = module.fooBar;
|
||||
|
||||
assert.equal("foo", fooBar.foo, "x -> global.x in sub level not working");
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ var buffer = new Buffer(1024);
|
||||
|
||||
var request = "GET /hello HTTP/1.1\r\n\r\n";
|
||||
|
||||
buffer.asciiWrite(request, 0, request.length);
|
||||
buffer.write(request, 0, 'ascii');
|
||||
|
||||
var callbacks = 0;
|
||||
|
||||
@@ -39,7 +39,7 @@ parser.onURL = function (b, off, len) {
|
||||
|
||||
parser.onPath = function (b, off, length) {
|
||||
console.log("path [" + off + ", " + length + "]");
|
||||
var path = b.asciiSlice(off, off+length);
|
||||
var path = b.toString('ascii', off, off+length);
|
||||
console.log("path = '" + path + "'");
|
||||
assert.equal('/hello', path);
|
||||
callbacks++;
|
||||
|
||||
@@ -27,7 +27,13 @@ var caPem = fs.readFileSync(common.fixturesDir+"/test_ca.pem", 'ascii');
|
||||
var certPem = fs.readFileSync(common.fixturesDir+"/test_cert.pem", 'ascii');
|
||||
var keyPem = fs.readFileSync(common.fixturesDir+"/test_key.pem", 'ascii');
|
||||
|
||||
var credentials = crypto.createCredentials({key:keyPem, cert:certPem, ca:caPem});
|
||||
try{
|
||||
var credentials = crypto.createCredentials({key:keyPem, cert:certPem, ca:caPem});
|
||||
} catch (e) {
|
||||
console.log("Not compiled with OPENSSL support.");
|
||||
process.exit();
|
||||
}
|
||||
|
||||
|
||||
var https_server = http.createServer(function (req, res) {
|
||||
res.id = request_number;
|
||||
@@ -41,7 +47,8 @@ var https_server = http.createServer(function (req, res) {
|
||||
+ '"issuer":"/C=UK/ST=Acknack Ltd/L=Rhys Jones/O=node.js'
|
||||
+ '/OU=Test TLS Certificate/CN=localhost","valid_from":'
|
||||
+ '"Nov 11 09:52:22 2009 GMT","valid_to":'
|
||||
+ '"Nov 6 09:52:22 2029 GMT"}');
|
||||
+ '"Nov 6 09:52:22 2029 GMT",'
|
||||
+ '"fingerprint":"2A:7A:C2:DD:E5:F9:CC:53:72:35:99:7A:02:5A:71:38:52:EC:8A:DF"}');
|
||||
|
||||
if (req.id == 0) {
|
||||
assert.equal("GET", req.method);
|
||||
@@ -92,7 +99,8 @@ https_server.addListener("listening", function() {
|
||||
+ '"issuer":"/C=UK/ST=Acknack Ltd/L=Rhys Jones/O=node.js'
|
||||
+ '/OU=Test TLS Certificate/CN=localhost","valid_from":'
|
||||
+ '"Nov 11 09:52:22 2009 GMT","valid_to":'
|
||||
+ '"Nov 6 09:52:22 2029 GMT"}');
|
||||
+ '"Nov 6 09:52:22 2029 GMT",'
|
||||
+ '"fingerprint":"2A:7A:C2:DD:E5:F9:CC:53:72:35:99:7A:02:5A:71:38:52:EC:8A:DF"}');
|
||||
c.write( "GET /hello?hello=world&foo=b==ar HTTP/1.1\r\n\r\n" );
|
||||
requests_sent += 1;
|
||||
});
|
||||
|
||||
@@ -12,7 +12,7 @@ var responses_recvd = 0;
|
||||
var body0 = "";
|
||||
var body1 = "";
|
||||
|
||||
var server = http.createServer(function (req, res) {
|
||||
var server = http.Server(function (req, res) {
|
||||
if (responses_sent == 0) {
|
||||
assert.equal("GET", req.method);
|
||||
assert.equal("/hello", url.parse(req.url).pathname);
|
||||
|
||||
@@ -4,8 +4,7 @@ var path = require('path');
|
||||
var fs = require('fs');
|
||||
|
||||
var dirname = path.dirname(__filename);
|
||||
var fixtures = path.join(dirname, "../fixtures");
|
||||
var d = path.join(fixtures, "dir");
|
||||
var d = path.join(common.tmpDir, "dir");
|
||||
|
||||
var mkdir_error = false;
|
||||
var rmdir_error = false;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
common = require("../common");
|
||||
assert = common.assert
|
||||
tcp = require("tcp");
|
||||
net = require("net");
|
||||
|
||||
binaryString = "";
|
||||
for (var i = 255; i >= 0; i--) {
|
||||
@@ -19,7 +19,8 @@ for (var i = 255; i >= 0; i--) {
|
||||
binaryString += S;
|
||||
}
|
||||
|
||||
var echoServer = tcp.createServer(function (connection) {
|
||||
// safe constructor
|
||||
var echoServer = net.Server(function (connection) {
|
||||
connection.setEncoding("binary");
|
||||
connection.addListener("data", function (chunk) {
|
||||
common.error("recved: " + JSON.stringify(chunk));
|
||||
@@ -35,7 +36,7 @@ var recv = "";
|
||||
|
||||
echoServer.addListener("listening", function() {
|
||||
var j = 0;
|
||||
var c = tcp.createConnection(common.PORT);
|
||||
var c = net.createConnection(common.PORT);
|
||||
|
||||
c.setEncoding("binary");
|
||||
c.addListener("data", function (chunk) {
|
||||
|
||||
@@ -18,7 +18,12 @@ var caPem = fs.readFileSync(common.fixturesDir+"/test_ca.pem", 'ascii');
|
||||
var certPem = fs.readFileSync(common.fixturesDir+"/test_cert.pem", 'ascii');
|
||||
var keyPem = fs.readFileSync(common.fixturesDir+"/test_key.pem", 'ascii');
|
||||
|
||||
var credentials = crypto.createCredentials({key:keyPem, cert:certPem, ca:caPem});
|
||||
try{
|
||||
var credentials = crypto.createCredentials({key:keyPem, cert:certPem, ca:caPem});
|
||||
} catch (e) {
|
||||
console.log("Not compiled with OPENSSL support.");
|
||||
process.exit();
|
||||
}
|
||||
|
||||
var testData = "TEST123";
|
||||
var serverData = '';
|
||||
@@ -41,7 +46,8 @@ var secureServer = net.createServer(function (connection) {
|
||||
+ '"issuer":"/C=UK/ST=Acknack Ltd/L=Rhys Jones/O=node.js'
|
||||
+ '/OU=Test TLS Certificate/CN=localhost","valid_from":'
|
||||
+ '"Nov 11 09:52:22 2009 GMT","valid_to":'
|
||||
+ '"Nov 6 09:52:22 2029 GMT"}');
|
||||
+ '"Nov 6 09:52:22 2029 GMT",'
|
||||
+ '"fingerprint":"2A:7A:C2:DD:E5:F9:CC:53:72:35:99:7A:02:5A:71:38:52:EC:8A:DF"}');
|
||||
|
||||
});
|
||||
|
||||
@@ -76,7 +82,8 @@ secureServer.addListener("listening", function() {
|
||||
+ '"issuer":"/C=UK/ST=Acknack Ltd/L=Rhys Jones/O=node.js'
|
||||
+ '/OU=Test TLS Certificate/CN=localhost","valid_from":'
|
||||
+ '"Nov 11 09:52:22 2009 GMT","valid_to":'
|
||||
+ '"Nov 6 09:52:22 2029 GMT"}');
|
||||
+ '"Nov 6 09:52:22 2029 GMT",'
|
||||
+ '"fingerprint":"2A:7A:C2:DD:E5:F9:CC:53:72:35:99:7A:02:5A:71:38:52:EC:8A:DF"}');
|
||||
|
||||
secureClient.write(testData);
|
||||
secureClient.end();
|
||||
@@ -94,4 +101,4 @@ secureServer.addListener("listening", function() {
|
||||
process.addListener("exit", function () {
|
||||
assert.ok(gotSecureServer, "Did not get secure event for server");
|
||||
assert.ok(gotSecureClient, "Did not get secure event for clientr");
|
||||
});
|
||||
});
|
||||
|
||||
36
test/simple/test-next-tick-errors.js
Normal file
36
test/simple/test-next-tick-errors.js
Normal file
@@ -0,0 +1,36 @@
|
||||
common = require("../common");
|
||||
assert = common.assert
|
||||
|
||||
var order = [],
|
||||
exceptionHandled = false;
|
||||
|
||||
// This nextTick function will throw an error. It should only be called once.
|
||||
// When it throws an error, it should still get removed from the queue.
|
||||
process.nextTick(function() {
|
||||
order.push('A');
|
||||
// cause an error
|
||||
what();
|
||||
});
|
||||
|
||||
// This nextTick function should remain in the queue when the first one
|
||||
// is removed. It should be called if the error in the first one is
|
||||
// caught (which we do in this test).
|
||||
process.nextTick(function() {
|
||||
order.push('C');
|
||||
});
|
||||
|
||||
process.addListener('uncaughtException', function() {
|
||||
if (!exceptionHandled) {
|
||||
exceptionHandled = true;
|
||||
order.push('B');
|
||||
}
|
||||
else {
|
||||
// If we get here then the first process.nextTick got called twice
|
||||
order.push('OOPS!');
|
||||
}
|
||||
});
|
||||
|
||||
process.addListener('exit', function() {
|
||||
assert.deepEqual(['A','B','C'], order);
|
||||
});
|
||||
|
||||
17
test/simple/test-next-tick-ordering2.js
Normal file
17
test/simple/test-next-tick-ordering2.js
Normal file
@@ -0,0 +1,17 @@
|
||||
common = require("../common");
|
||||
assert = common.assert
|
||||
|
||||
var order = [];
|
||||
process.nextTick(function () {
|
||||
setTimeout(function() {
|
||||
order.push('setTimeout');
|
||||
}, 0);
|
||||
|
||||
process.nextTick(function() {
|
||||
order.push('nextTick');
|
||||
});
|
||||
})
|
||||
|
||||
process.addListener('exit', function () {
|
||||
assert.deepEqual(order, ['nextTick', 'setTimeout']);
|
||||
});
|
||||
52
test/simple/test-pump-file2tcp-noexist.js
Normal file
52
test/simple/test-pump-file2tcp-noexist.js
Normal file
@@ -0,0 +1,52 @@
|
||||
common = require("../common");
|
||||
assert = common.assert
|
||||
net = require("net");
|
||||
fs = require("fs");
|
||||
sys = require("sys");
|
||||
path = require("path");
|
||||
fn = path.join(common.fixturesDir, 'does_not_exist.txt');
|
||||
|
||||
var got_error = false;
|
||||
var conn_closed = false;
|
||||
|
||||
server = net.createServer(function (stream) {
|
||||
common.error('pump!');
|
||||
sys.pump(fs.createReadStream(fn), stream, function (err) {
|
||||
common.error("sys.pump's callback fired");
|
||||
if (err) {
|
||||
got_error = true;
|
||||
} else {
|
||||
common.debug("sys.pump's callback fired with no error");
|
||||
common.debug("this shouldn't happen as the file doesn't exist...");
|
||||
assert.equal(true, false);
|
||||
}
|
||||
server.close();
|
||||
});
|
||||
});
|
||||
|
||||
server.listen(common.PORT, function () {
|
||||
conn = net.createConnection(common.PORT);
|
||||
conn.setEncoding('utf8');
|
||||
conn.addListener("data", function (chunk) {
|
||||
common.error('recv data! nchars = ' + chunk.length);
|
||||
buffer += chunk;
|
||||
});
|
||||
|
||||
conn.addListener("end", function () {
|
||||
conn.end();
|
||||
});
|
||||
|
||||
conn.addListener("close", function () {
|
||||
common.error('client connection close');
|
||||
conn_closed = true;
|
||||
});
|
||||
});
|
||||
|
||||
var buffer = '';
|
||||
count = 0;
|
||||
|
||||
process.addListener('exit', function () {
|
||||
assert.equal(true, got_error);
|
||||
assert.equal(true, conn_closed);
|
||||
console.log("exiting");
|
||||
});
|
||||
108
test/simple/test-readline.js
Normal file
108
test/simple/test-readline.js
Normal file
@@ -0,0 +1,108 @@
|
||||
common = require("../common");
|
||||
assert = common.assert;
|
||||
var readline = require("readline");
|
||||
|
||||
var key = {
|
||||
xterm: {
|
||||
home: [27, 91, 72],
|
||||
end: [27, 91, 70],
|
||||
metab: [27, 98],
|
||||
metaf: [27, 102],
|
||||
metad: [27, 100]
|
||||
},
|
||||
gnome: {
|
||||
home: [27, 79, 72],
|
||||
end: [27, 79, 70]
|
||||
},
|
||||
rxvt: {
|
||||
home: [27, 91, 55],
|
||||
end: [27, 91, 56]
|
||||
},
|
||||
putty: {
|
||||
home: [27, 91, 49, 126],
|
||||
end: [27, 91, 52, 126]
|
||||
}
|
||||
};
|
||||
|
||||
var readlineFakeStream = function() {
|
||||
var written_bytes = [];
|
||||
var rl = readline.createInterface({
|
||||
fd: 1,
|
||||
write: function(b) {
|
||||
written_bytes.push(b);
|
||||
}}, function (text) {
|
||||
return [[], ""];
|
||||
});
|
||||
rl.written_bytes = written_bytes;
|
||||
return rl;
|
||||
};
|
||||
|
||||
var rl = readlineFakeStream();
|
||||
var written_bytes_length, refreshed;
|
||||
|
||||
rl.write('foo');
|
||||
assert.equal(3, rl.cursor);
|
||||
rl.write(key.xterm.home);
|
||||
assert.equal(0, rl.cursor);
|
||||
rl.write(key.xterm.end);
|
||||
assert.equal(3, rl.cursor);
|
||||
rl.write(key.rxvt.home);
|
||||
assert.equal(0, rl.cursor);
|
||||
rl.write(key.rxvt.end);
|
||||
assert.equal(3, rl.cursor);
|
||||
rl.write(key.gnome.home);
|
||||
assert.equal(0, rl.cursor);
|
||||
rl.write(key.gnome.end);
|
||||
assert.equal(3, rl.cursor);
|
||||
rl.write(key.putty.home);
|
||||
assert.equal(0, rl.cursor);
|
||||
rl.write(key.putty.end);
|
||||
assert.equal(3, rl.cursor);
|
||||
|
||||
rl = readlineFakeStream();
|
||||
rl.write('foo bar.hop/zoo');
|
||||
rl.write(key.xterm.home);
|
||||
written_bytes_length = rl.written_bytes.length;
|
||||
rl.write(key.xterm.metaf);
|
||||
assert.equal(3, rl.cursor);
|
||||
refreshed = written_bytes_length !== rl.written_bytes.length;
|
||||
assert.equal(true, refreshed);
|
||||
rl.write(key.xterm.metaf);
|
||||
assert.equal(7, rl.cursor);
|
||||
rl.write(key.xterm.metaf);
|
||||
assert.equal(11, rl.cursor);
|
||||
written_bytes_length = rl.written_bytes.length;
|
||||
rl.write(key.xterm.metaf);
|
||||
assert.equal(15, rl.cursor);
|
||||
refreshed = written_bytes_length !== rl.written_bytes.length;
|
||||
assert.equal(true, refreshed);
|
||||
written_bytes_length = rl.written_bytes.length;
|
||||
rl.write(key.xterm.metab);
|
||||
assert.equal(12, rl.cursor);
|
||||
refreshed = written_bytes_length !== rl.written_bytes.length;
|
||||
assert.equal(true, refreshed);
|
||||
rl.write(key.xterm.metab);
|
||||
assert.equal(8, rl.cursor);
|
||||
rl.write(key.xterm.metab);
|
||||
assert.equal(4, rl.cursor);
|
||||
written_bytes_length = rl.written_bytes.length;
|
||||
rl.write(key.xterm.metab);
|
||||
assert.equal(0, rl.cursor);
|
||||
refreshed = written_bytes_length !== rl.written_bytes.length;
|
||||
assert.equal(true, refreshed);
|
||||
|
||||
rl = readlineFakeStream();
|
||||
rl.write('foo bar.hop/zoo');
|
||||
rl.write(key.xterm.home);
|
||||
rl.write(key.xterm.metad);
|
||||
assert.equal(0, rl.cursor);
|
||||
assert.equal(' bar.hop/zoo', rl.line);
|
||||
rl.write(key.xterm.metad);
|
||||
assert.equal(0, rl.cursor);
|
||||
assert.equal('.hop/zoo', rl.line);
|
||||
rl.write(key.xterm.metad);
|
||||
assert.equal(0, rl.cursor);
|
||||
assert.equal('/zoo', rl.line);
|
||||
rl.write(key.xterm.metad);
|
||||
assert.equal(0, rl.cursor);
|
||||
assert.equal('', rl.line);
|
||||
@@ -60,7 +60,7 @@ function tcp_test() {
|
||||
});
|
||||
|
||||
client_tcp.addListener('data', function (data) {
|
||||
read_buffer += data.asciiSlice(0, data.length);
|
||||
read_buffer += data.toString('ascii', 0, data.length);
|
||||
common.error("TCP data: " + JSON.stringify(read_buffer) + ", expecting " + JSON.stringify(client_tcp.expect));
|
||||
if (read_buffer.indexOf(prompt_tcp) !== -1) {
|
||||
assert.strictEqual(client_tcp.expect, read_buffer);
|
||||
@@ -121,7 +121,7 @@ function unix_test() {
|
||||
});
|
||||
|
||||
client_unix.addListener('data', function (data) {
|
||||
read_buffer += data.asciiSlice(0, data.length);
|
||||
read_buffer += data.toString('ascii', 0, data.length);
|
||||
common.error("Unix data: " + JSON.stringify(read_buffer) + ", expecting " + JSON.stringify(client_unix.expect));
|
||||
if (read_buffer.indexOf(prompt_unix) !== -1) {
|
||||
assert.strictEqual(client_unix.expect, read_buffer);
|
||||
|
||||
@@ -7,6 +7,10 @@ var url = require("url"),
|
||||
// URLs to parse, and expected data
|
||||
// { url : parsed }
|
||||
var parseTests = {
|
||||
"//some_path" : {
|
||||
"href": "//some_path",
|
||||
"pathname": "//some_path"
|
||||
},
|
||||
"http://www.narwhaljs.org/blog/categories?id=news" : {
|
||||
"href": "http://www.narwhaljs.org/blog/categories?id=news",
|
||||
"protocol": "http:",
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
|
||||
import test
|
||||
import os
|
||||
import shutil
|
||||
from shutil import rmtree
|
||||
from os import mkdir
|
||||
from os.path import join, dirname, exists
|
||||
import re
|
||||
|
||||
@@ -42,7 +45,19 @@ class SimpleTestCase(test.TestCase):
|
||||
self.file = file
|
||||
self.config = config
|
||||
self.mode = mode
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
rmtree(join(dirname(self.config.root), 'tmp'))
|
||||
except:
|
||||
pass
|
||||
|
||||
def setUp(self):
|
||||
try:
|
||||
mkdir(join(dirname(self.config.root), 'tmp'))
|
||||
except:
|
||||
pass
|
||||
|
||||
def GetLabel(self):
|
||||
return "%s %s" % (self.mode, self.GetName())
|
||||
|
||||
|
||||
@@ -359,7 +359,16 @@ class TestCase(object):
|
||||
return TestOutput(self, full_command, output)
|
||||
|
||||
def Run(self):
|
||||
return self.RunCommand(self.GetCommand())
|
||||
self.setUp()
|
||||
result = self.RunCommand(self.GetCommand())
|
||||
self.tearDown()
|
||||
return result
|
||||
|
||||
def setUp(self):
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
return
|
||||
|
||||
|
||||
class TestOutput(object):
|
||||
|
||||
13
wscript
13
wscript
@@ -162,11 +162,12 @@ def configure(conf):
|
||||
if Options.options.efence:
|
||||
conf.check(lib='efence', libpath=['/usr/lib', '/usr/local/lib'], uselib_store='EFENCE')
|
||||
|
||||
if not conf.check(lib="execinfo", includes=['/usr/include', '/usr/local/include'], libpath=['/usr/lib', '/usr/local/lib'], uselib_store="EXECINFO"):
|
||||
# Note on Darwin/OS X: This will fail, but will still be used as the
|
||||
# execinfo stuff are part of the standard library.
|
||||
if sys.platform.startswith("freebsd"):
|
||||
conf.fatal("Install the libexecinfo port from /usr/ports/devel/libexecinfo.")
|
||||
if sys.platform.startswith("freebsd"):
|
||||
if not conf.check(lib="execinfo",
|
||||
includes=['/usr/include', '/usr/local/include'],
|
||||
libpath=['/usr/lib', '/usr/local/lib'],
|
||||
uselib_store="EXECINFO"):
|
||||
conf.fatal("Install the libexecinfo port from /usr/ports/devel/libexecinfo.")
|
||||
|
||||
if not Options.options.without_ssl:
|
||||
if conf.check_cfg(package='openssl',
|
||||
@@ -186,6 +187,8 @@ def configure(conf):
|
||||
if libcrypto and libssl:
|
||||
conf.env["USE_OPENSSL"] = Options.options.use_openssl = True
|
||||
conf.env.append_value("CXXFLAGS", "-DHAVE_OPENSSL=1")
|
||||
else:
|
||||
Options.options.use_openssl = conf.env["USE_OPENSSL"] = False
|
||||
|
||||
conf.check(lib='rt', uselib_store='RT')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user