mirror of
https://github.com/nodejs/node.git
synced 2025-05-06 23:10:15 +00:00
src, lib: update after internal api change
Libuv now returns errors directly. Make everything in src/ and lib/ follow suit. The changes to lib/ are not strictly necessary but they remove the need for the abominations that are process._errno and node::SetErrno().
This commit is contained in:
parent
0161ec87af
commit
ca9eb718fb
@ -23,10 +23,13 @@ var StringDecoder = require('string_decoder').StringDecoder;
|
|||||||
var EventEmitter = require('events').EventEmitter;
|
var EventEmitter = require('events').EventEmitter;
|
||||||
var net = require('net');
|
var net = require('net');
|
||||||
var dgram = require('dgram');
|
var dgram = require('dgram');
|
||||||
var Process = process.binding('process_wrap').Process;
|
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var util = require('util');
|
var util = require('util');
|
||||||
var constants; // if (!constants) constants = process.binding('constants');
|
|
||||||
|
var Process = process.binding('process_wrap').Process;
|
||||||
|
var uv = process.binding('uv');
|
||||||
|
|
||||||
|
var constants; // Lazy-loaded process.binding('constants')
|
||||||
|
|
||||||
var errnoException = util._errnoException;
|
var errnoException = util._errnoException;
|
||||||
var handleWraps = {};
|
var handleWraps = {};
|
||||||
@ -326,7 +329,8 @@ function setupChannel(target, channel) {
|
|||||||
var decoder = new StringDecoder('utf8');
|
var decoder = new StringDecoder('utf8');
|
||||||
var jsonBuffer = '';
|
var jsonBuffer = '';
|
||||||
channel.buffering = false;
|
channel.buffering = false;
|
||||||
channel.onread = function(pool, recvHandle) {
|
channel.onread = function(nread, pool, recvHandle) {
|
||||||
|
// TODO(bnoordhuis) Check that nread > 0.
|
||||||
if (pool) {
|
if (pool) {
|
||||||
jsonBuffer += decoder.write(pool);
|
jsonBuffer += decoder.write(pool);
|
||||||
|
|
||||||
@ -449,22 +453,18 @@ function setupChannel(target, channel) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var req = { oncomplete: nop };
|
||||||
var string = JSON.stringify(message) + '\n';
|
var string = JSON.stringify(message) + '\n';
|
||||||
var writeReq = channel.writeUtf8String(string, handle);
|
var err = channel.writeUtf8String(req, string, handle);
|
||||||
|
|
||||||
if (!writeReq) {
|
if (err) {
|
||||||
var er = errnoException(process._errno,
|
this.emit('error', errnoException(err, 'write'));
|
||||||
'write',
|
|
||||||
'cannot write to IPC channel.');
|
|
||||||
this.emit('error', er);
|
|
||||||
} else if (handle && !this._handleQueue) {
|
} else if (handle && !this._handleQueue) {
|
||||||
this._handleQueue = [];
|
this._handleQueue = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj && obj.postSend) {
|
if (obj && obj.postSend) {
|
||||||
writeReq.oncomplete = obj.postSend.bind(null, handle);
|
req.oncomplete = obj.postSend.bind(null, handle);
|
||||||
} else {
|
|
||||||
writeReq.oncomplete = nop;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If the master is > 2 read() calls behind, please stop sending. */
|
/* If the master is > 2 read() calls behind, please stop sending. */
|
||||||
@ -617,7 +617,7 @@ exports.execFile = function(file /* args, options, callback */) {
|
|||||||
var exited = false;
|
var exited = false;
|
||||||
var timeoutId;
|
var timeoutId;
|
||||||
|
|
||||||
var err;
|
var ex;
|
||||||
|
|
||||||
function exithandler(code, signal) {
|
function exithandler(code, signal) {
|
||||||
if (exited) return;
|
if (exited) return;
|
||||||
@ -630,21 +630,21 @@ exports.execFile = function(file /* args, options, callback */) {
|
|||||||
|
|
||||||
if (!callback) return;
|
if (!callback) return;
|
||||||
|
|
||||||
if (err) {
|
if (ex) {
|
||||||
callback(err, stdout, stderr);
|
callback(ex, stdout, stderr);
|
||||||
} else if (code === 0 && signal === null) {
|
} else if (code === 0 && signal === null) {
|
||||||
callback(null, stdout, stderr);
|
callback(null, stdout, stderr);
|
||||||
} else {
|
} else {
|
||||||
var e = new Error('Command failed: ' + stderr);
|
ex = new Error('Command failed: ' + stderr);
|
||||||
e.killed = child.killed || killed;
|
ex.killed = child.killed || killed;
|
||||||
e.code = code;
|
ex.code = code < 0 ? uv.errname(code) : code;
|
||||||
e.signal = signal;
|
ex.signal = signal;
|
||||||
callback(e, stdout, stderr);
|
callback(ex, stdout, stderr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function errorhandler(e) {
|
function errorhandler(e) {
|
||||||
err = e;
|
ex = e;
|
||||||
child.stdout.destroy();
|
child.stdout.destroy();
|
||||||
child.stderr.destroy();
|
child.stderr.destroy();
|
||||||
exithandler();
|
exithandler();
|
||||||
@ -658,7 +658,7 @@ exports.execFile = function(file /* args, options, callback */) {
|
|||||||
try {
|
try {
|
||||||
child.kill(options.killSignal);
|
child.kill(options.killSignal);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
err = e;
|
ex = e;
|
||||||
exithandler();
|
exithandler();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -676,7 +676,7 @@ exports.execFile = function(file /* args, options, callback */) {
|
|||||||
child.stdout.addListener('data', function(chunk) {
|
child.stdout.addListener('data', function(chunk) {
|
||||||
stdout += chunk;
|
stdout += chunk;
|
||||||
if (stdout.length > options.maxBuffer) {
|
if (stdout.length > options.maxBuffer) {
|
||||||
err = new Error('stdout maxBuffer exceeded.');
|
ex = new Error('stdout maxBuffer exceeded.');
|
||||||
kill();
|
kill();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -684,7 +684,7 @@ exports.execFile = function(file /* args, options, callback */) {
|
|||||||
child.stderr.addListener('data', function(chunk) {
|
child.stderr.addListener('data', function(chunk) {
|
||||||
stderr += chunk;
|
stderr += chunk;
|
||||||
if (stderr.length > options.maxBuffer) {
|
if (stderr.length > options.maxBuffer) {
|
||||||
err = new Error('stderr maxBuffer exceeded.');
|
ex = new Error('stderr maxBuffer exceeded.');
|
||||||
kill();
|
kill();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -767,9 +767,9 @@ function ChildProcess() {
|
|||||||
//
|
//
|
||||||
// new in 0.9.x:
|
// new in 0.9.x:
|
||||||
//
|
//
|
||||||
// - spawn failures are reported with exitCode == -1
|
// - spawn failures are reported with exitCode < 0
|
||||||
//
|
//
|
||||||
var err = (exitCode == -1) ? errnoException(process._errno, 'spawn') : null;
|
var err = (exitCode < 0) ? errnoException(exitCode, 'spawn') : null;
|
||||||
|
|
||||||
if (signalCode) {
|
if (signalCode) {
|
||||||
self.signalCode = signalCode;
|
self.signalCode = signalCode;
|
||||||
@ -784,7 +784,7 @@ function ChildProcess() {
|
|||||||
self._handle.close();
|
self._handle.close();
|
||||||
self._handle = null;
|
self._handle = null;
|
||||||
|
|
||||||
if (exitCode == -1) {
|
if (exitCode < 0) {
|
||||||
self.emit('error', err);
|
self.emit('error', err);
|
||||||
} else {
|
} else {
|
||||||
self.emit('exit', self.exitCode, self.signalCode);
|
self.emit('exit', self.exitCode, self.signalCode);
|
||||||
@ -913,9 +913,9 @@ ChildProcess.prototype.spawn = function(options) {
|
|||||||
options.envPairs.push('NODE_CHANNEL_FD=' + ipcFd);
|
options.envPairs.push('NODE_CHANNEL_FD=' + ipcFd);
|
||||||
}
|
}
|
||||||
|
|
||||||
var r = this._handle.spawn(options);
|
var err = this._handle.spawn(options);
|
||||||
|
|
||||||
if (r) {
|
if (err) {
|
||||||
// Close all opened fds on error
|
// Close all opened fds on error
|
||||||
stdio.forEach(function(stdio) {
|
stdio.forEach(function(stdio) {
|
||||||
if (stdio.type === 'pipe') {
|
if (stdio.type === 'pipe') {
|
||||||
@ -925,7 +925,7 @@ ChildProcess.prototype.spawn = function(options) {
|
|||||||
|
|
||||||
this._handle.close();
|
this._handle.close();
|
||||||
this._handle = null;
|
this._handle = null;
|
||||||
throw errnoException(process._errno, 'spawn');
|
throw errnoException(err, 'spawn');
|
||||||
}
|
}
|
||||||
|
|
||||||
this.pid = this._handle.pid;
|
this.pid = this._handle.pid;
|
||||||
@ -966,7 +966,7 @@ ChildProcess.prototype.spawn = function(options) {
|
|||||||
// Add .send() method and start listening for IPC data
|
// Add .send() method and start listening for IPC data
|
||||||
if (ipc !== undefined) setupChannel(this, ipc);
|
if (ipc !== undefined) setupChannel(this, ipc);
|
||||||
|
|
||||||
return r;
|
return err;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -990,19 +990,20 @@ ChildProcess.prototype.kill = function(sig) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this._handle) {
|
if (this._handle) {
|
||||||
var r = this._handle.kill(signal);
|
var err = this._handle.kill(signal);
|
||||||
if (r == 0) {
|
if (err === 0) {
|
||||||
/* Success. */
|
/* Success. */
|
||||||
this.killed = true;
|
this.killed = true;
|
||||||
return true;
|
return true;
|
||||||
} else if (process._errno == 'ESRCH') {
|
}
|
||||||
|
if (err === uv.UV_ESRCH) {
|
||||||
/* Already dead. */
|
/* Already dead. */
|
||||||
} else if (process._errno == 'EINVAL' || process._errno == 'ENOSYS') {
|
} else if (err === uv.UV_EINVAL || err === uv.UV_ENOSYS) {
|
||||||
/* The underlying platform doesn't support this signal. */
|
/* The underlying platform doesn't support this signal. */
|
||||||
throw errnoException(process._errno, 'kill');
|
throw errnoException(err, 'kill');
|
||||||
} else {
|
} else {
|
||||||
/* Other error, almost certainly EPERM. */
|
/* Other error, almost certainly EPERM. */
|
||||||
this.emit('error', errnoException(process._errno, 'kill'));
|
this.emit('error', errnoException(err, 'kill'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,13 +58,20 @@ function SharedHandle(key, address, port, addressType, backlog, fd) {
|
|||||||
this.key = key;
|
this.key = key;
|
||||||
this.errno = '';
|
this.errno = '';
|
||||||
this.workers = [];
|
this.workers = [];
|
||||||
|
this.handle = null;
|
||||||
|
this.errno = 0;
|
||||||
|
|
||||||
|
// FIXME(bnoordhuis) Polymorphic return type for lack of a better solution.
|
||||||
|
var rval;
|
||||||
if (addressType === 'udp4' || addressType === 'udp6')
|
if (addressType === 'udp4' || addressType === 'udp6')
|
||||||
this.handle = dgram._createSocketHandle(address, port, addressType, fd);
|
rval = dgram._createSocketHandle(address, port, addressType, fd);
|
||||||
else
|
else
|
||||||
this.handle = net._createServerHandle(address, port, addressType, fd);
|
rval = net._createServerHandle(address, port, addressType, fd);
|
||||||
|
|
||||||
this.errno = this.handle ? '' : process._errno;
|
if (typeof rval === 'number')
|
||||||
|
this.errno = rval;
|
||||||
|
else
|
||||||
|
this.handle = rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedHandle.prototype.add = function(worker, send) {
|
SharedHandle.prototype.add = function(worker, send) {
|
||||||
@ -116,10 +123,15 @@ RoundRobinHandle.prototype.add = function(worker, send) {
|
|||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
function done() {
|
function done() {
|
||||||
if (self.handle.getsockname)
|
if (self.handle.getsockname) {
|
||||||
send(null, { sockname: self.handle.getsockname() }, null);
|
var out = {};
|
||||||
else
|
var err = self.handle.getsockname(out);
|
||||||
|
// TODO(bnoordhuis) Check err.
|
||||||
|
send(null, { sockname: out }, null);
|
||||||
|
}
|
||||||
|
else {
|
||||||
send(null, null, null); // UNIX socket.
|
send(null, null, null); // UNIX socket.
|
||||||
|
}
|
||||||
self.handoff(worker); // In case there are connections pending.
|
self.handoff(worker); // In case there are connections pending.
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,7 +155,7 @@ RoundRobinHandle.prototype.remove = function(worker) {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
RoundRobinHandle.prototype.distribute = function(handle) {
|
RoundRobinHandle.prototype.distribute = function(err, handle) {
|
||||||
this.handles.push(handle);
|
this.handles.push(handle);
|
||||||
var worker = this.free.shift();
|
var worker = this.free.shift();
|
||||||
if (worker) this.handoff(worker);
|
if (worker) this.handoff(worker);
|
||||||
@ -164,7 +176,7 @@ RoundRobinHandle.prototype.handoff = function(worker) {
|
|||||||
if (reply.accepted)
|
if (reply.accepted)
|
||||||
handle.close();
|
handle.close();
|
||||||
else
|
else
|
||||||
self.distribute(handle); // Worker is shutting down. Send to another.
|
self.distribute(0, handle); // Worker is shutting down. Send to another.
|
||||||
self.handoff(worker);
|
self.handoff(worker);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -476,8 +488,9 @@ function workerInit() {
|
|||||||
|
|
||||||
function onerror(message, cb) {
|
function onerror(message, cb) {
|
||||||
function listen(backlog) {
|
function listen(backlog) {
|
||||||
process._errno = message.errno;
|
// Translate 'EADDRINUSE' error back to numeric value. This function
|
||||||
return -1;
|
// is called as sock._handle.listen().
|
||||||
|
return process.binding('uv')['UV_' + message.errno];
|
||||||
}
|
}
|
||||||
function close() {
|
function close() {
|
||||||
}
|
}
|
||||||
@ -503,10 +516,8 @@ function workerInit() {
|
|||||||
delete handles[key];
|
delete handles[key];
|
||||||
key = undefined;
|
key = undefined;
|
||||||
}
|
}
|
||||||
function getsockname() {
|
function getsockname(out) {
|
||||||
var rv = {};
|
if (key) util._extend(out, message.sockname);
|
||||||
if (key) return util._extend(rv, message.sockname);
|
|
||||||
return rv;
|
|
||||||
}
|
}
|
||||||
// Faux handle. Mimics a TCPWrap with just enough fidelity to get away
|
// Faux handle. Mimics a TCPWrap with just enough fidelity to get away
|
||||||
// with it. Fools net.Server into thinking that it's backed by a real
|
// with it. Fools net.Server into thinking that it's backed by a real
|
||||||
@ -530,7 +541,7 @@ function workerInit() {
|
|||||||
var server = handles[key];
|
var server = handles[key];
|
||||||
var accepted = (typeof server !== 'undefined');
|
var accepted = (typeof server !== 'undefined');
|
||||||
send({ ack: message.seq, accepted: accepted });
|
send({ ack: message.seq, accepted: accepted });
|
||||||
if (accepted) server.onconnection(handle);
|
if (accepted) server.onconnection(0, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
Worker.prototype.disconnect = function() {
|
Worker.prototype.disconnect = function() {
|
||||||
|
79
lib/dgram.js
79
lib/dgram.js
@ -96,10 +96,10 @@ exports._createSocketHandle = function(address, port, addressType, fd) {
|
|||||||
var handle = newHandle(addressType);
|
var handle = newHandle(addressType);
|
||||||
|
|
||||||
if (port || address) {
|
if (port || address) {
|
||||||
var r = handle.bind(address, port || 0, 0);
|
var err = handle.bind(address, port || 0, 0);
|
||||||
if (r == -1) {
|
if (err) {
|
||||||
handle.close();
|
handle.close();
|
||||||
handle = null;
|
return err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,8 +204,9 @@ Socket.prototype.bind = function(/*port, address, callback*/) {
|
|||||||
if (!self._handle)
|
if (!self._handle)
|
||||||
return; // handle has been closed in the mean time
|
return; // handle has been closed in the mean time
|
||||||
|
|
||||||
if (self._handle.bind(ip, port || 0, /*flags=*/ 0)) {
|
var err = self._handle.bind(ip, port || 0, /*flags=*/ 0);
|
||||||
self.emit('error', errnoException(process._errno, 'bind'));
|
if (err) {
|
||||||
|
self.emit('error', errnoException(err, 'bind'));
|
||||||
self._bindState = BIND_STATE_UNBOUND;
|
self._bindState = BIND_STATE_UNBOUND;
|
||||||
// Todo: close?
|
// Todo: close?
|
||||||
return;
|
return;
|
||||||
@ -276,22 +277,18 @@ Socket.prototype.send = function(buffer,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self._handle.lookup(address, function(err, ip) {
|
self._handle.lookup(address, function(ex, ip) {
|
||||||
if (err) {
|
if (ex) {
|
||||||
if (callback) callback(err);
|
if (callback) callback(ex);
|
||||||
self.emit('error', err);
|
self.emit('error', ex);
|
||||||
}
|
}
|
||||||
else if (self._handle) {
|
else if (self._handle) {
|
||||||
var req = self._handle.send(buffer, offset, length, port, ip);
|
var req = { cb: callback, oncomplete: afterSend };
|
||||||
if (req) {
|
var err = self._handle.send(req, buffer, offset, length, port, ip);
|
||||||
req.oncomplete = afterSend;
|
if (err) {
|
||||||
req.cb = callback;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// don't emit as error, dgram_legacy.js compatibility
|
// don't emit as error, dgram_legacy.js compatibility
|
||||||
var err = errnoException(process._errno, 'send');
|
|
||||||
process.nextTick(function() {
|
process.nextTick(function() {
|
||||||
callback(err);
|
callback(errnoException(err, 'send'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -319,17 +316,20 @@ Socket.prototype.close = function() {
|
|||||||
Socket.prototype.address = function() {
|
Socket.prototype.address = function() {
|
||||||
this._healthCheck();
|
this._healthCheck();
|
||||||
|
|
||||||
var address = this._handle.getsockname();
|
var out = {};
|
||||||
if (!address)
|
var err = this._handle.getsockname(out);
|
||||||
throw errnoException(process._errno, 'getsockname');
|
if (err) {
|
||||||
|
throw errnoException(err, 'getsockname');
|
||||||
|
}
|
||||||
|
|
||||||
return address;
|
return out;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Socket.prototype.setBroadcast = function(arg) {
|
Socket.prototype.setBroadcast = function(arg) {
|
||||||
if (this._handle.setBroadcast((arg) ? 1 : 0)) {
|
var err = this._handle.setBroadcast(arg ? 1 : 0);
|
||||||
throw errnoException(process._errno, 'setBroadcast');
|
if (err) {
|
||||||
|
throw errnoException(err, 'setBroadcast');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -339,8 +339,9 @@ Socket.prototype.setTTL = function(arg) {
|
|||||||
throw new TypeError('Argument must be a number');
|
throw new TypeError('Argument must be a number');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._handle.setTTL(arg)) {
|
var err = this._handle.setTTL(arg);
|
||||||
throw errnoException(process._errno, 'setTTL');
|
if (err) {
|
||||||
|
throw errnoException(err, 'setTTL');
|
||||||
}
|
}
|
||||||
|
|
||||||
return arg;
|
return arg;
|
||||||
@ -352,8 +353,9 @@ Socket.prototype.setMulticastTTL = function(arg) {
|
|||||||
throw new TypeError('Argument must be a number');
|
throw new TypeError('Argument must be a number');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._handle.setMulticastTTL(arg)) {
|
var err = this._handle.setMulticastTTL(arg);
|
||||||
throw errnoException(process._errno, 'setMulticastTTL');
|
if (err) {
|
||||||
|
throw errnoException(err, 'setMulticastTTL');
|
||||||
}
|
}
|
||||||
|
|
||||||
return arg;
|
return arg;
|
||||||
@ -361,10 +363,9 @@ Socket.prototype.setMulticastTTL = function(arg) {
|
|||||||
|
|
||||||
|
|
||||||
Socket.prototype.setMulticastLoopback = function(arg) {
|
Socket.prototype.setMulticastLoopback = function(arg) {
|
||||||
arg = arg ? 1 : 0;
|
var err = this._handle.setMulticastLoopback(arg ? 1 : 0);
|
||||||
|
if (err) {
|
||||||
if (this._handle.setMulticastLoopback(arg)) {
|
throw errnoException(err, 'setMulticastLoopback');
|
||||||
throw errnoException(process._errno, 'setMulticastLoopback');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return arg; // 0.4 compatibility
|
return arg; // 0.4 compatibility
|
||||||
@ -379,8 +380,9 @@ Socket.prototype.addMembership = function(multicastAddress,
|
|||||||
throw new Error('multicast address must be specified');
|
throw new Error('multicast address must be specified');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._handle.addMembership(multicastAddress, interfaceAddress)) {
|
var err = this._handle.addMembership(multicastAddress, interfaceAddress);
|
||||||
throw new errnoException(process._errno, 'addMembership');
|
if (err) {
|
||||||
|
throw new errnoException(err, 'addMembership');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -393,8 +395,9 @@ Socket.prototype.dropMembership = function(multicastAddress,
|
|||||||
throw new Error('multicast address must be specified');
|
throw new Error('multicast address must be specified');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._handle.dropMembership(multicastAddress, interfaceAddress)) {
|
var err = this._handle.dropMembership(multicastAddress, interfaceAddress);
|
||||||
throw new errnoException(process._errno, 'dropMembership');
|
if (err) {
|
||||||
|
throw new errnoException(err, 'dropMembership');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -415,10 +418,10 @@ Socket.prototype._stopReceiving = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
function onMessage(handle, buf, rinfo) {
|
function onMessage(nread, handle, buf, rinfo) {
|
||||||
var self = handle.owner;
|
var self = handle.owner;
|
||||||
if (!buf) {
|
if (nread < 0) {
|
||||||
return self.emit('error', errnoException(process._errno, 'recvmsg'));
|
return self.emit('error', errnoException(nread, 'recvmsg'));
|
||||||
}
|
}
|
||||||
rinfo.size = buf.length; // compatibility
|
rinfo.size = buf.length; // compatibility
|
||||||
self.emit('message', buf, rinfo);
|
self.emit('message', buf, rinfo);
|
||||||
|
65
lib/dns.js
65
lib/dns.js
@ -19,14 +19,31 @@
|
|||||||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
var cares = process.binding('cares_wrap');
|
|
||||||
var net = require('net');
|
var net = require('net');
|
||||||
var util = require('util');
|
var util = require('util');
|
||||||
|
|
||||||
var errnoException = util._errnoException;
|
var cares = process.binding('cares_wrap');
|
||||||
|
var uv = process.binding('uv');
|
||||||
|
|
||||||
var isIp = net.isIP;
|
var isIp = net.isIP;
|
||||||
|
|
||||||
|
|
||||||
|
function errnoException(err, syscall) {
|
||||||
|
// FIXME(bnoordhuis) Remove this backwards compatibility shite and pass
|
||||||
|
// the true error to the user. ENOTFOUND is not even a proper POSIX error!
|
||||||
|
if (err === uv.UV_EAI_MEMORY ||
|
||||||
|
err === uv.UV_EAI_NODATA ||
|
||||||
|
err === uv.UV_EAI_NONAME) {
|
||||||
|
var ex = new Error(syscall + ' ENOTFOUND');
|
||||||
|
ex.code = 'ENOTFOUND';
|
||||||
|
ex.errno = 'ENOTFOUND';
|
||||||
|
ex.syscall = syscall;
|
||||||
|
return ex;
|
||||||
|
}
|
||||||
|
return util._errnoException(err, syscall);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// c-ares invokes a callback either synchronously or asynchronously,
|
// c-ares invokes a callback either synchronously or asynchronously,
|
||||||
// but the dns API should always invoke a callback asynchronously.
|
// but the dns API should always invoke a callback asynchronously.
|
||||||
//
|
//
|
||||||
@ -98,28 +115,28 @@ exports.lookup = function(domain, family, callback) {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
function onanswer(addresses) {
|
function onanswer(err, addresses) {
|
||||||
if (addresses) {
|
if (err) {
|
||||||
if (family) {
|
return callback(errnoException(err, 'getaddrinfo'));
|
||||||
callback(null, addresses[0], family);
|
}
|
||||||
} else {
|
if (family) {
|
||||||
callback(null, addresses[0], addresses[0].indexOf(':') >= 0 ? 6 : 4);
|
callback(null, addresses[0], family);
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
callback(errnoException(process._errno, 'getaddrinfo'));
|
callback(null, addresses[0], addresses[0].indexOf(':') >= 0 ? 6 : 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var wrap = cares.getaddrinfo(domain, family);
|
var req = {};
|
||||||
|
var err = cares.getaddrinfo(req, domain, family);
|
||||||
|
|
||||||
if (!wrap) {
|
if (err) {
|
||||||
throw errnoException(process._errno, 'getaddrinfo');
|
throw errnoException(err, 'getaddrinfo');
|
||||||
}
|
}
|
||||||
|
|
||||||
wrap.oncomplete = onanswer;
|
req.oncomplete = onanswer;
|
||||||
|
|
||||||
callback.immediately = true;
|
callback.immediately = true;
|
||||||
return wrap;
|
return req;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -127,22 +144,22 @@ function resolver(bindingName) {
|
|||||||
var binding = cares[bindingName];
|
var binding = cares[bindingName];
|
||||||
|
|
||||||
return function query(name, callback) {
|
return function query(name, callback) {
|
||||||
function onanswer(status, result) {
|
function onanswer(err, result) {
|
||||||
if (!status) {
|
if (err)
|
||||||
|
callback(errnoException(err, bindingName));
|
||||||
|
else
|
||||||
callback(null, result);
|
callback(null, result);
|
||||||
} else {
|
|
||||||
callback(errnoException(process._errno, bindingName));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
callback = makeAsync(callback);
|
callback = makeAsync(callback);
|
||||||
var wrap = binding(name, onanswer);
|
var req = {};
|
||||||
if (!wrap) {
|
var err = binding(req, name, onanswer);
|
||||||
throw errnoException(process._errno, bindingName);
|
if (err) {
|
||||||
|
throw errnoException(err, bindingName);
|
||||||
}
|
}
|
||||||
|
|
||||||
callback.immediately = true;
|
callback.immediately = true;
|
||||||
return wrap;
|
return req;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
lib/fs.js
11
lib/fs.js
@ -1004,9 +1004,9 @@ function FSWatcher() {
|
|||||||
this._handle.owner = this;
|
this._handle.owner = this;
|
||||||
|
|
||||||
this._handle.onchange = function(status, event, filename) {
|
this._handle.onchange = function(status, event, filename) {
|
||||||
if (status) {
|
if (status < 0) {
|
||||||
self._handle.close();
|
self._handle.close();
|
||||||
self.emit('error', errnoException(process._errno, 'watch'));
|
self.emit('error', errnoException(status, 'watch'));
|
||||||
} else {
|
} else {
|
||||||
self.emit('change', event, filename);
|
self.emit('change', event, filename);
|
||||||
}
|
}
|
||||||
@ -1016,11 +1016,10 @@ util.inherits(FSWatcher, EventEmitter);
|
|||||||
|
|
||||||
FSWatcher.prototype.start = function(filename, persistent) {
|
FSWatcher.prototype.start = function(filename, persistent) {
|
||||||
nullCheck(filename);
|
nullCheck(filename);
|
||||||
var r = this._handle.start(pathModule._makeLong(filename), persistent);
|
var err = this._handle.start(pathModule._makeLong(filename), persistent);
|
||||||
|
if (err) {
|
||||||
if (r) {
|
|
||||||
this._handle.close();
|
this._handle.close();
|
||||||
throw errnoException(process._errno, 'watch');
|
throw errnoException(err, 'watch');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
226
lib/net.js
226
lib/net.js
@ -25,6 +25,7 @@ var timers = require('timers');
|
|||||||
var util = require('util');
|
var util = require('util');
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var cares = process.binding('cares_wrap');
|
var cares = process.binding('cares_wrap');
|
||||||
|
var uv = process.binding('uv');
|
||||||
|
|
||||||
var cluster;
|
var cluster;
|
||||||
var errnoException = util._errnoException;
|
var errnoException = util._errnoException;
|
||||||
@ -206,12 +207,11 @@ function onSocketFinish() {
|
|||||||
if (!this._handle || !this._handle.shutdown)
|
if (!this._handle || !this._handle.shutdown)
|
||||||
return this.destroy();
|
return this.destroy();
|
||||||
|
|
||||||
var shutdownReq = this._handle.shutdown();
|
var req = { oncomplete: afterShutdown };
|
||||||
|
var err = this._handle.shutdown(req);
|
||||||
|
|
||||||
if (!shutdownReq)
|
if (err)
|
||||||
return this._destroy(errnoException(process._errno, 'shutdown'));
|
return this._destroy(errnoException(err, 'shutdown'));
|
||||||
|
|
||||||
shutdownReq.oncomplete = afterShutdown;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -338,7 +338,10 @@ Socket.prototype.setKeepAlive = function(setting, msecs) {
|
|||||||
|
|
||||||
Socket.prototype.address = function() {
|
Socket.prototype.address = function() {
|
||||||
if (this._handle && this._handle.getsockname) {
|
if (this._handle && this._handle.getsockname) {
|
||||||
return this._handle.getsockname();
|
var out = {};
|
||||||
|
var err = this._handle.getsockname(out);
|
||||||
|
// TODO(bnoordhuis) Check err and throw?
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
@ -381,9 +384,9 @@ Socket.prototype._read = function(n) {
|
|||||||
// not already reading, start the flow
|
// not already reading, start the flow
|
||||||
debug('Socket._read readStart');
|
debug('Socket._read readStart');
|
||||||
this._handle.reading = true;
|
this._handle.reading = true;
|
||||||
var r = this._handle.readStart();
|
var err = this._handle.readStart();
|
||||||
if (r)
|
if (err)
|
||||||
this._destroy(errnoException(process._errno, 'read'));
|
this._destroy(errnoException(err, 'read'));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -486,17 +489,16 @@ Socket.prototype.destroy = function(exception) {
|
|||||||
|
|
||||||
// This function is called whenever the handle gets a
|
// This function is called whenever the handle gets a
|
||||||
// buffer, or when there's an error reading.
|
// buffer, or when there's an error reading.
|
||||||
function onread(buffer) {
|
function onread(nread, buffer) {
|
||||||
var handle = this;
|
var handle = this;
|
||||||
var self = handle.owner;
|
var self = handle.owner;
|
||||||
var length = !!buffer ? buffer.length : 0;
|
|
||||||
assert(handle === self._handle, 'handle != self._handle');
|
assert(handle === self._handle, 'handle != self._handle');
|
||||||
|
|
||||||
timers._unrefActive(self);
|
timers._unrefActive(self);
|
||||||
|
|
||||||
debug('onread', process._errno, length);
|
debug('onread', nread);
|
||||||
|
|
||||||
if (buffer) {
|
if (nread > 0) {
|
||||||
debug('got data');
|
debug('got data');
|
||||||
|
|
||||||
// read success.
|
// read success.
|
||||||
@ -504,16 +506,9 @@ function onread(buffer) {
|
|||||||
// will prevent this from being called again until _read() gets
|
// will prevent this from being called again until _read() gets
|
||||||
// called again.
|
// called again.
|
||||||
|
|
||||||
// if we didn't get any bytes, that doesn't necessarily mean EOF.
|
|
||||||
// wait for the next one.
|
|
||||||
if (length === 0) {
|
|
||||||
debug('not any data, keep waiting');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if it's not enough data, we'll just call handle.readStart()
|
// if it's not enough data, we'll just call handle.readStart()
|
||||||
// again right away.
|
// again right away.
|
||||||
self.bytesRead += length;
|
self.bytesRead += nread;
|
||||||
|
|
||||||
// Optimization: emit the original buffer with end points
|
// Optimization: emit the original buffer with end points
|
||||||
var ret = true;
|
var ret = true;
|
||||||
@ -523,33 +518,41 @@ function onread(buffer) {
|
|||||||
if (handle.reading && !ret) {
|
if (handle.reading && !ret) {
|
||||||
handle.reading = false;
|
handle.reading = false;
|
||||||
debug('readStop');
|
debug('readStop');
|
||||||
var r = handle.readStop();
|
var err = handle.readStop();
|
||||||
if (r)
|
if (err)
|
||||||
self._destroy(errnoException(process._errno, 'read'));
|
self._destroy(errnoException(err, 'read'));
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
} else if (process._errno == 'EOF') {
|
|
||||||
debug('EOF');
|
|
||||||
|
|
||||||
if (self._readableState.length === 0) {
|
|
||||||
self.readable = false;
|
|
||||||
maybeDestroy(self);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self.onend) self.once('end', self.onend);
|
|
||||||
|
|
||||||
// push a null to signal the end of data.
|
|
||||||
self.push(null);
|
|
||||||
|
|
||||||
// internal end event so that we know that the actual socket
|
|
||||||
// is no longer readable, and we can start the shutdown
|
|
||||||
// procedure. No need to wait for all the data to be consumed.
|
|
||||||
self.emit('_socketEnd');
|
|
||||||
} else {
|
|
||||||
debug('error', process._errno);
|
|
||||||
// Error
|
|
||||||
self._destroy(errnoException(process._errno, 'read'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if we didn't get any bytes, that doesn't necessarily mean EOF.
|
||||||
|
// wait for the next one.
|
||||||
|
if (nread === 0) {
|
||||||
|
debug('not any data, keep waiting');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error, possibly EOF.
|
||||||
|
if (nread !== uv.UV_EOF) {
|
||||||
|
return self._destroy(errnoException(nread, 'read'));
|
||||||
|
}
|
||||||
|
|
||||||
|
debug('EOF');
|
||||||
|
|
||||||
|
if (self._readableState.length === 0) {
|
||||||
|
self.readable = false;
|
||||||
|
maybeDestroy(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.onend) self.once('end', self.onend);
|
||||||
|
|
||||||
|
// push a null to signal the end of data.
|
||||||
|
self.push(null);
|
||||||
|
|
||||||
|
// internal end event so that we know that the actual socket
|
||||||
|
// is no longer readable, and we can start the shutdown
|
||||||
|
// procedure. No need to wait for all the data to be consumed.
|
||||||
|
self.emit('_socketEnd');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -558,10 +561,10 @@ Socket.prototype._getpeername = function() {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
if (!this._peername) {
|
if (!this._peername) {
|
||||||
this._peername = this._handle.getpeername();
|
var out = {};
|
||||||
if (!this._peername) {
|
var err = this._handle.getpeername(out);
|
||||||
return {};
|
if (err) return {}; // FIXME(bnoordhuis) Throw?
|
||||||
}
|
this._peername = out;
|
||||||
}
|
}
|
||||||
return this._peername;
|
return this._peername;
|
||||||
};
|
};
|
||||||
@ -582,10 +585,10 @@ Socket.prototype._getsockname = function() {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
if (!this._sockname) {
|
if (!this._sockname) {
|
||||||
this._sockname = this._handle.getsockname();
|
var out = {};
|
||||||
if (!this._sockname) {
|
var err = this._handle.getsockname(out);
|
||||||
return {};
|
if (err) return {}; // FIXME(bnoordhuis) Throw?
|
||||||
}
|
this._sockname = out;
|
||||||
}
|
}
|
||||||
return this._sockname;
|
return this._sockname;
|
||||||
};
|
};
|
||||||
@ -630,7 +633,9 @@ Socket.prototype._writeGeneric = function(writev, data, encoding, cb) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var writeReq;
|
var req = { oncomplete: afterWrite };
|
||||||
|
var err;
|
||||||
|
|
||||||
if (writev) {
|
if (writev) {
|
||||||
var chunks = new Array(data.length << 1);
|
var chunks = new Array(data.length << 1);
|
||||||
for (var i = 0; i < data.length; i++) {
|
for (var i = 0; i < data.length; i++) {
|
||||||
@ -640,28 +645,26 @@ Socket.prototype._writeGeneric = function(writev, data, encoding, cb) {
|
|||||||
chunks[i * 2] = chunk;
|
chunks[i * 2] = chunk;
|
||||||
chunks[i * 2 + 1] = enc;
|
chunks[i * 2 + 1] = enc;
|
||||||
}
|
}
|
||||||
var writeReq = this._handle.writev(chunks);
|
err = this._handle.writev(req, chunks);
|
||||||
|
|
||||||
// Retain chunks
|
// Retain chunks
|
||||||
if (writeReq)
|
if (err === 0) req._chunks = chunks;
|
||||||
writeReq._chunks = chunks;
|
|
||||||
} else {
|
} else {
|
||||||
var enc = Buffer.isBuffer(data) ? 'buffer' : encoding;
|
var enc = Buffer.isBuffer(data) ? 'buffer' : encoding;
|
||||||
var writeReq = createWriteReq(this._handle, data, enc);
|
err = createWriteReq(req, this._handle, data, enc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!writeReq)
|
if (err)
|
||||||
return this._destroy(errnoException(process._errno, 'write'), cb);
|
return this._destroy(errnoException(err, 'write'), cb);
|
||||||
|
|
||||||
writeReq.oncomplete = afterWrite;
|
this._bytesDispatched += req.bytes;
|
||||||
this._bytesDispatched += writeReq.bytes;
|
|
||||||
|
|
||||||
// If it was entirely flushed, we can write some more right now.
|
// If it was entirely flushed, we can write some more right now.
|
||||||
// However, if more is left in the queue, then wait until that clears.
|
// However, if more is left in the queue, then wait until that clears.
|
||||||
if (this._handle.writeQueueSize === 0)
|
if (this._handle.writeQueueSize === 0)
|
||||||
cb();
|
cb();
|
||||||
else
|
else
|
||||||
writeReq.cb = cb;
|
req.cb = cb;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -698,26 +701,26 @@ function getEncodingId(encoding) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function createWriteReq(handle, data, encoding) {
|
function createWriteReq(req, handle, data, encoding) {
|
||||||
switch (encoding) {
|
switch (encoding) {
|
||||||
case 'buffer':
|
case 'buffer':
|
||||||
return handle.writeBuffer(data);
|
return handle.writeBuffer(req, data);
|
||||||
|
|
||||||
case 'utf8':
|
case 'utf8':
|
||||||
case 'utf-8':
|
case 'utf-8':
|
||||||
return handle.writeUtf8String(data);
|
return handle.writeUtf8String(req, data);
|
||||||
|
|
||||||
case 'ascii':
|
case 'ascii':
|
||||||
return handle.writeAsciiString(data);
|
return handle.writeAsciiString(req, data);
|
||||||
|
|
||||||
case 'ucs2':
|
case 'ucs2':
|
||||||
case 'ucs-2':
|
case 'ucs-2':
|
||||||
case 'utf16le':
|
case 'utf16le':
|
||||||
case 'utf-16le':
|
case 'utf-16le':
|
||||||
return handle.writeUcs2String(data);
|
return handle.writeUcs2String(req, data);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return handle.writeBuffer(new Buffer(data, encoding));
|
return handle.writeBuffer(req, new Buffer(data, encoding));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -758,9 +761,10 @@ function afterWrite(status, handle, req) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status) {
|
if (status < 0) {
|
||||||
debug('write failure', errnoException(process._errno, 'write'));
|
var ex = errnoException(status, 'write');
|
||||||
self._destroy(errnoException(process._errno, 'write'), req.cb);
|
debug('write failure', ex);
|
||||||
|
self._destroy(ex, req.cb);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -780,33 +784,31 @@ function connect(self, address, port, addressType, localAddress) {
|
|||||||
|
|
||||||
assert.ok(self._connecting);
|
assert.ok(self._connecting);
|
||||||
|
|
||||||
|
var err;
|
||||||
if (localAddress) {
|
if (localAddress) {
|
||||||
var r;
|
|
||||||
if (addressType == 6) {
|
if (addressType == 6) {
|
||||||
r = self._handle.bind6(localAddress);
|
err = self._handle.bind6(localAddress);
|
||||||
} else {
|
} else {
|
||||||
r = self._handle.bind(localAddress);
|
err = self._handle.bind(localAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r) {
|
if (err) {
|
||||||
self._destroy(errnoException(process._errno, 'bind'));
|
self._destroy(errnoException(err, 'bind'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var connectReq;
|
var req = { oncomplete: afterConnect };
|
||||||
if (addressType == 6) {
|
if (addressType == 6) {
|
||||||
connectReq = self._handle.connect6(address, port);
|
err = self._handle.connect6(req, address, port);
|
||||||
} else if (addressType == 4) {
|
} else if (addressType == 4) {
|
||||||
connectReq = self._handle.connect(address, port);
|
err = self._handle.connect(req, address, port);
|
||||||
} else {
|
} else {
|
||||||
connectReq = self._handle.connect(address, afterConnect);
|
err = self._handle.connect(req, address, afterConnect);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (connectReq !== null) {
|
if (err) {
|
||||||
connectReq.oncomplete = afterConnect;
|
self._destroy(errnoException(err, 'connect'));
|
||||||
} else {
|
|
||||||
self._destroy(errnoException(process._errno, 'connect'));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -937,7 +939,7 @@ function afterConnect(status, handle, req, readable, writable) {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
self._connecting = false;
|
self._connecting = false;
|
||||||
self._destroy(errnoException(process._errno, 'connect'));
|
self._destroy(errnoException(status, 'connect'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -992,7 +994,7 @@ function toNumber(x) { return (x = Number(x)) >= 0 ? x : false; }
|
|||||||
|
|
||||||
var createServerHandle = exports._createServerHandle =
|
var createServerHandle = exports._createServerHandle =
|
||||||
function(address, port, addressType, fd) {
|
function(address, port, addressType, fd) {
|
||||||
var r = 0;
|
var err = 0;
|
||||||
// assign handle in listen, and clean up if bind or listen fails
|
// assign handle in listen, and clean up if bind or listen fails
|
||||||
var handle;
|
var handle;
|
||||||
|
|
||||||
@ -1003,8 +1005,7 @@ var createServerHandle = exports._createServerHandle =
|
|||||||
catch (e) {
|
catch (e) {
|
||||||
// Not a fd we can listen on. This will trigger an error.
|
// Not a fd we can listen on. This will trigger an error.
|
||||||
debug('listen invalid fd=' + fd + ': ' + e.message);
|
debug('listen invalid fd=' + fd + ': ' + e.message);
|
||||||
process._errno = 'EINVAL'; // hack, callers expect that errno is set
|
return uv.UV_EINVAL;
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
handle.open(fd);
|
handle.open(fd);
|
||||||
handle.readable = true;
|
handle.readable = true;
|
||||||
@ -1026,15 +1027,15 @@ var createServerHandle = exports._createServerHandle =
|
|||||||
if (address || port) {
|
if (address || port) {
|
||||||
debug('bind to ' + address);
|
debug('bind to ' + address);
|
||||||
if (addressType == 6) {
|
if (addressType == 6) {
|
||||||
r = handle.bind6(address, port);
|
err = handle.bind6(address, port);
|
||||||
} else {
|
} else {
|
||||||
r = handle.bind(address, port);
|
err = handle.bind(address, port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r) {
|
if (err) {
|
||||||
handle.close();
|
handle.close();
|
||||||
handle = null;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
@ -1044,20 +1045,20 @@ var createServerHandle = exports._createServerHandle =
|
|||||||
Server.prototype._listen2 = function(address, port, addressType, backlog, fd) {
|
Server.prototype._listen2 = function(address, port, addressType, backlog, fd) {
|
||||||
debug('listen2', address, port, addressType, backlog);
|
debug('listen2', address, port, addressType, backlog);
|
||||||
var self = this;
|
var self = this;
|
||||||
var r = 0;
|
|
||||||
|
|
||||||
// If there is not yet a handle, we need to create one and bind.
|
// If there is not yet a handle, we need to create one and bind.
|
||||||
// In the case of a server sent via IPC, we don't need to do this.
|
// In the case of a server sent via IPC, we don't need to do this.
|
||||||
if (!self._handle) {
|
if (!self._handle) {
|
||||||
debug('_listen2: create a handle');
|
debug('_listen2: create a handle');
|
||||||
self._handle = createServerHandle(address, port, addressType, fd);
|
var rval = createServerHandle(address, port, addressType, fd);
|
||||||
if (!self._handle) {
|
if (typeof rval === 'number') {
|
||||||
var error = errnoException(process._errno, 'listen');
|
var error = errnoException(rval, 'listen');
|
||||||
process.nextTick(function() {
|
process.nextTick(function() {
|
||||||
self.emit('error', error);
|
self.emit('error', error);
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
self._handle = rval;
|
||||||
} else {
|
} else {
|
||||||
debug('_listen2: have a handle already');
|
debug('_listen2: have a handle already');
|
||||||
}
|
}
|
||||||
@ -1068,10 +1069,10 @@ Server.prototype._listen2 = function(address, port, addressType, backlog, fd) {
|
|||||||
// Use a backlog of 512 entries. We pass 511 to the listen() call because
|
// Use a backlog of 512 entries. We pass 511 to the listen() call because
|
||||||
// the kernel does: backlogsize = roundup_pow_of_two(backlogsize + 1);
|
// the kernel does: backlogsize = roundup_pow_of_two(backlogsize + 1);
|
||||||
// which will thus give us a backlog of 512 entries.
|
// which will thus give us a backlog of 512 entries.
|
||||||
r = self._handle.listen(backlog || 511);
|
var err = self._handle.listen(backlog || 511);
|
||||||
|
|
||||||
if (r) {
|
if (err) {
|
||||||
var ex = errnoException(process._errno, 'listen');
|
var ex = errnoException(err, 'listen');
|
||||||
self._handle.close();
|
self._handle.close();
|
||||||
self._handle = null;
|
self._handle = null;
|
||||||
process.nextTick(function() {
|
process.nextTick(function() {
|
||||||
@ -1104,9 +1105,15 @@ function listen(self, address, port, addressType, backlog, fd) {
|
|||||||
// not actually bound. That's why we check if the actual port matches what
|
// not actually bound. That's why we check if the actual port matches what
|
||||||
// we requested and if not, raise an error. The exception is when port == 0
|
// we requested and if not, raise an error. The exception is when port == 0
|
||||||
// because that means "any random port".
|
// because that means "any random port".
|
||||||
if (port && handle.getsockname && port != handle.getsockname().port) {
|
if (port && handle.getsockname) {
|
||||||
self.emit('error', errnoException('EADDRINUSE', 'bind'));
|
var out = {};
|
||||||
return;
|
var err = handle.getsockname(out);
|
||||||
|
if (err === 0 && port !== out.port) {
|
||||||
|
err = uv.UV_EADDRINUSE;
|
||||||
|
}
|
||||||
|
if (err) {
|
||||||
|
return self.emit('error', errnoException(err, 'bind'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self._handle = handle;
|
self._handle = handle;
|
||||||
@ -1176,7 +1183,10 @@ Server.prototype.listen = function() {
|
|||||||
|
|
||||||
Server.prototype.address = function() {
|
Server.prototype.address = function() {
|
||||||
if (this._handle && this._handle.getsockname) {
|
if (this._handle && this._handle.getsockname) {
|
||||||
return this._handle.getsockname();
|
var out = {};
|
||||||
|
var err = this._handle.getsockname(out);
|
||||||
|
// TODO(bnoordhuis) Check err and throw?
|
||||||
|
return out;
|
||||||
} else if (this._pipeName) {
|
} else if (this._pipeName) {
|
||||||
return this._pipeName;
|
return this._pipeName;
|
||||||
} else {
|
} else {
|
||||||
@ -1184,14 +1194,14 @@ Server.prototype.address = function() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function onconnection(clientHandle) {
|
function onconnection(err, clientHandle) {
|
||||||
var handle = this;
|
var handle = this;
|
||||||
var self = handle.owner;
|
var self = handle.owner;
|
||||||
|
|
||||||
debug('onconnection');
|
debug('onconnection');
|
||||||
|
|
||||||
if (!clientHandle) {
|
if (err) {
|
||||||
self.emit('error', errnoException(process._errno, 'accept'));
|
self.emit('error', errnoException(err, 'accept'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
12
lib/tty.js
12
lib/tty.js
@ -79,8 +79,9 @@ function WriteStream(fd) {
|
|||||||
writable: true
|
writable: true
|
||||||
});
|
});
|
||||||
|
|
||||||
var winSize = this._handle.getWindowSize();
|
var winSize = [];
|
||||||
if (winSize) {
|
var err = this._handle.getWindowSize(winSize);
|
||||||
|
if (!err) {
|
||||||
this.columns = winSize[0];
|
this.columns = winSize[0];
|
||||||
this.rows = winSize[1];
|
this.rows = winSize[1];
|
||||||
}
|
}
|
||||||
@ -95,9 +96,10 @@ WriteStream.prototype.isTTY = true;
|
|||||||
WriteStream.prototype._refreshSize = function() {
|
WriteStream.prototype._refreshSize = function() {
|
||||||
var oldCols = this.columns;
|
var oldCols = this.columns;
|
||||||
var oldRows = this.rows;
|
var oldRows = this.rows;
|
||||||
var winSize = this._handle.getWindowSize();
|
var winSize = [];
|
||||||
if (!winSize) {
|
var err = this._handle.getWindowSize(winSize);
|
||||||
this.emit('error', errnoException(process._errno, 'getWindowSize'));
|
if (err) {
|
||||||
|
this.emit('error', errnoException(err, 'getWindowSize'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var newCols = winSize[0];
|
var newCols = winSize[0];
|
||||||
|
@ -228,56 +228,11 @@ static Local<Array> HostentToNames(struct hostent* host) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const char* AresErrnoString(int errorno) {
|
|
||||||
switch (errorno) {
|
|
||||||
#define ERRNO_CASE(e) case ARES_##e: return #e;
|
|
||||||
ERRNO_CASE(SUCCESS)
|
|
||||||
ERRNO_CASE(ENODATA)
|
|
||||||
ERRNO_CASE(EFORMERR)
|
|
||||||
ERRNO_CASE(ESERVFAIL)
|
|
||||||
ERRNO_CASE(ENOTFOUND)
|
|
||||||
ERRNO_CASE(ENOTIMP)
|
|
||||||
ERRNO_CASE(EREFUSED)
|
|
||||||
ERRNO_CASE(EBADQUERY)
|
|
||||||
ERRNO_CASE(EBADNAME)
|
|
||||||
ERRNO_CASE(EBADFAMILY)
|
|
||||||
ERRNO_CASE(EBADRESP)
|
|
||||||
ERRNO_CASE(ECONNREFUSED)
|
|
||||||
ERRNO_CASE(ETIMEOUT)
|
|
||||||
ERRNO_CASE(EOF)
|
|
||||||
ERRNO_CASE(EFILE)
|
|
||||||
ERRNO_CASE(ENOMEM)
|
|
||||||
ERRNO_CASE(EDESTRUCTION)
|
|
||||||
ERRNO_CASE(EBADSTR)
|
|
||||||
ERRNO_CASE(EBADFLAGS)
|
|
||||||
ERRNO_CASE(ENONAME)
|
|
||||||
ERRNO_CASE(EBADHINTS)
|
|
||||||
ERRNO_CASE(ENOTINITIALIZED)
|
|
||||||
ERRNO_CASE(ELOADIPHLPAPI)
|
|
||||||
ERRNO_CASE(EADDRGETNETWORKPARAMS)
|
|
||||||
ERRNO_CASE(ECANCELLED)
|
|
||||||
#undef ERRNO_CASE
|
|
||||||
default:
|
|
||||||
assert(0 && "Unhandled c-ares error");
|
|
||||||
return "(UNKNOWN)";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void SetAresErrno(int errorno) {
|
|
||||||
HandleScope scope(node_isolate);
|
|
||||||
Local<Value> key = String::NewSymbol("_errno");
|
|
||||||
Local<Value> value = String::NewSymbol(AresErrnoString(errorno));
|
|
||||||
Local<Object> process = PersistentToLocal(process_p);
|
|
||||||
process->Set(key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class QueryWrap {
|
class QueryWrap {
|
||||||
public:
|
public:
|
||||||
QueryWrap() {
|
QueryWrap(Local<Object> req_wrap_obj) {
|
||||||
HandleScope scope(node_isolate);
|
HandleScope scope(node_isolate);
|
||||||
persistent().Reset(node_isolate, Object::New());
|
persistent().Reset(node_isolate, req_wrap_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~QueryWrap() {
|
virtual ~QueryWrap() {
|
||||||
@ -355,10 +310,10 @@ class QueryWrap {
|
|||||||
|
|
||||||
void ParseError(int status) {
|
void ParseError(int status) {
|
||||||
assert(status != ARES_SUCCESS);
|
assert(status != ARES_SUCCESS);
|
||||||
SetAresErrno(status);
|
|
||||||
|
|
||||||
HandleScope scope(node_isolate);
|
HandleScope scope(node_isolate);
|
||||||
Local<Value> argv[1] = { Integer::New(-1, node_isolate) };
|
Local<Value> argv[] = {
|
||||||
|
Integer::New(status, node_isolate)
|
||||||
|
};
|
||||||
MakeCallback(object(), oncomplete_sym, ARRAY_SIZE(argv), argv);
|
MakeCallback(object(), oncomplete_sym, ARRAY_SIZE(argv), argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -378,6 +333,9 @@ class QueryWrap {
|
|||||||
|
|
||||||
class QueryAWrap: public QueryWrap {
|
class QueryAWrap: public QueryWrap {
|
||||||
public:
|
public:
|
||||||
|
QueryAWrap(Local<Object> req_wrap_obj) : QueryWrap(req_wrap_obj) {
|
||||||
|
}
|
||||||
|
|
||||||
int Send(const char* name) {
|
int Send(const char* name) {
|
||||||
ares_query(ares_channel, name, ns_c_in, ns_t_a, Callback, GetQueryArg());
|
ares_query(ares_channel, name, ns_c_in, ns_t_a, Callback, GetQueryArg());
|
||||||
return 0;
|
return 0;
|
||||||
@ -405,6 +363,9 @@ class QueryAWrap: public QueryWrap {
|
|||||||
|
|
||||||
class QueryAaaaWrap: public QueryWrap {
|
class QueryAaaaWrap: public QueryWrap {
|
||||||
public:
|
public:
|
||||||
|
QueryAaaaWrap(Local<Object> req_wrap_obj) : QueryWrap(req_wrap_obj) {
|
||||||
|
}
|
||||||
|
|
||||||
int Send(const char* name) {
|
int Send(const char* name) {
|
||||||
ares_query(ares_channel,
|
ares_query(ares_channel,
|
||||||
name,
|
name,
|
||||||
@ -437,6 +398,9 @@ class QueryAaaaWrap: public QueryWrap {
|
|||||||
|
|
||||||
class QueryCnameWrap: public QueryWrap {
|
class QueryCnameWrap: public QueryWrap {
|
||||||
public:
|
public:
|
||||||
|
QueryCnameWrap(Local<Object> req_wrap_obj) : QueryWrap(req_wrap_obj) {
|
||||||
|
}
|
||||||
|
|
||||||
int Send(const char* name) {
|
int Send(const char* name) {
|
||||||
ares_query(ares_channel,
|
ares_query(ares_channel,
|
||||||
name,
|
name,
|
||||||
@ -472,6 +436,9 @@ class QueryCnameWrap: public QueryWrap {
|
|||||||
|
|
||||||
class QueryMxWrap: public QueryWrap {
|
class QueryMxWrap: public QueryWrap {
|
||||||
public:
|
public:
|
||||||
|
QueryMxWrap(Local<Object> req_wrap_obj) : QueryWrap(req_wrap_obj) {
|
||||||
|
}
|
||||||
|
|
||||||
int Send(const char* name) {
|
int Send(const char* name) {
|
||||||
ares_query(ares_channel, name, ns_c_in, ns_t_mx, Callback, GetQueryArg());
|
ares_query(ares_channel, name, ns_c_in, ns_t_mx, Callback, GetQueryArg());
|
||||||
return 0;
|
return 0;
|
||||||
@ -511,6 +478,9 @@ class QueryMxWrap: public QueryWrap {
|
|||||||
|
|
||||||
class QueryNsWrap: public QueryWrap {
|
class QueryNsWrap: public QueryWrap {
|
||||||
public:
|
public:
|
||||||
|
QueryNsWrap(Local<Object> req_wrap_obj) : QueryWrap(req_wrap_obj) {
|
||||||
|
}
|
||||||
|
|
||||||
int Send(const char* name) {
|
int Send(const char* name) {
|
||||||
ares_query(ares_channel, name, ns_c_in, ns_t_ns, Callback, GetQueryArg());
|
ares_query(ares_channel, name, ns_c_in, ns_t_ns, Callback, GetQueryArg());
|
||||||
return 0;
|
return 0;
|
||||||
@ -536,6 +506,9 @@ class QueryNsWrap: public QueryWrap {
|
|||||||
|
|
||||||
class QueryTxtWrap: public QueryWrap {
|
class QueryTxtWrap: public QueryWrap {
|
||||||
public:
|
public:
|
||||||
|
QueryTxtWrap(Local<Object> req_wrap_obj) : QueryWrap(req_wrap_obj) {
|
||||||
|
}
|
||||||
|
|
||||||
int Send(const char* name) {
|
int Send(const char* name) {
|
||||||
ares_query(ares_channel, name, ns_c_in, ns_t_txt, Callback, GetQueryArg());
|
ares_query(ares_channel, name, ns_c_in, ns_t_txt, Callback, GetQueryArg());
|
||||||
return 0;
|
return 0;
|
||||||
@ -568,6 +541,9 @@ class QueryTxtWrap: public QueryWrap {
|
|||||||
|
|
||||||
class QuerySrvWrap: public QueryWrap {
|
class QuerySrvWrap: public QueryWrap {
|
||||||
public:
|
public:
|
||||||
|
QuerySrvWrap(Local<Object> req_wrap_obj) : QueryWrap(req_wrap_obj) {
|
||||||
|
}
|
||||||
|
|
||||||
int Send(const char* name) {
|
int Send(const char* name) {
|
||||||
ares_query(ares_channel,
|
ares_query(ares_channel,
|
||||||
name,
|
name,
|
||||||
@ -617,6 +593,9 @@ class QuerySrvWrap: public QueryWrap {
|
|||||||
|
|
||||||
class QueryNaptrWrap: public QueryWrap {
|
class QueryNaptrWrap: public QueryWrap {
|
||||||
public:
|
public:
|
||||||
|
QueryNaptrWrap(Local<Object> req_wrap_obj) : QueryWrap(req_wrap_obj) {
|
||||||
|
}
|
||||||
|
|
||||||
int Send(const char* name) {
|
int Send(const char* name) {
|
||||||
ares_query(ares_channel,
|
ares_query(ares_channel,
|
||||||
name,
|
name,
|
||||||
@ -679,18 +658,21 @@ class QueryNaptrWrap: public QueryWrap {
|
|||||||
|
|
||||||
class GetHostByAddrWrap: public QueryWrap {
|
class GetHostByAddrWrap: public QueryWrap {
|
||||||
public:
|
public:
|
||||||
|
GetHostByAddrWrap(Local<Object> req_wrap_obj) : QueryWrap(req_wrap_obj) {
|
||||||
|
}
|
||||||
|
|
||||||
int Send(const char* name) {
|
int Send(const char* name) {
|
||||||
int length, family;
|
int length, family;
|
||||||
char address_buffer[sizeof(struct in6_addr)];
|
char address_buffer[sizeof(struct in6_addr)];
|
||||||
|
|
||||||
if (uv_inet_pton(AF_INET, name, &address_buffer).code == UV_OK) {
|
if (uv_inet_pton(AF_INET, name, &address_buffer) == 0) {
|
||||||
length = sizeof(struct in_addr);
|
length = sizeof(struct in_addr);
|
||||||
family = AF_INET;
|
family = AF_INET;
|
||||||
} else if (uv_inet_pton(AF_INET6, name, &address_buffer).code == UV_OK) {
|
} else if (uv_inet_pton(AF_INET6, name, &address_buffer) == 0) {
|
||||||
length = sizeof(struct in6_addr);
|
length = sizeof(struct in6_addr);
|
||||||
family = AF_INET6;
|
family = AF_INET6;
|
||||||
} else {
|
} else {
|
||||||
return ARES_ENOTIMP;
|
return UV_EINVAL; // So errnoException() reports a proper error.
|
||||||
}
|
}
|
||||||
|
|
||||||
ares_gethostbyaddr(ares_channel,
|
ares_gethostbyaddr(ares_channel,
|
||||||
@ -713,6 +695,9 @@ class GetHostByAddrWrap: public QueryWrap {
|
|||||||
|
|
||||||
class GetHostByNameWrap: public QueryWrap {
|
class GetHostByNameWrap: public QueryWrap {
|
||||||
public:
|
public:
|
||||||
|
GetHostByNameWrap(Local<Object> req_wrap_obj) : QueryWrap(req_wrap_obj) {
|
||||||
|
}
|
||||||
|
|
||||||
int Send(const char* name, int family) {
|
int Send(const char* name, int family) {
|
||||||
ares_gethostbyname(ares_channel, name, family, Callback, GetQueryArg());
|
ares_gethostbyname(ares_channel, name, family, Callback, GetQueryArg());
|
||||||
return 0;
|
return 0;
|
||||||
@ -735,26 +720,27 @@ static void Query(const FunctionCallbackInfo<Value>& args) {
|
|||||||
HandleScope scope(node_isolate);
|
HandleScope scope(node_isolate);
|
||||||
|
|
||||||
assert(!args.IsConstructCall());
|
assert(!args.IsConstructCall());
|
||||||
assert(args.Length() >= 2);
|
assert(args[0]->IsObject());
|
||||||
assert(args[1]->IsFunction());
|
assert(args[1]->IsString());
|
||||||
|
assert(args[2]->IsFunction());
|
||||||
|
|
||||||
Wrap* wrap = new Wrap();
|
Local<Object> req_wrap_obj = args[0].As<Object>();
|
||||||
wrap->SetOnComplete(args[1]);
|
Local<String> string = args[1].As<String>();
|
||||||
|
Local<Function> callback = args[2].As<Function>();
|
||||||
|
|
||||||
|
Wrap* wrap = new Wrap(req_wrap_obj);
|
||||||
|
wrap->SetOnComplete(callback);
|
||||||
|
|
||||||
// We must cache the wrap's js object here, because cares might make the
|
// We must cache the wrap's js object here, because cares might make the
|
||||||
// callback from the wrap->Send stack. This will destroy the wrap's internal
|
// callback from the wrap->Send stack. This will destroy the wrap's internal
|
||||||
// object reference, causing wrap->object() to return an empty handle.
|
// object reference, causing wrap->object() to return an empty handle.
|
||||||
Local<Object> object = Local<Object>::New(node_isolate, wrap->persistent());
|
Local<Object> object = Local<Object>::New(node_isolate, wrap->persistent());
|
||||||
|
|
||||||
String::Utf8Value name(args[0]);
|
String::Utf8Value name(string);
|
||||||
|
int err = wrap->Send(*name);
|
||||||
|
if (err) delete wrap;
|
||||||
|
|
||||||
int r = wrap->Send(*name);
|
args.GetReturnValue().Set(err);
|
||||||
if (r) {
|
|
||||||
SetAresErrno(r);
|
|
||||||
delete wrap;
|
|
||||||
} else {
|
|
||||||
args.GetReturnValue().Set(object);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -763,27 +749,29 @@ static void QueryWithFamily(const FunctionCallbackInfo<Value>& args) {
|
|||||||
HandleScope scope(node_isolate);
|
HandleScope scope(node_isolate);
|
||||||
|
|
||||||
assert(!args.IsConstructCall());
|
assert(!args.IsConstructCall());
|
||||||
assert(args.Length() >= 3);
|
assert(args[0]->IsObject());
|
||||||
assert(args[2]->IsFunction());
|
assert(args[1]->IsString());
|
||||||
|
assert(args[2]->IsInt32());
|
||||||
|
assert(args[3]->IsFunction());
|
||||||
|
|
||||||
Wrap* wrap = new Wrap();
|
Local<Object> req_wrap_obj = args[0].As<Object>();
|
||||||
wrap->SetOnComplete(args[2]);
|
Local<String> string = args[1].As<String>();
|
||||||
|
int family = args[2]->Int32Value();
|
||||||
|
Local<Function> callback = args[3].As<Function>();
|
||||||
|
|
||||||
|
Wrap* wrap = new Wrap(req_wrap_obj);
|
||||||
|
wrap->SetOnComplete(callback);
|
||||||
|
|
||||||
// We must cache the wrap's js object here, because cares might make the
|
// We must cache the wrap's js object here, because cares might make the
|
||||||
// callback from the wrap->Send stack. This will destroy the wrap's internal
|
// callback from the wrap->Send stack. This will destroy the wrap's internal
|
||||||
// object reference, causing wrap->object() to return an empty handle.
|
// object reference, causing wrap->object() to return an empty handle.
|
||||||
Local<Object> object = Local<Object>::New(node_isolate, wrap->persistent());
|
Local<Object> object = Local<Object>::New(node_isolate, wrap->persistent());
|
||||||
|
|
||||||
String::Utf8Value name(args[0]);
|
String::Utf8Value name(string);
|
||||||
int family = args[1]->Int32Value();
|
int err = wrap->Send(*name, family);
|
||||||
|
if (err) delete wrap;
|
||||||
|
|
||||||
int r = wrap->Send(*name, family);
|
args.GetReturnValue().Set(err);
|
||||||
if (r) {
|
|
||||||
SetAresErrno(r);
|
|
||||||
delete wrap;
|
|
||||||
} else {
|
|
||||||
args.GetReturnValue().Set(object);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -792,13 +780,12 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
|
|||||||
|
|
||||||
GetAddrInfoReqWrap* req_wrap = (GetAddrInfoReqWrap*) req->data;
|
GetAddrInfoReqWrap* req_wrap = (GetAddrInfoReqWrap*) req->data;
|
||||||
|
|
||||||
Local<Value> argv[1];
|
Local<Value> argv[] = {
|
||||||
|
Integer::New(status, node_isolate),
|
||||||
|
Null(node_isolate)
|
||||||
|
};
|
||||||
|
|
||||||
if (status) {
|
if (status == 0) {
|
||||||
// Error
|
|
||||||
SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
argv[0] = Null(node_isolate);
|
|
||||||
} else {
|
|
||||||
// Success
|
// Success
|
||||||
struct addrinfo *address;
|
struct addrinfo *address;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
@ -826,11 +813,11 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
|
|||||||
if (address->ai_family == AF_INET) {
|
if (address->ai_family == AF_INET) {
|
||||||
// Juggle pointers
|
// Juggle pointers
|
||||||
addr = (char*) &((struct sockaddr_in*) address->ai_addr)->sin_addr;
|
addr = (char*) &((struct sockaddr_in*) address->ai_addr)->sin_addr;
|
||||||
uv_err_t err = uv_inet_ntop(address->ai_family,
|
int err = uv_inet_ntop(address->ai_family,
|
||||||
addr,
|
addr,
|
||||||
ip,
|
ip,
|
||||||
INET6_ADDRSTRLEN);
|
INET6_ADDRSTRLEN);
|
||||||
if (err.code != UV_OK)
|
if (err)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Create JavaScript string
|
// Create JavaScript string
|
||||||
@ -852,11 +839,11 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
|
|||||||
if (address->ai_family == AF_INET6) {
|
if (address->ai_family == AF_INET6) {
|
||||||
// Juggle pointers
|
// Juggle pointers
|
||||||
addr = (char*) &((struct sockaddr_in6*) address->ai_addr)->sin6_addr;
|
addr = (char*) &((struct sockaddr_in6*) address->ai_addr)->sin6_addr;
|
||||||
uv_err_t err = uv_inet_ntop(address->ai_family,
|
int err = uv_inet_ntop(address->ai_family,
|
||||||
addr,
|
addr,
|
||||||
ip,
|
ip,
|
||||||
INET6_ADDRSTRLEN);
|
INET6_ADDRSTRLEN);
|
||||||
if (err.code != UV_OK)
|
if (err)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Create JavaScript string
|
// Create JavaScript string
|
||||||
@ -870,7 +857,7 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
argv[0] = results;
|
argv[1] = results;
|
||||||
}
|
}
|
||||||
|
|
||||||
uv_freeaddrinfo(res);
|
uv_freeaddrinfo(res);
|
||||||
@ -889,9 +876,9 @@ static void IsIP(const FunctionCallbackInfo<Value>& args) {
|
|||||||
char address_buffer[sizeof(struct in6_addr)];
|
char address_buffer[sizeof(struct in6_addr)];
|
||||||
|
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
if (uv_inet_pton(AF_INET, *ip, &address_buffer).code == UV_OK)
|
if (uv_inet_pton(AF_INET, *ip, &address_buffer) == 0)
|
||||||
rc = 4;
|
rc = 4;
|
||||||
else if (uv_inet_pton(AF_INET6, *ip, &address_buffer).code == UV_OK)
|
else if (uv_inet_pton(AF_INET6, *ip, &address_buffer) == 0)
|
||||||
rc = 6;
|
rc = 6;
|
||||||
|
|
||||||
args.GetReturnValue().Set(rc);
|
args.GetReturnValue().Set(rc);
|
||||||
@ -901,42 +888,45 @@ static void IsIP(const FunctionCallbackInfo<Value>& args) {
|
|||||||
static void GetAddrInfo(const FunctionCallbackInfo<Value>& args) {
|
static void GetAddrInfo(const FunctionCallbackInfo<Value>& args) {
|
||||||
HandleScope scope(node_isolate);
|
HandleScope scope(node_isolate);
|
||||||
|
|
||||||
String::Utf8Value hostname(args[0]);
|
assert(args[0]->IsObject());
|
||||||
|
assert(args[1]->IsString());
|
||||||
|
assert(args[2]->IsInt32());
|
||||||
|
Local<Object> req_wrap_obj = args[0].As<Object>();
|
||||||
|
String::Utf8Value hostname(args[1]);
|
||||||
|
|
||||||
int fam = AF_UNSPEC;
|
int family;
|
||||||
if (args[1]->IsInt32()) {
|
switch (args[2]->Int32Value()) {
|
||||||
switch (args[1]->Int32Value()) {
|
case 0:
|
||||||
case 6:
|
family = AF_UNSPEC;
|
||||||
fam = AF_INET6;
|
break;
|
||||||
break;
|
case 4:
|
||||||
|
family = AF_INET;
|
||||||
case 4:
|
break;
|
||||||
fam = AF_INET;
|
case 6:
|
||||||
break;
|
family = AF_INET6;
|
||||||
}
|
break;
|
||||||
|
default:
|
||||||
|
assert(0 && "bad address family");
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
GetAddrInfoReqWrap* req_wrap = new GetAddrInfoReqWrap();
|
GetAddrInfoReqWrap* req_wrap = new GetAddrInfoReqWrap(req_wrap_obj);
|
||||||
|
|
||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
memset(&hints, 0, sizeof(struct addrinfo));
|
memset(&hints, 0, sizeof(struct addrinfo));
|
||||||
hints.ai_family = fam;
|
hints.ai_family = family;
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
|
||||||
int r = uv_getaddrinfo(uv_default_loop(),
|
int err = uv_getaddrinfo(uv_default_loop(),
|
||||||
&req_wrap->req_,
|
&req_wrap->req_,
|
||||||
AfterGetAddrInfo,
|
AfterGetAddrInfo,
|
||||||
*hostname,
|
*hostname,
|
||||||
NULL,
|
NULL,
|
||||||
&hints);
|
&hints);
|
||||||
req_wrap->Dispatched();
|
req_wrap->Dispatched();
|
||||||
|
if (err) delete req_wrap;
|
||||||
|
|
||||||
if (r) {
|
args.GetReturnValue().Set(err);
|
||||||
SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
delete req_wrap;
|
|
||||||
} else {
|
|
||||||
args.GetReturnValue().Set(req_wrap->persistent());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -956,8 +946,8 @@ static void GetServers(const FunctionCallbackInfo<Value>& args) {
|
|||||||
char ip[INET6_ADDRSTRLEN];
|
char ip[INET6_ADDRSTRLEN];
|
||||||
|
|
||||||
const void* caddr = static_cast<const void*>(&cur->addr);
|
const void* caddr = static_cast<const void*>(&cur->addr);
|
||||||
uv_err_t err = uv_inet_ntop(cur->family, caddr, ip, sizeof(ip));
|
int err = uv_inet_ntop(cur->family, caddr, ip, sizeof(ip));
|
||||||
assert(err.code == UV_OK);
|
assert(err == 0);
|
||||||
|
|
||||||
Local<String> addr = String::New(ip);
|
Local<String> addr = String::New(ip);
|
||||||
server_array->Set(i, addr);
|
server_array->Set(i, addr);
|
||||||
@ -986,7 +976,7 @@ static void SetServers(const FunctionCallbackInfo<Value>& args) {
|
|||||||
ares_addr_node* servers = new ares_addr_node[len];
|
ares_addr_node* servers = new ares_addr_node[len];
|
||||||
ares_addr_node* last = NULL;
|
ares_addr_node* last = NULL;
|
||||||
|
|
||||||
uv_err_t uv_ret;
|
int err;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < len; i++) {
|
for (uint32_t i = 0; i < len; i++) {
|
||||||
assert(arr->Get(i)->IsArray());
|
assert(arr->Get(i)->IsArray());
|
||||||
@ -1004,18 +994,18 @@ static void SetServers(const FunctionCallbackInfo<Value>& args) {
|
|||||||
switch (fam) {
|
switch (fam) {
|
||||||
case 4:
|
case 4:
|
||||||
cur->family = AF_INET;
|
cur->family = AF_INET;
|
||||||
uv_ret = uv_inet_pton(AF_INET, *ip, &cur->addr);
|
err = uv_inet_pton(AF_INET, *ip, &cur->addr);
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
cur->family = AF_INET6;
|
cur->family = AF_INET6;
|
||||||
uv_ret = uv_inet_pton(AF_INET6, *ip, &cur->addr);
|
err = uv_inet_pton(AF_INET6, *ip, &cur->addr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0 && "Bad address family.");
|
assert(0 && "Bad address family.");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uv_ret.code != UV_OK)
|
if (err)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
cur->next = NULL;
|
cur->next = NULL;
|
||||||
@ -1026,16 +1016,14 @@ static void SetServers(const FunctionCallbackInfo<Value>& args) {
|
|||||||
last = cur;
|
last = cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
int r;
|
if (err == 0)
|
||||||
|
err = ares_set_servers(ares_channel, &servers[0]);
|
||||||
if (uv_ret.code == UV_OK)
|
|
||||||
r = ares_set_servers(ares_channel, &servers[0]);
|
|
||||||
else
|
else
|
||||||
r = ARES_EBADSTR;
|
err = ARES_EBADSTR;
|
||||||
|
|
||||||
delete[] servers;
|
delete[] servers;
|
||||||
|
|
||||||
args.GetReturnValue().Set(r);
|
args.GetReturnValue().Set(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -108,18 +108,20 @@ void FSEventWrap::Start(const FunctionCallbackInfo<Value>& args) {
|
|||||||
|
|
||||||
String::Utf8Value path(args[0]);
|
String::Utf8Value path(args[0]);
|
||||||
|
|
||||||
int r = uv_fs_event_init(uv_default_loop(), &wrap->handle_, *path, OnEvent, 0);
|
int err = uv_fs_event_init(uv_default_loop(),
|
||||||
if (r == 0) {
|
&wrap->handle_,
|
||||||
|
*path,
|
||||||
|
OnEvent,
|
||||||
|
0);
|
||||||
|
if (err == 0) {
|
||||||
// Check for persistent argument
|
// Check for persistent argument
|
||||||
if (!args[1]->IsTrue()) {
|
if (!args[1]->IsTrue()) {
|
||||||
uv_unref(reinterpret_cast<uv_handle_t*>(&wrap->handle_));
|
uv_unref(reinterpret_cast<uv_handle_t*>(&wrap->handle_));
|
||||||
}
|
}
|
||||||
wrap->initialized_ = true;
|
wrap->initialized_ = true;
|
||||||
} else {
|
|
||||||
SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
args.GetReturnValue().Set(r);
|
args.GetReturnValue().Set(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -144,7 +146,6 @@ void FSEventWrap::OnEvent(uv_fs_event_t* handle, const char* filename,
|
|||||||
// assumption that a rename implicitly means an attribute change. Not too
|
// assumption that a rename implicitly means an attribute change. Not too
|
||||||
// unreasonable, right? Still, we should revisit this before v1.0.
|
// unreasonable, right? Still, we should revisit this before v1.0.
|
||||||
if (status) {
|
if (status) {
|
||||||
SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
eventStr = String::Empty(node_isolate);
|
eventStr = String::Empty(node_isolate);
|
||||||
}
|
}
|
||||||
else if (events & UV_RENAME) {
|
else if (events & UV_RENAME) {
|
||||||
|
70
src/node.cc
70
src/node.cc
@ -774,22 +774,6 @@ Local<Value> ErrnoException(int errorno,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const char* get_uv_errno_string(int errorno) {
|
|
||||||
uv_err_t err;
|
|
||||||
memset(&err, 0, sizeof err);
|
|
||||||
err.code = (uv_err_code)errorno;
|
|
||||||
return uv_err_name(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static const char* get_uv_errno_message(int errorno) {
|
|
||||||
uv_err_t err;
|
|
||||||
memset(&err, 0, sizeof err);
|
|
||||||
err.code = (uv_err_code)errorno;
|
|
||||||
return uv_strerror(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// hack alert! copy of ErrnoException, tuned for uv errors
|
// hack alert! copy of ErrnoException, tuned for uv errors
|
||||||
Local<Value> UVException(int errorno,
|
Local<Value> UVException(int errorno,
|
||||||
const char *syscall,
|
const char *syscall,
|
||||||
@ -803,9 +787,9 @@ Local<Value> UVException(int errorno,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!msg || !msg[0])
|
if (!msg || !msg[0])
|
||||||
msg = get_uv_errno_message(errorno);
|
msg = uv_strerror(errorno);
|
||||||
|
|
||||||
Local<String> estring = String::NewSymbol(get_uv_errno_string(errorno));
|
Local<String> estring = String::NewSymbol(uv_err_name(errorno));
|
||||||
Local<String> message = String::NewSymbol(msg);
|
Local<String> message = String::NewSymbol(msg);
|
||||||
Local<String> cons1 = String::Concat(estring, String::NewSymbol(", "));
|
Local<String> cons1 = String::Concat(estring, String::NewSymbol(", "));
|
||||||
Local<String> cons2 = String::Concat(cons1, message);
|
Local<String> cons2 = String::Concat(cons1, message);
|
||||||
@ -1080,25 +1064,6 @@ MakeCallback(const Handle<Object> object,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SetErrno(uv_err_t err) {
|
|
||||||
HandleScope scope(node_isolate);
|
|
||||||
Local<Object> process = PersistentToLocal(process_p);
|
|
||||||
|
|
||||||
static Cached<String> errno_symbol;
|
|
||||||
if (errno_symbol.IsEmpty()) {
|
|
||||||
errno_symbol = String::New("_errno");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err.code == UV_UNKNOWN) {
|
|
||||||
char errno_buf[100];
|
|
||||||
snprintf(errno_buf, 100, "Unknown system errno %d", err.sys_errno_);
|
|
||||||
process->Set(errno_symbol, String::New(errno_buf));
|
|
||||||
} else {
|
|
||||||
process->Set(errno_symbol, String::NewSymbol(uv_err_name(err)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
enum encoding ParseEncoding(Handle<Value> encoding_v, enum encoding _default) {
|
enum encoding ParseEncoding(Handle<Value> encoding_v, enum encoding _default) {
|
||||||
HandleScope scope(node_isolate);
|
HandleScope scope(node_isolate);
|
||||||
|
|
||||||
@ -1356,11 +1321,9 @@ static void Chdir(const FunctionCallbackInfo<Value>& args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String::Utf8Value path(args[0]);
|
String::Utf8Value path(args[0]);
|
||||||
|
int err = uv_chdir(*path);
|
||||||
uv_err_t r = uv_chdir(*path);
|
if (err) {
|
||||||
|
return ThrowUVException(err, "uv_chdir");
|
||||||
if (r.code != UV_OK) {
|
|
||||||
return ThrowUVException(r.code, "uv_chdir");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1374,9 +1337,9 @@ static void Cwd(const FunctionCallbackInfo<Value>& args) {
|
|||||||
char buf[PATH_MAX + 1];
|
char buf[PATH_MAX + 1];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uv_err_t r = uv_cwd(buf, ARRAY_SIZE(buf) - 1);
|
int err = uv_cwd(buf, ARRAY_SIZE(buf) - 1);
|
||||||
if (r.code != UV_OK) {
|
if (err) {
|
||||||
return ThrowUVException(r.code, "uv_cwd");
|
return ThrowUVException(err, "uv_cwd");
|
||||||
}
|
}
|
||||||
|
|
||||||
buf[ARRAY_SIZE(buf) - 1] = '\0';
|
buf[ARRAY_SIZE(buf) - 1] = '\0';
|
||||||
@ -1698,7 +1661,7 @@ void Exit(const FunctionCallbackInfo<Value>& args) {
|
|||||||
static void Uptime(const FunctionCallbackInfo<Value>& args) {
|
static void Uptime(const FunctionCallbackInfo<Value>& args) {
|
||||||
HandleScope scope(node_isolate);
|
HandleScope scope(node_isolate);
|
||||||
double uptime;
|
double uptime;
|
||||||
if (uv_uptime(&uptime).code != UV_OK) return;
|
if (uv_uptime(&uptime)) return;
|
||||||
args.GetReturnValue().Set(uptime - prog_start_time);
|
args.GetReturnValue().Set(uptime - prog_start_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1708,10 +1671,9 @@ void MemoryUsage(const FunctionCallbackInfo<Value>& args) {
|
|||||||
|
|
||||||
size_t rss;
|
size_t rss;
|
||||||
|
|
||||||
uv_err_t err = uv_resident_set_memory(&rss);
|
int err = uv_resident_set_memory(&rss);
|
||||||
|
if (err) {
|
||||||
if (err.code != UV_OK) {
|
return ThrowUVException(err, "uv_resident_set_memory");
|
||||||
return ThrowUVException(err.code, "uv_resident_set_memory");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Local<Object> info = Object::New();
|
Local<Object> info = Object::New();
|
||||||
@ -1747,12 +1709,8 @@ void Kill(const FunctionCallbackInfo<Value>& args) {
|
|||||||
|
|
||||||
int pid = args[0]->IntegerValue();
|
int pid = args[0]->IntegerValue();
|
||||||
int sig = args[1]->Int32Value();
|
int sig = args[1]->Int32Value();
|
||||||
uv_err_t err = uv_kill(pid, sig);
|
int err = uv_kill(pid, sig);
|
||||||
|
args.GetReturnValue().Set(err);
|
||||||
if (err.code != UV_OK) {
|
|
||||||
SetErrno(err);
|
|
||||||
args.GetReturnValue().Set(-1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// used in Hrtime() below
|
// used in Hrtime() below
|
||||||
|
@ -239,8 +239,6 @@ node_module_struct* get_builtin_module(const char *name);
|
|||||||
*/
|
*/
|
||||||
NODE_EXTERN void AtExit(void (*cb)(void* arg), void* arg = 0);
|
NODE_EXTERN void AtExit(void (*cb)(void* arg), void* arg = 0);
|
||||||
|
|
||||||
NODE_EXTERN void SetErrno(uv_err_t err);
|
|
||||||
|
|
||||||
} // namespace node
|
} // namespace node
|
||||||
|
|
||||||
#endif // SRC_NODE_H_
|
#endif // SRC_NODE_H_
|
||||||
|
16
src/node.js
16
src/node.js
@ -626,23 +626,23 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
process.kill = function(pid, sig) {
|
process.kill = function(pid, sig) {
|
||||||
var r;
|
var err;
|
||||||
|
|
||||||
// preserve null signal
|
// preserve null signal
|
||||||
if (0 === sig) {
|
if (0 === sig) {
|
||||||
r = process._kill(pid, 0);
|
err = process._kill(pid, 0);
|
||||||
} else {
|
} else {
|
||||||
sig = sig || 'SIGTERM';
|
sig = sig || 'SIGTERM';
|
||||||
if (startup.lazyConstants()[sig]) {
|
if (startup.lazyConstants()[sig]) {
|
||||||
r = process._kill(pid, startup.lazyConstants()[sig]);
|
err = process._kill(pid, startup.lazyConstants()[sig]);
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Unknown signal: ' + sig);
|
throw new Error('Unknown signal: ' + sig);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r) {
|
if (err) {
|
||||||
var errnoException = NativeModule.require('util')._errnoException;
|
var errnoException = NativeModule.require('util')._errnoException;
|
||||||
throw errnoException(process._errno, 'kill');
|
throw errnoException(err, 'kill');
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -673,11 +673,11 @@
|
|||||||
wrap.onsignal = function() { process.emit(type); };
|
wrap.onsignal = function() { process.emit(type); };
|
||||||
|
|
||||||
var signum = startup.lazyConstants()[type];
|
var signum = startup.lazyConstants()[type];
|
||||||
var r = wrap.start(signum);
|
var err = wrap.start(signum);
|
||||||
if (r) {
|
if (err) {
|
||||||
wrap.close();
|
wrap.close();
|
||||||
var errnoException = NativeModule.require('util')._errnoException;
|
var errnoException = NativeModule.require('util')._errnoException;
|
||||||
throw errnoException(process._errno, 'uv_signal_start');
|
throw errnoException(err, 'uv_signal_start');
|
||||||
}
|
}
|
||||||
|
|
||||||
signalWraps[type] = wrap;
|
signalWraps[type] = wrap;
|
||||||
|
@ -104,17 +104,12 @@ static void After(uv_fs_t *req) {
|
|||||||
// (Feel free to increase this if you need more)
|
// (Feel free to increase this if you need more)
|
||||||
Local<Value> argv[2];
|
Local<Value> argv[2];
|
||||||
|
|
||||||
// NOTE: This may be needed to be changed if something returns a -1
|
if (req->result < 0) {
|
||||||
// for a success, which is possible.
|
|
||||||
if (req->result == -1) {
|
|
||||||
// If the request doesn't have a path parameter set.
|
// If the request doesn't have a path parameter set.
|
||||||
|
if (req->path == NULL) {
|
||||||
if (!req->path) {
|
argv[0] = UVException(req->result, NULL, req_wrap->syscall());
|
||||||
argv[0] = UVException(req->errorno,
|
|
||||||
NULL,
|
|
||||||
req_wrap->syscall());
|
|
||||||
} else {
|
} else {
|
||||||
argv[0] = UVException(req->errorno,
|
argv[0] = UVException(req->result,
|
||||||
NULL,
|
NULL,
|
||||||
req_wrap->syscall(),
|
req_wrap->syscall(),
|
||||||
static_cast<const char*>(req->path));
|
static_cast<const char*>(req->path));
|
||||||
@ -225,30 +220,29 @@ struct fs_req_wrap {
|
|||||||
|
|
||||||
#define ASYNC_CALL(func, callback, ...) \
|
#define ASYNC_CALL(func, callback, ...) \
|
||||||
FSReqWrap* req_wrap = new FSReqWrap(#func); \
|
FSReqWrap* req_wrap = new FSReqWrap(#func); \
|
||||||
int r = uv_fs_##func(uv_default_loop(), &req_wrap->req_, \
|
int err = uv_fs_ ## func(uv_default_loop(), &req_wrap->req_, \
|
||||||
__VA_ARGS__, After); \
|
__VA_ARGS__, After); \
|
||||||
req_wrap->object()->Set(oncomplete_sym, callback); \
|
req_wrap->object()->Set(oncomplete_sym, callback); \
|
||||||
req_wrap->Dispatched(); \
|
req_wrap->Dispatched(); \
|
||||||
if (r < 0) { \
|
if (err < 0) { \
|
||||||
uv_fs_t* req = &req_wrap->req_; \
|
uv_fs_t* req = &req_wrap->req_; \
|
||||||
req->result = r; \
|
req->result = err; \
|
||||||
req->path = NULL; \
|
req->path = NULL; \
|
||||||
req->errorno = uv_last_error(uv_default_loop()).code; \
|
|
||||||
After(req); \
|
After(req); \
|
||||||
} \
|
} \
|
||||||
args.GetReturnValue().Set(req_wrap->persistent());
|
args.GetReturnValue().Set(req_wrap->persistent());
|
||||||
|
|
||||||
#define SYNC_CALL(func, path, ...) \
|
#define SYNC_CALL(func, path, ...) \
|
||||||
fs_req_wrap req_wrap; \
|
fs_req_wrap req_wrap; \
|
||||||
int result = uv_fs_##func(uv_default_loop(), &req_wrap.req, __VA_ARGS__, NULL); \
|
int err = uv_fs_ ## func(uv_default_loop(), \
|
||||||
if (result < 0) { \
|
&req_wrap.req, \
|
||||||
int code = uv_last_error(uv_default_loop()).code; \
|
__VA_ARGS__, \
|
||||||
return ThrowUVException(code, #func, "", path); \
|
NULL); \
|
||||||
}
|
if (err < 0) return ThrowUVException(err, #func, NULL, path); \
|
||||||
|
|
||||||
#define SYNC_REQ req_wrap.req
|
#define SYNC_REQ req_wrap.req
|
||||||
|
|
||||||
#define SYNC_RESULT result
|
#define SYNC_RESULT err
|
||||||
|
|
||||||
|
|
||||||
static void Close(const FunctionCallbackInfo<Value>& args) {
|
static void Close(const FunctionCallbackInfo<Value>& args) {
|
||||||
|
@ -131,8 +131,8 @@ static void GetCPUInfo(const FunctionCallbackInfo<Value>& args) {
|
|||||||
uv_cpu_info_t* cpu_infos;
|
uv_cpu_info_t* cpu_infos;
|
||||||
int count, i;
|
int count, i;
|
||||||
|
|
||||||
uv_err_t err = uv_cpu_info(&cpu_infos, &count);
|
int err = uv_cpu_info(&cpu_infos, &count);
|
||||||
if (err.code != UV_OK) return;
|
if (err) return;
|
||||||
|
|
||||||
Local<Array> cpus = Array::New();
|
Local<Array> cpus = Array::New();
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
@ -180,9 +180,8 @@ static void GetTotalMemory(const FunctionCallbackInfo<Value>& args) {
|
|||||||
static void GetUptime(const FunctionCallbackInfo<Value>& args) {
|
static void GetUptime(const FunctionCallbackInfo<Value>& args) {
|
||||||
HandleScope scope(node_isolate);
|
HandleScope scope(node_isolate);
|
||||||
double uptime;
|
double uptime;
|
||||||
uv_err_t err = uv_uptime(&uptime);
|
int err = uv_uptime(&uptime);
|
||||||
if (err.code != UV_OK) return;
|
if (err == 0) args.GetReturnValue().Set(uptime);
|
||||||
args.GetReturnValue().Set(uptime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -208,9 +207,9 @@ static void GetInterfaceAddresses(const FunctionCallbackInfo<Value>& args) {
|
|||||||
Local<String> name, family;
|
Local<String> name, family;
|
||||||
Local<Array> ifarr;
|
Local<Array> ifarr;
|
||||||
|
|
||||||
uv_err_t err = uv_interface_addresses(&interfaces, &count);
|
int err = uv_interface_addresses(&interfaces, &count);
|
||||||
if (err.code != UV_OK) {
|
if (err) {
|
||||||
return ThrowUVException(err.code, "uv_interface_addresses");
|
return ThrowUVException(err, "uv_interface_addresses");
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = Object::New();
|
ret = Object::New();
|
||||||
|
@ -86,9 +86,6 @@ void StatWatcher::Callback(uv_fs_poll_t* handle,
|
|||||||
argv[0] = BuildStatsObject(curr);
|
argv[0] = BuildStatsObject(curr);
|
||||||
argv[1] = BuildStatsObject(prev);
|
argv[1] = BuildStatsObject(prev);
|
||||||
argv[2] = Integer::New(status, node_isolate);
|
argv[2] = Integer::New(status, node_isolate);
|
||||||
if (status == -1) {
|
|
||||||
SetErrno(uv_last_error(wrap->watcher_->loop));
|
|
||||||
}
|
|
||||||
if (onchange_sym.IsEmpty()) {
|
if (onchange_sym.IsEmpty()) {
|
||||||
onchange_sym = String::New("onchange");
|
onchange_sym = String::New("onchange");
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@ using v8::Object;
|
|||||||
using v8::Persistent;
|
using v8::Persistent;
|
||||||
using v8::PropertyAttribute;
|
using v8::PropertyAttribute;
|
||||||
using v8::String;
|
using v8::String;
|
||||||
|
using v8::Undefined;
|
||||||
using v8::Value;
|
using v8::Value;
|
||||||
|
|
||||||
static Persistent<Function> pipeConstructor;
|
static Persistent<Function> pipeConstructor;
|
||||||
@ -145,13 +146,8 @@ void PipeWrap::Bind(const FunctionCallbackInfo<Value>& args) {
|
|||||||
UNWRAP(PipeWrap)
|
UNWRAP(PipeWrap)
|
||||||
|
|
||||||
String::AsciiValue name(args[0]);
|
String::AsciiValue name(args[0]);
|
||||||
|
int err = uv_pipe_bind(&wrap->handle_, *name);
|
||||||
int r = uv_pipe_bind(&wrap->handle_, *name);
|
args.GetReturnValue().Set(err);
|
||||||
|
|
||||||
// Error starting the pipe.
|
|
||||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
|
|
||||||
args.GetReturnValue().Set(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -174,15 +170,10 @@ void PipeWrap::Listen(const FunctionCallbackInfo<Value>& args) {
|
|||||||
UNWRAP(PipeWrap)
|
UNWRAP(PipeWrap)
|
||||||
|
|
||||||
int backlog = args[0]->Int32Value();
|
int backlog = args[0]->Int32Value();
|
||||||
|
int err = uv_listen(reinterpret_cast<uv_stream_t*>(&wrap->handle_),
|
||||||
int r = uv_listen(reinterpret_cast<uv_stream_t*>(&wrap->handle_),
|
backlog,
|
||||||
backlog,
|
OnConnection);
|
||||||
OnConnection);
|
args.GetReturnValue().Set(err);
|
||||||
|
|
||||||
// Error starting the pipe.
|
|
||||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
|
|
||||||
args.GetReturnValue().Set(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -197,9 +188,13 @@ void PipeWrap::OnConnection(uv_stream_t* handle, int status) {
|
|||||||
// uv_close() on the handle.
|
// uv_close() on the handle.
|
||||||
assert(wrap->persistent().IsEmpty() == false);
|
assert(wrap->persistent().IsEmpty() == false);
|
||||||
|
|
||||||
|
Local<Value> argv[] = {
|
||||||
|
Integer::New(status, node_isolate),
|
||||||
|
Undefined()
|
||||||
|
};
|
||||||
|
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
SetErrno(uv_last_error(uv_default_loop()));
|
MakeCallback(wrap->object(), "onconnection", ARRAY_SIZE(argv), argv);
|
||||||
MakeCallback(wrap->object(), "onconnection", 0, NULL);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,7 +210,7 @@ void PipeWrap::OnConnection(uv_stream_t* handle, int status) {
|
|||||||
if (uv_accept(handle, client_handle)) return;
|
if (uv_accept(handle, client_handle)) return;
|
||||||
|
|
||||||
// Successful accept. Call the onconnection callback in JavaScript land.
|
// Successful accept. Call the onconnection callback in JavaScript land.
|
||||||
Local<Value> argv[1] = { client_obj };
|
argv[1] = client_obj;
|
||||||
if (onconnection_sym.IsEmpty()) {
|
if (onconnection_sym.IsEmpty()) {
|
||||||
onconnection_sym = String::New("onconnection");
|
onconnection_sym = String::New("onconnection");
|
||||||
}
|
}
|
||||||
@ -236,7 +231,6 @@ void PipeWrap::AfterConnect(uv_connect_t* req, int status) {
|
|||||||
bool readable, writable;
|
bool readable, writable;
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
readable = writable = 0;
|
readable = writable = 0;
|
||||||
} else {
|
} else {
|
||||||
readable = uv_is_readable(req->handle) != 0;
|
readable = uv_is_readable(req->handle) != 0;
|
||||||
@ -277,18 +271,20 @@ void PipeWrap::Connect(const FunctionCallbackInfo<Value>& args) {
|
|||||||
|
|
||||||
UNWRAP(PipeWrap)
|
UNWRAP(PipeWrap)
|
||||||
|
|
||||||
String::AsciiValue name(args[0]);
|
assert(args[0]->IsObject());
|
||||||
|
assert(args[1]->IsString());
|
||||||
|
|
||||||
ConnectWrap* req_wrap = new ConnectWrap();
|
Local<Object> req_wrap_obj = args[0].As<Object>();
|
||||||
|
String::AsciiValue name(args[1]);
|
||||||
|
|
||||||
|
ConnectWrap* req_wrap = new ConnectWrap(req_wrap_obj);
|
||||||
uv_pipe_connect(&req_wrap->req_,
|
uv_pipe_connect(&req_wrap->req_,
|
||||||
&wrap->handle_,
|
&wrap->handle_,
|
||||||
*name,
|
*name,
|
||||||
AfterConnect);
|
AfterConnect);
|
||||||
|
|
||||||
req_wrap->Dispatched();
|
req_wrap->Dispatched();
|
||||||
|
|
||||||
args.GetReturnValue().Set(req_wrap->persistent());
|
args.GetReturnValue().Set(0); // uv_pipe_connect() doesn't return errors.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -217,12 +217,9 @@ class ProcessWrap : public HandleWrap {
|
|||||||
options.flags |= UV_PROCESS_DETACHED;
|
options.flags |= UV_PROCESS_DETACHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
int r = uv_spawn(uv_default_loop(), &wrap->process_, options);
|
int err = uv_spawn(uv_default_loop(), &wrap->process_, options);
|
||||||
|
|
||||||
if (r) {
|
if (err == 0) {
|
||||||
SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assert(wrap->process_.data == wrap);
|
assert(wrap->process_.data == wrap);
|
||||||
wrap->object()->Set(String::New("pid"),
|
wrap->object()->Set(String::New("pid"),
|
||||||
Integer::New(wrap->process_.pid, node_isolate));
|
Integer::New(wrap->process_.pid, node_isolate));
|
||||||
@ -240,7 +237,7 @@ class ProcessWrap : public HandleWrap {
|
|||||||
|
|
||||||
delete[] options.stdio;
|
delete[] options.stdio;
|
||||||
|
|
||||||
args.GetReturnValue().Set(r);
|
args.GetReturnValue().Set(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Kill(const FunctionCallbackInfo<Value>& args) {
|
static void Kill(const FunctionCallbackInfo<Value>& args) {
|
||||||
@ -248,9 +245,8 @@ class ProcessWrap : public HandleWrap {
|
|||||||
UNWRAP(ProcessWrap)
|
UNWRAP(ProcessWrap)
|
||||||
|
|
||||||
int signal = args[0]->Int32Value();
|
int signal = args[0]->Int32Value();
|
||||||
int r = uv_process_kill(&wrap->process_, signal);
|
int err = uv_process_kill(&wrap->process_, signal);
|
||||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
args.GetReturnValue().Set(err);
|
||||||
args.GetReturnValue().Set(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OnExit(uv_process_t* handle, int exit_status, int term_signal) {
|
static void OnExit(uv_process_t* handle, int exit_status, int term_signal) {
|
||||||
@ -260,15 +256,11 @@ class ProcessWrap : public HandleWrap {
|
|||||||
assert(wrap);
|
assert(wrap);
|
||||||
assert(&wrap->process_ == handle);
|
assert(&wrap->process_ == handle);
|
||||||
|
|
||||||
Local<Value> argv[2] = {
|
Local<Value> argv[] = {
|
||||||
Integer::New(exit_status, node_isolate),
|
Integer::New(exit_status, node_isolate),
|
||||||
String::New(signo_string(term_signal))
|
String::New(signo_string(term_signal))
|
||||||
};
|
};
|
||||||
|
|
||||||
if (exit_status == -1) {
|
|
||||||
SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (onexit_sym.IsEmpty()) {
|
if (onexit_sym.IsEmpty()) {
|
||||||
onexit_sym = String::New("onexit");
|
onexit_sym = String::New("onexit");
|
||||||
}
|
}
|
||||||
|
@ -86,18 +86,16 @@ class SignalWrap : public HandleWrap {
|
|||||||
UNWRAP(SignalWrap)
|
UNWRAP(SignalWrap)
|
||||||
|
|
||||||
int signum = args[0]->Int32Value();
|
int signum = args[0]->Int32Value();
|
||||||
int r = uv_signal_start(&wrap->handle_, OnSignal, signum);
|
int err = uv_signal_start(&wrap->handle_, OnSignal, signum);
|
||||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
args.GetReturnValue().Set(err);
|
||||||
args.GetReturnValue().Set(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Stop(const FunctionCallbackInfo<Value>& args) {
|
static void Stop(const FunctionCallbackInfo<Value>& args) {
|
||||||
HandleScope scope(node_isolate);
|
HandleScope scope(node_isolate);
|
||||||
UNWRAP(SignalWrap)
|
UNWRAP(SignalWrap)
|
||||||
|
|
||||||
int r = uv_signal_stop(&wrap->handle_);
|
int err = uv_signal_stop(&wrap->handle_);
|
||||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
args.GetReturnValue().Set(err);
|
||||||
args.GetReturnValue().Set(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OnSignal(uv_signal_t* handle, int signum) {
|
static void OnSignal(uv_signal_t* handle, int signum) {
|
||||||
|
@ -45,6 +45,7 @@ using v8::Number;
|
|||||||
using v8::Object;
|
using v8::Object;
|
||||||
using v8::PropertyCallbackInfo;
|
using v8::PropertyCallbackInfo;
|
||||||
using v8::String;
|
using v8::String;
|
||||||
|
using v8::Undefined;
|
||||||
using v8::Value;
|
using v8::Value;
|
||||||
|
|
||||||
|
|
||||||
@ -106,17 +107,14 @@ void StreamWrap::ReadStart(const FunctionCallbackInfo<Value>& args) {
|
|||||||
|
|
||||||
bool ipc_pipe = wrap->stream_->type == UV_NAMED_PIPE &&
|
bool ipc_pipe = wrap->stream_->type == UV_NAMED_PIPE &&
|
||||||
reinterpret_cast<uv_pipe_t*>(wrap->stream_)->ipc;
|
reinterpret_cast<uv_pipe_t*>(wrap->stream_)->ipc;
|
||||||
int r;
|
int err;
|
||||||
if (ipc_pipe) {
|
if (ipc_pipe) {
|
||||||
r = uv_read2_start(wrap->stream_, OnAlloc, OnRead2);
|
err = uv_read2_start(wrap->stream_, OnAlloc, OnRead2);
|
||||||
} else {
|
} else {
|
||||||
r = uv_read_start(wrap->stream_, OnAlloc, OnRead);
|
err = uv_read_start(wrap->stream_, OnAlloc, OnRead);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error starting the tcp.
|
args.GetReturnValue().Set(err);
|
||||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
|
|
||||||
args.GetReturnValue().Set(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -125,12 +123,8 @@ void StreamWrap::ReadStop(const FunctionCallbackInfo<Value>& args) {
|
|||||||
|
|
||||||
UNWRAP(StreamWrap)
|
UNWRAP(StreamWrap)
|
||||||
|
|
||||||
int r = uv_read_stop(wrap->stream_);
|
int err = uv_read_stop(wrap->stream_);
|
||||||
|
args.GetReturnValue().Set(err);
|
||||||
// Error starting the tcp.
|
|
||||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
|
|
||||||
args.GetReturnValue().Set(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -215,48 +209,50 @@ void StreamWrap::WriteBuffer(const FunctionCallbackInfo<Value>& args) {
|
|||||||
|
|
||||||
UNWRAP(StreamWrap)
|
UNWRAP(StreamWrap)
|
||||||
|
|
||||||
// The first argument is a buffer.
|
assert(args[0]->IsObject());
|
||||||
assert(args.Length() >= 1 && Buffer::HasInstance(args[0]));
|
assert(Buffer::HasInstance(args[1]));
|
||||||
size_t length = Buffer::Length(args[0]);
|
|
||||||
char* storage = new char[sizeof(WriteWrap)];
|
|
||||||
WriteWrap* req_wrap = new (storage) WriteWrap(wrap);
|
|
||||||
|
|
||||||
Local<Object> req_wrap_obj = req_wrap->object();
|
Local<Object> req_wrap_obj = args[0].As<Object>();
|
||||||
req_wrap_obj->SetHiddenValue(buffer_sym, args[0]);
|
Local<Object> buf_obj = args[1].As<Object>();
|
||||||
|
|
||||||
|
size_t length = Buffer::Length(buf_obj);
|
||||||
|
char* storage = new char[sizeof(WriteWrap)];
|
||||||
|
WriteWrap* req_wrap = new (storage) WriteWrap(req_wrap_obj, wrap);
|
||||||
|
|
||||||
|
req_wrap_obj->SetHiddenValue(buffer_sym, buf_obj);
|
||||||
|
|
||||||
uv_buf_t buf;
|
uv_buf_t buf;
|
||||||
WriteBuffer(args[0], &buf);
|
WriteBuffer(buf_obj, &buf);
|
||||||
|
|
||||||
int r = wrap->callbacks_->DoWrite(req_wrap,
|
|
||||||
&buf,
|
|
||||||
1,
|
|
||||||
NULL,
|
|
||||||
StreamWrap::AfterWrite);
|
|
||||||
|
|
||||||
|
int err = wrap->callbacks_->DoWrite(req_wrap,
|
||||||
|
&buf,
|
||||||
|
1,
|
||||||
|
NULL,
|
||||||
|
StreamWrap::AfterWrite);
|
||||||
req_wrap->Dispatched();
|
req_wrap->Dispatched();
|
||||||
req_wrap_obj->Set(bytes_sym, Integer::NewFromUnsigned(length, node_isolate));
|
req_wrap_obj->Set(bytes_sym, Integer::NewFromUnsigned(length, node_isolate));
|
||||||
|
|
||||||
if (r) {
|
if (err) {
|
||||||
SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
req_wrap->~WriteWrap();
|
req_wrap->~WriteWrap();
|
||||||
delete[] storage;
|
delete[] storage;
|
||||||
} else {
|
|
||||||
args.GetReturnValue().Set(req_wrap->persistent());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
args.GetReturnValue().Set(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <enum encoding encoding>
|
template <enum encoding encoding>
|
||||||
void StreamWrap::WriteStringImpl(const FunctionCallbackInfo<Value>& args) {
|
void StreamWrap::WriteStringImpl(const FunctionCallbackInfo<Value>& args) {
|
||||||
HandleScope scope(node_isolate);
|
HandleScope scope(node_isolate);
|
||||||
int r;
|
int err;
|
||||||
|
|
||||||
UNWRAP(StreamWrap)
|
UNWRAP(StreamWrap)
|
||||||
|
|
||||||
if (args.Length() < 1)
|
assert(args[0]->IsObject());
|
||||||
return ThrowTypeError("Not enough arguments");
|
assert(args[1]->IsString());
|
||||||
|
|
||||||
Local<String> string = args[0]->ToString();
|
Local<Object> req_wrap_obj = args[0].As<Object>();
|
||||||
|
Local<String> string = args[1].As<String>();
|
||||||
|
|
||||||
// Compute the size of the storage that the string will be flattened into.
|
// Compute the size of the storage that the string will be flattened into.
|
||||||
// For UTF8 strings that are very long, go ahead and take the hit for
|
// For UTF8 strings that are very long, go ahead and take the hit for
|
||||||
@ -268,14 +264,12 @@ void StreamWrap::WriteStringImpl(const FunctionCallbackInfo<Value>& args) {
|
|||||||
storage_size = StringBytes::StorageSize(string, encoding);
|
storage_size = StringBytes::StorageSize(string, encoding);
|
||||||
|
|
||||||
if (storage_size > INT_MAX) {
|
if (storage_size > INT_MAX) {
|
||||||
uv_err_t err;
|
args.GetReturnValue().Set(UV_ENOBUFS);
|
||||||
err.code = UV_ENOBUFS;
|
|
||||||
SetErrno(err);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* storage = new char[sizeof(WriteWrap) + storage_size + 15];
|
char* storage = new char[sizeof(WriteWrap) + storage_size + 15];
|
||||||
WriteWrap* req_wrap = new (storage) WriteWrap(wrap);
|
WriteWrap* req_wrap = new (storage) WriteWrap(req_wrap_obj, wrap);
|
||||||
|
|
||||||
char* data = reinterpret_cast<char*>(ROUND_UP(
|
char* data = reinterpret_cast<char*>(ROUND_UP(
|
||||||
reinterpret_cast<uintptr_t>(storage) + sizeof(WriteWrap), 16));
|
reinterpret_cast<uintptr_t>(storage) + sizeof(WriteWrap), 16));
|
||||||
@ -294,16 +288,16 @@ void StreamWrap::WriteStringImpl(const FunctionCallbackInfo<Value>& args) {
|
|||||||
reinterpret_cast<uv_pipe_t*>(wrap->stream_)->ipc;
|
reinterpret_cast<uv_pipe_t*>(wrap->stream_)->ipc;
|
||||||
|
|
||||||
if (!ipc_pipe) {
|
if (!ipc_pipe) {
|
||||||
r = wrap->callbacks_->DoWrite(req_wrap,
|
err = wrap->callbacks_->DoWrite(req_wrap,
|
||||||
&buf,
|
&buf,
|
||||||
1,
|
1,
|
||||||
NULL,
|
NULL,
|
||||||
StreamWrap::AfterWrite);
|
StreamWrap::AfterWrite);
|
||||||
} else {
|
} else {
|
||||||
uv_handle_t* send_handle = NULL;
|
uv_handle_t* send_handle = NULL;
|
||||||
|
|
||||||
if (args[1]->IsObject()) {
|
if (args[2]->IsObject()) {
|
||||||
Local<Object> send_handle_obj = args[1]->ToObject();
|
Local<Object> send_handle_obj = args[2]->ToObject();
|
||||||
assert(send_handle_obj->InternalFieldCount() > 0);
|
assert(send_handle_obj->InternalFieldCount() > 0);
|
||||||
HandleWrap* send_handle_wrap = static_cast<HandleWrap*>(
|
HandleWrap* send_handle_wrap = static_cast<HandleWrap*>(
|
||||||
send_handle_obj->GetAlignedPointerFromInternalField(0));
|
send_handle_obj->GetAlignedPointerFromInternalField(0));
|
||||||
@ -318,23 +312,22 @@ void StreamWrap::WriteStringImpl(const FunctionCallbackInfo<Value>& args) {
|
|||||||
req_wrap->object()->Set(handle_sym, send_handle_obj);
|
req_wrap->object()->Set(handle_sym, send_handle_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
r = wrap->callbacks_->DoWrite(req_wrap,
|
err = wrap->callbacks_->DoWrite(req_wrap,
|
||||||
&buf,
|
&buf,
|
||||||
1,
|
1,
|
||||||
reinterpret_cast<uv_stream_t*>(send_handle),
|
reinterpret_cast<uv_stream_t*>(send_handle),
|
||||||
StreamWrap::AfterWrite);
|
StreamWrap::AfterWrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
req_wrap->Dispatched();
|
req_wrap->Dispatched();
|
||||||
req_wrap->object()->Set(bytes_sym, Number::New(node_isolate, data_size));
|
req_wrap->object()->Set(bytes_sym, Number::New(node_isolate, data_size));
|
||||||
|
|
||||||
if (r) {
|
if (err) {
|
||||||
SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
req_wrap->~WriteWrap();
|
req_wrap->~WriteWrap();
|
||||||
delete[] storage;
|
delete[] storage;
|
||||||
} else {
|
|
||||||
args.GetReturnValue().Set(req_wrap->persistent());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
args.GetReturnValue().Set(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -343,13 +336,11 @@ void StreamWrap::Writev(const FunctionCallbackInfo<Value>& args) {
|
|||||||
|
|
||||||
UNWRAP(StreamWrap)
|
UNWRAP(StreamWrap)
|
||||||
|
|
||||||
if (args.Length() < 1)
|
assert(args[0]->IsObject());
|
||||||
return ThrowTypeError("Not enough arguments");
|
assert(args[1]->IsArray());
|
||||||
|
|
||||||
if (!args[0]->IsArray())
|
Local<Object> req_wrap_obj = args[0].As<Object>();
|
||||||
return ThrowTypeError("Argument should be array");
|
Local<Array> chunks = args[1].As<Array>();
|
||||||
|
|
||||||
Handle<Array> chunks = args[0].As<Array>();
|
|
||||||
size_t count = chunks->Length() >> 1;
|
size_t count = chunks->Length() >> 1;
|
||||||
|
|
||||||
uv_buf_t bufs_[16];
|
uv_buf_t bufs_[16];
|
||||||
@ -377,9 +368,7 @@ void StreamWrap::Writev(const FunctionCallbackInfo<Value>& args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (storage_size > INT_MAX) {
|
if (storage_size > INT_MAX) {
|
||||||
uv_err_t err;
|
args.GetReturnValue().Set(UV_ENOBUFS);
|
||||||
err.code = UV_ENOBUFS;
|
|
||||||
SetErrno(err);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,7 +377,7 @@ void StreamWrap::Writev(const FunctionCallbackInfo<Value>& args) {
|
|||||||
|
|
||||||
storage_size += sizeof(WriteWrap);
|
storage_size += sizeof(WriteWrap);
|
||||||
char* storage = new char[storage_size];
|
char* storage = new char[storage_size];
|
||||||
WriteWrap* req_wrap = new (storage) WriteWrap(wrap);
|
WriteWrap* req_wrap = new (storage) WriteWrap(req_wrap_obj, wrap);
|
||||||
|
|
||||||
uint32_t bytes = 0;
|
uint32_t bytes = 0;
|
||||||
size_t offset = sizeof(WriteWrap);
|
size_t offset = sizeof(WriteWrap);
|
||||||
@ -418,11 +407,11 @@ void StreamWrap::Writev(const FunctionCallbackInfo<Value>& args) {
|
|||||||
bytes += str_size;
|
bytes += str_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
int r = wrap->callbacks_->DoWrite(req_wrap,
|
int err = wrap->callbacks_->DoWrite(req_wrap,
|
||||||
bufs,
|
bufs,
|
||||||
count,
|
count,
|
||||||
NULL,
|
NULL,
|
||||||
StreamWrap::AfterWrite);
|
StreamWrap::AfterWrite);
|
||||||
|
|
||||||
// Deallocate space
|
// Deallocate space
|
||||||
if (bufs != bufs_)
|
if (bufs != bufs_)
|
||||||
@ -431,13 +420,12 @@ void StreamWrap::Writev(const FunctionCallbackInfo<Value>& args) {
|
|||||||
req_wrap->Dispatched();
|
req_wrap->Dispatched();
|
||||||
req_wrap->object()->Set(bytes_sym, Number::New(node_isolate, bytes));
|
req_wrap->object()->Set(bytes_sym, Number::New(node_isolate, bytes));
|
||||||
|
|
||||||
if (r) {
|
if (err) {
|
||||||
SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
req_wrap->~WriteWrap();
|
req_wrap->~WriteWrap();
|
||||||
delete[] storage;
|
delete[] storage;
|
||||||
} else {
|
|
||||||
args.GetReturnValue().Set(req_wrap->persistent());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
args.GetReturnValue().Set(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -472,10 +460,6 @@ void StreamWrap::AfterWrite(uv_write_t* req, int status) {
|
|||||||
req_wrap_obj->Delete(handle_sym);
|
req_wrap_obj->Delete(handle_sym);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status) {
|
|
||||||
SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
}
|
|
||||||
|
|
||||||
wrap->callbacks_->AfterWrite(req_wrap);
|
wrap->callbacks_->AfterWrite(req_wrap);
|
||||||
|
|
||||||
Local<Value> argv[] = {
|
Local<Value> argv[] = {
|
||||||
@ -496,24 +480,20 @@ void StreamWrap::Shutdown(const FunctionCallbackInfo<Value>& args) {
|
|||||||
|
|
||||||
UNWRAP(StreamWrap)
|
UNWRAP(StreamWrap)
|
||||||
|
|
||||||
ShutdownWrap* req_wrap = new ShutdownWrap();
|
assert(args[0]->IsObject());
|
||||||
|
Local<Object> req_wrap_obj = args[0].As<Object>();
|
||||||
int r = wrap->callbacks_->DoShutdown(req_wrap, AfterShutdown);
|
|
||||||
|
|
||||||
|
ShutdownWrap* req_wrap = new ShutdownWrap(req_wrap_obj);
|
||||||
|
int err = wrap->callbacks_->DoShutdown(req_wrap, AfterShutdown);
|
||||||
req_wrap->Dispatched();
|
req_wrap->Dispatched();
|
||||||
|
if (err) delete req_wrap;
|
||||||
if (r) {
|
args.GetReturnValue().Set(err);
|
||||||
SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
delete req_wrap;
|
|
||||||
} else {
|
|
||||||
args.GetReturnValue().Set(req_wrap->persistent());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void StreamWrap::AfterShutdown(uv_shutdown_t* req, int status) {
|
void StreamWrap::AfterShutdown(uv_shutdown_t* req, int status) {
|
||||||
ReqWrap<uv_shutdown_t>* req_wrap = (ReqWrap<uv_shutdown_t>*) req->data;
|
ShutdownWrap* req_wrap = static_cast<ShutdownWrap*>(req->data);
|
||||||
StreamWrap* wrap = (StreamWrap*) req->handle->data;
|
StreamWrap* wrap = static_cast<StreamWrap*>(req->handle->data);
|
||||||
|
|
||||||
// The wrap and request objects should still be there.
|
// The wrap and request objects should still be there.
|
||||||
assert(req_wrap->persistent().IsEmpty() == false);
|
assert(req_wrap->persistent().IsEmpty() == false);
|
||||||
@ -521,10 +501,6 @@ void StreamWrap::AfterShutdown(uv_shutdown_t* req, int status) {
|
|||||||
|
|
||||||
HandleScope scope(node_isolate);
|
HandleScope scope(node_isolate);
|
||||||
|
|
||||||
if (status) {
|
|
||||||
SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
}
|
|
||||||
|
|
||||||
Local<Object> req_wrap_obj = req_wrap->object();
|
Local<Object> req_wrap_obj = req_wrap->object();
|
||||||
Local<Value> argv[3] = {
|
Local<Value> argv[3] = {
|
||||||
Integer::New(status, node_isolate),
|
Integer::New(status, node_isolate),
|
||||||
@ -589,11 +565,16 @@ void StreamWrapCallbacks::DoRead(uv_stream_t* handle,
|
|||||||
uv_handle_type pending) {
|
uv_handle_type pending) {
|
||||||
HandleScope scope(node_isolate);
|
HandleScope scope(node_isolate);
|
||||||
|
|
||||||
|
Local<Value> argv[] = {
|
||||||
|
Integer::New(nread, node_isolate),
|
||||||
|
Undefined(),
|
||||||
|
Undefined()
|
||||||
|
};
|
||||||
|
|
||||||
if (nread < 0) {
|
if (nread < 0) {
|
||||||
if (buf.base != NULL)
|
if (buf.base != NULL)
|
||||||
free(buf.base);
|
free(buf.base);
|
||||||
SetErrno(uv_last_error(uv_default_loop()));
|
MakeCallback(Self(), onread_sym, ARRAY_SIZE(argv), argv);
|
||||||
MakeCallback(Self(), onread_sym, 0, NULL);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -604,13 +585,8 @@ void StreamWrapCallbacks::DoRead(uv_stream_t* handle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
buf.base = static_cast<char*>(realloc(buf.base, nread));
|
buf.base = static_cast<char*>(realloc(buf.base, nread));
|
||||||
|
|
||||||
assert(static_cast<size_t>(nread) <= buf.len);
|
assert(static_cast<size_t>(nread) <= buf.len);
|
||||||
|
argv[1] = Buffer::Use(buf.base, nread);
|
||||||
int argc = 1;
|
|
||||||
Local<Value> argv[2] = {
|
|
||||||
Buffer::Use(buf.base, nread)
|
|
||||||
};
|
|
||||||
|
|
||||||
Local<Object> pending_obj;
|
Local<Object> pending_obj;
|
||||||
if (pending == UV_TCP) {
|
if (pending == UV_TCP) {
|
||||||
@ -624,11 +600,10 @@ void StreamWrapCallbacks::DoRead(uv_stream_t* handle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!pending_obj.IsEmpty()) {
|
if (!pending_obj.IsEmpty()) {
|
||||||
argv[1] = pending_obj;
|
argv[2] = pending_obj;
|
||||||
argc++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MakeCallback(wrap_->object(), onread_sym, argc, argv);
|
MakeCallback(wrap_->object(), onread_sym, ARRAY_SIZE(argv), argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,7 +37,8 @@ typedef class ReqWrap<uv_shutdown_t> ShutdownWrap;
|
|||||||
|
|
||||||
class WriteWrap: public ReqWrap<uv_write_t> {
|
class WriteWrap: public ReqWrap<uv_write_t> {
|
||||||
public:
|
public:
|
||||||
explicit WriteWrap(StreamWrap* wrap) {
|
explicit WriteWrap(v8::Local<v8::Object> obj, StreamWrap* wrap)
|
||||||
|
: ReqWrap<uv_write_t>(obj) {
|
||||||
wrap_ = wrap;
|
wrap_ = wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
145
src/tcp_wrap.cc
145
src/tcp_wrap.cc
@ -39,11 +39,11 @@ using v8::Handle;
|
|||||||
using v8::HandleScope;
|
using v8::HandleScope;
|
||||||
using v8::Integer;
|
using v8::Integer;
|
||||||
using v8::Local;
|
using v8::Local;
|
||||||
using v8::Null;
|
|
||||||
using v8::Object;
|
using v8::Object;
|
||||||
using v8::Persistent;
|
using v8::Persistent;
|
||||||
using v8::PropertyAttribute;
|
using v8::PropertyAttribute;
|
||||||
using v8::String;
|
using v8::String;
|
||||||
|
using v8::Undefined;
|
||||||
using v8::Value;
|
using v8::Value;
|
||||||
|
|
||||||
static Persistent<Function> tcpConstructor;
|
static Persistent<Function> tcpConstructor;
|
||||||
@ -168,14 +168,19 @@ void TCPWrap::GetSockName(const FunctionCallbackInfo<Value>& args) {
|
|||||||
|
|
||||||
UNWRAP(TCPWrap)
|
UNWRAP(TCPWrap)
|
||||||
|
|
||||||
int addrlen = sizeof(address);
|
assert(args[0]->IsObject());
|
||||||
int r = uv_tcp_getsockname(&wrap->handle_,
|
Local<Object> out = args[0].As<Object>();
|
||||||
reinterpret_cast<sockaddr*>(&address),
|
|
||||||
&addrlen);
|
|
||||||
if (r) return SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
|
|
||||||
const sockaddr* addr = reinterpret_cast<const sockaddr*>(&address);
|
int addrlen = sizeof(address);
|
||||||
args.GetReturnValue().Set(AddressToJS(addr));
|
int err = uv_tcp_getsockname(&wrap->handle_,
|
||||||
|
reinterpret_cast<sockaddr*>(&address),
|
||||||
|
&addrlen);
|
||||||
|
if (err == 0) {
|
||||||
|
const sockaddr* addr = reinterpret_cast<const sockaddr*>(&address);
|
||||||
|
AddressToJS(addr, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
args.GetReturnValue().Set(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -185,14 +190,19 @@ void TCPWrap::GetPeerName(const FunctionCallbackInfo<Value>& args) {
|
|||||||
|
|
||||||
UNWRAP(TCPWrap)
|
UNWRAP(TCPWrap)
|
||||||
|
|
||||||
int addrlen = sizeof(address);
|
assert(args[0]->IsObject());
|
||||||
int r = uv_tcp_getpeername(&wrap->handle_,
|
Local<Object> out = args[0].As<Object>();
|
||||||
reinterpret_cast<sockaddr*>(&address),
|
|
||||||
&addrlen);
|
|
||||||
if (r) return SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
|
|
||||||
const sockaddr* addr = reinterpret_cast<const sockaddr*>(&address);
|
int addrlen = sizeof(address);
|
||||||
args.GetReturnValue().Set(AddressToJS(addr));
|
int err = uv_tcp_getpeername(&wrap->handle_,
|
||||||
|
reinterpret_cast<sockaddr*>(&address),
|
||||||
|
&addrlen);
|
||||||
|
if (err == 0) {
|
||||||
|
const sockaddr* addr = reinterpret_cast<const sockaddr*>(&address);
|
||||||
|
AddressToJS(addr, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
args.GetReturnValue().Set(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -202,8 +212,8 @@ void TCPWrap::SetNoDelay(const FunctionCallbackInfo<Value>& args) {
|
|||||||
UNWRAP(TCPWrap)
|
UNWRAP(TCPWrap)
|
||||||
|
|
||||||
int enable = static_cast<int>(args[0]->BooleanValue());
|
int enable = static_cast<int>(args[0]->BooleanValue());
|
||||||
int r = uv_tcp_nodelay(&wrap->handle_, enable);
|
int err = uv_tcp_nodelay(&wrap->handle_, enable);
|
||||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
args.GetReturnValue().Set(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -215,8 +225,8 @@ void TCPWrap::SetKeepAlive(const FunctionCallbackInfo<Value>& args) {
|
|||||||
int enable = args[0]->Int32Value();
|
int enable = args[0]->Int32Value();
|
||||||
unsigned int delay = args[1]->Uint32Value();
|
unsigned int delay = args[1]->Uint32Value();
|
||||||
|
|
||||||
int r = uv_tcp_keepalive(&wrap->handle_, enable, delay);
|
int err = uv_tcp_keepalive(&wrap->handle_, enable, delay);
|
||||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
args.GetReturnValue().Set(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -227,8 +237,8 @@ void TCPWrap::SetSimultaneousAccepts(const FunctionCallbackInfo<Value>& args) {
|
|||||||
UNWRAP(TCPWrap)
|
UNWRAP(TCPWrap)
|
||||||
|
|
||||||
bool enable = args[0]->BooleanValue();
|
bool enable = args[0]->BooleanValue();
|
||||||
int r = uv_tcp_simultaneous_accepts(&wrap->handle_, enable ? 1 : 0);
|
int err = uv_tcp_simultaneous_accepts(&wrap->handle_, enable);
|
||||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
args.GetReturnValue().Set(err);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -250,12 +260,9 @@ void TCPWrap::Bind(const FunctionCallbackInfo<Value>& args) {
|
|||||||
int port = args[1]->Int32Value();
|
int port = args[1]->Int32Value();
|
||||||
|
|
||||||
struct sockaddr_in address = uv_ip4_addr(*ip_address, port);
|
struct sockaddr_in address = uv_ip4_addr(*ip_address, port);
|
||||||
int r = uv_tcp_bind(&wrap->handle_, address);
|
int err = uv_tcp_bind(&wrap->handle_, address);
|
||||||
|
|
||||||
// Error starting the tcp.
|
args.GetReturnValue().Set(err);
|
||||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
|
|
||||||
args.GetReturnValue().Set(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -268,12 +275,9 @@ void TCPWrap::Bind6(const FunctionCallbackInfo<Value>& args) {
|
|||||||
int port = args[1]->Int32Value();
|
int port = args[1]->Int32Value();
|
||||||
|
|
||||||
struct sockaddr_in6 address = uv_ip6_addr(*ip6_address, port);
|
struct sockaddr_in6 address = uv_ip6_addr(*ip6_address, port);
|
||||||
int r = uv_tcp_bind6(&wrap->handle_, address);
|
int err = uv_tcp_bind6(&wrap->handle_, address);
|
||||||
|
|
||||||
// Error starting the tcp.
|
args.GetReturnValue().Set(err);
|
||||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
|
|
||||||
args.GetReturnValue().Set(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -283,15 +287,10 @@ void TCPWrap::Listen(const FunctionCallbackInfo<Value>& args) {
|
|||||||
UNWRAP(TCPWrap)
|
UNWRAP(TCPWrap)
|
||||||
|
|
||||||
int backlog = args[0]->Int32Value();
|
int backlog = args[0]->Int32Value();
|
||||||
|
int err = uv_listen(reinterpret_cast<uv_stream_t*>(&wrap->handle_),
|
||||||
int r = uv_listen(reinterpret_cast<uv_stream_t*>(&wrap->handle_),
|
backlog,
|
||||||
backlog,
|
OnConnection);
|
||||||
OnConnection);
|
args.GetReturnValue().Set(err);
|
||||||
|
|
||||||
// Error starting the tcp.
|
|
||||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
|
|
||||||
args.GetReturnValue().Set(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -305,7 +304,10 @@ void TCPWrap::OnConnection(uv_stream_t* handle, int status) {
|
|||||||
// uv_close() on the handle.
|
// uv_close() on the handle.
|
||||||
assert(wrap->persistent().IsEmpty() == false);
|
assert(wrap->persistent().IsEmpty() == false);
|
||||||
|
|
||||||
Local<Value> argv[1];
|
Local<Value> argv[2] = {
|
||||||
|
Integer::New(status, node_isolate),
|
||||||
|
Undefined()
|
||||||
|
};
|
||||||
|
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
// Instantiate the client javascript object and handle.
|
// Instantiate the client javascript object and handle.
|
||||||
@ -321,10 +323,7 @@ void TCPWrap::OnConnection(uv_stream_t* handle, int status) {
|
|||||||
if (uv_accept(handle, client_handle)) return;
|
if (uv_accept(handle, client_handle)) return;
|
||||||
|
|
||||||
// Successful accept. Call the onconnection callback in JavaScript land.
|
// Successful accept. Call the onconnection callback in JavaScript land.
|
||||||
argv[0] = client_obj;
|
argv[1] = client_obj;
|
||||||
} else {
|
|
||||||
SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
argv[0] = Null(node_isolate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MakeCallback(wrap->object(), onconnection_sym, ARRAY_SIZE(argv), argv);
|
MakeCallback(wrap->object(), onconnection_sym, ARRAY_SIZE(argv), argv);
|
||||||
@ -341,10 +340,6 @@ void TCPWrap::AfterConnect(uv_connect_t* req, int status) {
|
|||||||
assert(req_wrap->persistent().IsEmpty() == false);
|
assert(req_wrap->persistent().IsEmpty() == false);
|
||||||
assert(wrap->persistent().IsEmpty() == false);
|
assert(wrap->persistent().IsEmpty() == false);
|
||||||
|
|
||||||
if (status) {
|
|
||||||
SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
}
|
|
||||||
|
|
||||||
Local<Object> req_wrap_obj = req_wrap->object();
|
Local<Object> req_wrap_obj = req_wrap->object();
|
||||||
Local<Value> argv[5] = {
|
Local<Value> argv[5] = {
|
||||||
Integer::New(status, node_isolate),
|
Integer::New(status, node_isolate),
|
||||||
@ -364,27 +359,29 @@ void TCPWrap::Connect(const FunctionCallbackInfo<Value>& args) {
|
|||||||
|
|
||||||
UNWRAP(TCPWrap)
|
UNWRAP(TCPWrap)
|
||||||
|
|
||||||
String::AsciiValue ip_address(args[0]);
|
assert(args[0]->IsObject());
|
||||||
int port = args[1]->Int32Value();
|
assert(args[1]->IsString());
|
||||||
|
assert(args[2]->Uint32Value());
|
||||||
|
|
||||||
|
Local<Object> req_wrap_obj = args[0].As<Object>();
|
||||||
|
String::AsciiValue ip_address(args[1]);
|
||||||
|
int port = args[2]->Uint32Value();
|
||||||
|
|
||||||
struct sockaddr_in address = uv_ip4_addr(*ip_address, port);
|
struct sockaddr_in address = uv_ip4_addr(*ip_address, port);
|
||||||
|
|
||||||
// I hate when people program C++ like it was C, and yet I do it too.
|
// I hate when people program C++ like it was C, and yet I do it too.
|
||||||
// I'm too lazy to come up with the perfect class hierarchy here. Let's
|
// I'm too lazy to come up with the perfect class hierarchy here. Let's
|
||||||
// just do some type munging.
|
// just do some type munging.
|
||||||
ConnectWrap* req_wrap = new ConnectWrap();
|
ConnectWrap* req_wrap = new ConnectWrap(req_wrap_obj);
|
||||||
|
|
||||||
int r = uv_tcp_connect(&req_wrap->req_, &wrap->handle_, address,
|
|
||||||
AfterConnect);
|
|
||||||
|
|
||||||
|
int err = uv_tcp_connect(&req_wrap->req_,
|
||||||
|
&wrap->handle_,
|
||||||
|
address,
|
||||||
|
AfterConnect);
|
||||||
req_wrap->Dispatched();
|
req_wrap->Dispatched();
|
||||||
|
if (err) delete req_wrap;
|
||||||
|
|
||||||
if (r) {
|
args.GetReturnValue().Set(err);
|
||||||
SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
delete req_wrap;
|
|
||||||
} else {
|
|
||||||
args.GetReturnValue().Set(req_wrap->persistent());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -393,24 +390,26 @@ void TCPWrap::Connect6(const FunctionCallbackInfo<Value>& args) {
|
|||||||
|
|
||||||
UNWRAP(TCPWrap)
|
UNWRAP(TCPWrap)
|
||||||
|
|
||||||
String::AsciiValue ip_address(args[0]);
|
assert(args[0]->IsObject());
|
||||||
int port = args[1]->Int32Value();
|
assert(args[1]->IsString());
|
||||||
|
assert(args[2]->Uint32Value());
|
||||||
|
|
||||||
|
Local<Object> req_wrap_obj = args[0].As<Object>();
|
||||||
|
String::AsciiValue ip_address(args[1]);
|
||||||
|
int port = args[2]->Int32Value();
|
||||||
|
|
||||||
struct sockaddr_in6 address = uv_ip6_addr(*ip_address, port);
|
struct sockaddr_in6 address = uv_ip6_addr(*ip_address, port);
|
||||||
|
|
||||||
ConnectWrap* req_wrap = new ConnectWrap();
|
ConnectWrap* req_wrap = new ConnectWrap(req_wrap_obj);
|
||||||
|
|
||||||
int r = uv_tcp_connect6(&req_wrap->req_, &wrap->handle_, address,
|
|
||||||
AfterConnect);
|
|
||||||
|
|
||||||
|
int err = uv_tcp_connect6(&req_wrap->req_,
|
||||||
|
&wrap->handle_,
|
||||||
|
address,
|
||||||
|
AfterConnect);
|
||||||
req_wrap->Dispatched();
|
req_wrap->Dispatched();
|
||||||
|
if (err) delete req_wrap;
|
||||||
|
|
||||||
if (r) {
|
args.GetReturnValue().Set(err);
|
||||||
SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
delete req_wrap;
|
|
||||||
} else {
|
|
||||||
args.GetReturnValue().Set(req_wrap->persistent());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -90,27 +90,24 @@ class TimerWrap : public HandleWrap {
|
|||||||
|
|
||||||
int64_t timeout = args[0]->IntegerValue();
|
int64_t timeout = args[0]->IntegerValue();
|
||||||
int64_t repeat = args[1]->IntegerValue();
|
int64_t repeat = args[1]->IntegerValue();
|
||||||
int r = uv_timer_start(&wrap->handle_, OnTimeout, timeout, repeat);
|
int err = uv_timer_start(&wrap->handle_, OnTimeout, timeout, repeat);
|
||||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
args.GetReturnValue().Set(err);
|
||||||
args.GetReturnValue().Set(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Stop(const FunctionCallbackInfo<Value>& args) {
|
static void Stop(const FunctionCallbackInfo<Value>& args) {
|
||||||
HandleScope scope(node_isolate);
|
HandleScope scope(node_isolate);
|
||||||
UNWRAP(TimerWrap)
|
UNWRAP(TimerWrap)
|
||||||
|
|
||||||
int r = uv_timer_stop(&wrap->handle_);
|
int err = uv_timer_stop(&wrap->handle_);
|
||||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
args.GetReturnValue().Set(err);
|
||||||
args.GetReturnValue().Set(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Again(const FunctionCallbackInfo<Value>& args) {
|
static void Again(const FunctionCallbackInfo<Value>& args) {
|
||||||
HandleScope scope(node_isolate);
|
HandleScope scope(node_isolate);
|
||||||
UNWRAP(TimerWrap)
|
UNWRAP(TimerWrap)
|
||||||
|
|
||||||
int r = uv_timer_again(&wrap->handle_);
|
int err = uv_timer_again(&wrap->handle_);
|
||||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
args.GetReturnValue().Set(err);
|
||||||
args.GetReturnValue().Set(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetRepeat(const FunctionCallbackInfo<Value>& args) {
|
static void SetRepeat(const FunctionCallbackInfo<Value>& args) {
|
||||||
@ -127,7 +124,6 @@ class TimerWrap : public HandleWrap {
|
|||||||
UNWRAP(TimerWrap)
|
UNWRAP(TimerWrap)
|
||||||
|
|
||||||
int64_t repeat = uv_timer_get_repeat(&wrap->handle_);
|
int64_t repeat = uv_timer_get_repeat(&wrap->handle_);
|
||||||
if (repeat < 0) SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
args.GetReturnValue().Set(static_cast<double>(repeat));
|
args.GetReturnValue().Set(static_cast<double>(repeat));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -418,7 +418,6 @@ void TLSCallbacks::EncOutCb(uv_write_t* req, int status) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Notify about error
|
// Notify about error
|
||||||
SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
Local<Value> arg = String::Concat(
|
Local<Value> arg = String::Concat(
|
||||||
String::New("write cb error, status: "),
|
String::New("write cb error, status: "),
|
||||||
Integer::New(status, node_isolate)->ToString());
|
Integer::New(status, node_isolate)->ToString());
|
||||||
@ -483,8 +482,11 @@ void TLSCallbacks::ClearOut() {
|
|||||||
do {
|
do {
|
||||||
read = SSL_read(ssl_, out, sizeof(out));
|
read = SSL_read(ssl_, out, sizeof(out));
|
||||||
if (read > 0) {
|
if (read > 0) {
|
||||||
Handle<Value> buf = Buffer::New(out, read);
|
Local<Value> argv[] = {
|
||||||
MakeCallback(Self(), onread_sym, 1, &buf);
|
Integer::New(read, node_isolate),
|
||||||
|
Buffer::New(out, read)
|
||||||
|
};
|
||||||
|
MakeCallback(Self(), onread_sym, ARRAY_SIZE(argv), argv);
|
||||||
}
|
}
|
||||||
} while (read > 0);
|
} while (read > 0);
|
||||||
|
|
||||||
@ -621,12 +623,10 @@ void TLSCallbacks::DoRead(uv_stream_t* handle,
|
|||||||
uv_buf_t buf,
|
uv_buf_t buf,
|
||||||
uv_handle_type pending) {
|
uv_handle_type pending) {
|
||||||
if (nread < 0) {
|
if (nread < 0) {
|
||||||
uv_err_t err = uv_last_error(uv_default_loop());
|
|
||||||
SetErrno(err);
|
|
||||||
|
|
||||||
// Error should be emitted only after all data was read
|
// Error should be emitted only after all data was read
|
||||||
ClearOut();
|
ClearOut();
|
||||||
MakeCallback(Self(), onread_sym, 0, NULL);
|
Local<Value> arg = Integer::New(nread, node_isolate);
|
||||||
|
MakeCallback(Self(), onread_sym, 1, &arg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
namespace node {
|
namespace node {
|
||||||
|
|
||||||
|
using v8::Array;
|
||||||
using v8::Function;
|
using v8::Function;
|
||||||
using v8::FunctionCallbackInfo;
|
using v8::FunctionCallbackInfo;
|
||||||
using v8::FunctionTemplate;
|
using v8::FunctionTemplate;
|
||||||
@ -131,15 +132,18 @@ void TTYWrap::GetWindowSize(const FunctionCallbackInfo<Value>& args) {
|
|||||||
HandleScope scope(node_isolate);
|
HandleScope scope(node_isolate);
|
||||||
|
|
||||||
UNWRAP(TTYWrap)
|
UNWRAP(TTYWrap)
|
||||||
|
assert(args[0]->IsArray());
|
||||||
|
|
||||||
int width, height;
|
int width, height;
|
||||||
int r = uv_tty_get_winsize(&wrap->handle_, &width, &height);
|
int err = uv_tty_get_winsize(&wrap->handle_, &width, &height);
|
||||||
if (r) return SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
|
|
||||||
Local<v8::Array> a = v8::Array::New(2);
|
if (err == 0) {
|
||||||
a->Set(0, Integer::New(width, node_isolate));
|
Local<v8::Array> a = args[0].As<Array>();
|
||||||
a->Set(1, Integer::New(height, node_isolate));
|
a->Set(0, Integer::New(width, node_isolate));
|
||||||
args.GetReturnValue().Set(a);
|
a->Set(1, Integer::New(height, node_isolate));
|
||||||
|
}
|
||||||
|
|
||||||
|
args.GetReturnValue().Set(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -148,9 +152,8 @@ void TTYWrap::SetRawMode(const FunctionCallbackInfo<Value>& args) {
|
|||||||
|
|
||||||
UNWRAP(TTYWrap)
|
UNWRAP(TTYWrap)
|
||||||
|
|
||||||
int r = uv_tty_set_mode(&wrap->handle_, args[0]->IsTrue());
|
int err = uv_tty_set_mode(&wrap->handle_, args[0]->IsTrue());
|
||||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
args.GetReturnValue().Set(err);
|
||||||
args.GetReturnValue().Set(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
146
src/udp_wrap.cc
146
src/udp_wrap.cc
@ -43,6 +43,7 @@ using v8::PropertyAttribute;
|
|||||||
using v8::PropertyCallbackInfo;
|
using v8::PropertyCallbackInfo;
|
||||||
using v8::String;
|
using v8::String;
|
||||||
using v8::Uint32;
|
using v8::Uint32;
|
||||||
|
using v8::Undefined;
|
||||||
using v8::Value;
|
using v8::Value;
|
||||||
|
|
||||||
typedef ReqWrap<uv_udp_send_t> SendWrap;
|
typedef ReqWrap<uv_udp_send_t> SendWrap;
|
||||||
@ -128,7 +129,7 @@ void UDPWrap::GetFD(Local<String>, const PropertyCallbackInfo<Value>& args) {
|
|||||||
|
|
||||||
void UDPWrap::DoBind(const FunctionCallbackInfo<Value>& args, int family) {
|
void UDPWrap::DoBind(const FunctionCallbackInfo<Value>& args, int family) {
|
||||||
HandleScope scope(node_isolate);
|
HandleScope scope(node_isolate);
|
||||||
int r;
|
int err;
|
||||||
|
|
||||||
UNWRAP(UDPWrap)
|
UNWRAP(UDPWrap)
|
||||||
|
|
||||||
@ -141,18 +142,17 @@ void UDPWrap::DoBind(const FunctionCallbackInfo<Value>& args, int family) {
|
|||||||
|
|
||||||
switch (family) {
|
switch (family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
r = uv_udp_bind(&wrap->handle_, uv_ip4_addr(*address, port), flags);
|
err = uv_udp_bind(&wrap->handle_, uv_ip4_addr(*address, port), flags);
|
||||||
break;
|
break;
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
r = uv_udp_bind6(&wrap->handle_, uv_ip6_addr(*address, port), flags);
|
err = uv_udp_bind6(&wrap->handle_, uv_ip6_addr(*address, port), flags);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0 && "unexpected address family");
|
assert(0 && "unexpected address family");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
args.GetReturnValue().Set(err);
|
||||||
args.GetReturnValue().Set(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -172,9 +172,8 @@ void UDPWrap::Bind6(const FunctionCallbackInfo<Value>& args) {
|
|||||||
UNWRAP(UDPWrap) \
|
UNWRAP(UDPWrap) \
|
||||||
assert(args.Length() == 1); \
|
assert(args.Length() == 1); \
|
||||||
int flag = args[0]->Int32Value(); \
|
int flag = args[0]->Int32Value(); \
|
||||||
int r = fn(&wrap->handle_, flag); \
|
int err = fn(&wrap->handle_, flag); \
|
||||||
if (r) SetErrno(uv_last_error(uv_default_loop())); \
|
args.GetReturnValue().Set(err); \
|
||||||
args.GetReturnValue().Set(r); \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
X(SetTTL, uv_udp_set_ttl)
|
X(SetTTL, uv_udp_set_ttl)
|
||||||
@ -200,12 +199,11 @@ void UDPWrap::SetMembership(const FunctionCallbackInfo<Value>& args,
|
|||||||
iface_cstr = NULL;
|
iface_cstr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int r = uv_udp_set_membership(&wrap->handle_,
|
int err = uv_udp_set_membership(&wrap->handle_,
|
||||||
*address,
|
*address,
|
||||||
iface_cstr,
|
iface_cstr,
|
||||||
membership);
|
membership);
|
||||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
args.GetReturnValue().Set(err);
|
||||||
args.GetReturnValue().Set(r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -221,38 +219,50 @@ void UDPWrap::DropMembership(const FunctionCallbackInfo<Value>& args) {
|
|||||||
|
|
||||||
void UDPWrap::DoSend(const FunctionCallbackInfo<Value>& args, int family) {
|
void UDPWrap::DoSend(const FunctionCallbackInfo<Value>& args, int family) {
|
||||||
HandleScope scope(node_isolate);
|
HandleScope scope(node_isolate);
|
||||||
int r;
|
int err;
|
||||||
|
|
||||||
// send(buffer, offset, length, port, address)
|
|
||||||
assert(args.Length() == 5);
|
|
||||||
|
|
||||||
UNWRAP(UDPWrap)
|
UNWRAP(UDPWrap)
|
||||||
|
|
||||||
assert(Buffer::HasInstance(args[0]));
|
// send(req, buffer, offset, length, port, address)
|
||||||
Local<Object> buffer_obj = args[0]->ToObject();
|
assert(args[0]->IsObject());
|
||||||
|
assert(Buffer::HasInstance(args[1]));
|
||||||
|
assert(args[2]->IsUint32());
|
||||||
|
assert(args[3]->IsUint32());
|
||||||
|
assert(args[4]->IsUint32());
|
||||||
|
assert(args[5]->IsString());
|
||||||
|
|
||||||
|
Local<Object> req_wrap_obj = args[0].As<Object>();
|
||||||
|
Local<Object> buffer_obj = args[1].As<Object>();
|
||||||
|
size_t offset = args[2]->Uint32Value();
|
||||||
|
size_t length = args[3]->Uint32Value();
|
||||||
|
const unsigned short port = args[4]->Uint32Value();
|
||||||
|
String::Utf8Value address(args[5]);
|
||||||
|
|
||||||
size_t offset = args[1]->Uint32Value();
|
|
||||||
size_t length = args[2]->Uint32Value();
|
|
||||||
assert(offset < Buffer::Length(buffer_obj));
|
assert(offset < Buffer::Length(buffer_obj));
|
||||||
assert(length <= Buffer::Length(buffer_obj) - offset);
|
assert(length <= Buffer::Length(buffer_obj) - offset);
|
||||||
|
|
||||||
SendWrap* req_wrap = new SendWrap();
|
SendWrap* req_wrap = new SendWrap(req_wrap_obj);
|
||||||
req_wrap->object()->SetHiddenValue(buffer_sym, buffer_obj);
|
req_wrap->object()->SetHiddenValue(buffer_sym, buffer_obj);
|
||||||
|
|
||||||
uv_buf_t buf = uv_buf_init(Buffer::Data(buffer_obj) + offset,
|
uv_buf_t buf = uv_buf_init(Buffer::Data(buffer_obj) + offset,
|
||||||
length);
|
length);
|
||||||
|
|
||||||
const unsigned short port = args[3]->Uint32Value();
|
|
||||||
String::Utf8Value address(args[4]);
|
|
||||||
|
|
||||||
switch (family) {
|
switch (family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
r = uv_udp_send(&req_wrap->req_, &wrap->handle_, &buf, 1,
|
err = uv_udp_send(&req_wrap->req_,
|
||||||
uv_ip4_addr(*address, port), OnSend);
|
&wrap->handle_,
|
||||||
|
&buf,
|
||||||
|
1,
|
||||||
|
uv_ip4_addr(*address, port),
|
||||||
|
OnSend);
|
||||||
break;
|
break;
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
r = uv_udp_send6(&req_wrap->req_, &wrap->handle_, &buf, 1,
|
err = uv_udp_send6(&req_wrap->req_,
|
||||||
uv_ip6_addr(*address, port), OnSend);
|
&wrap->handle_,
|
||||||
|
&buf,
|
||||||
|
1,
|
||||||
|
uv_ip6_addr(*address, port),
|
||||||
|
OnSend);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0 && "unexpected address family");
|
assert(0 && "unexpected address family");
|
||||||
@ -260,14 +270,9 @@ void UDPWrap::DoSend(const FunctionCallbackInfo<Value>& args, int family) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
req_wrap->Dispatched();
|
req_wrap->Dispatched();
|
||||||
|
if (err) delete req_wrap;
|
||||||
|
|
||||||
if (r) {
|
args.GetReturnValue().Set(err);
|
||||||
SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
delete req_wrap;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
args.GetReturnValue().Set(req_wrap->persistent());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -285,11 +290,10 @@ void UDPWrap::RecvStart(const FunctionCallbackInfo<Value>& args) {
|
|||||||
HandleScope scope(node_isolate);
|
HandleScope scope(node_isolate);
|
||||||
UNWRAP(UDPWrap)
|
UNWRAP(UDPWrap)
|
||||||
|
|
||||||
|
int err = uv_udp_recv_start(&wrap->handle_, OnAlloc, OnRecv);
|
||||||
// UV_EALREADY means that the socket is already bound but that's okay
|
// UV_EALREADY means that the socket is already bound but that's okay
|
||||||
int r = uv_udp_recv_start(&wrap->handle_, OnAlloc, OnRecv);
|
if (err == UV_EALREADY) err = 0;
|
||||||
bool ok = r == 0 || uv_last_error(uv_default_loop()).code == UV_EALREADY;
|
args.GetReturnValue().Set(err);
|
||||||
if (ok == false) SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
args.GetReturnValue().Set(ok);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -307,14 +311,20 @@ void UDPWrap::GetSockName(const FunctionCallbackInfo<Value>& args) {
|
|||||||
struct sockaddr_storage address;
|
struct sockaddr_storage address;
|
||||||
UNWRAP(UDPWrap)
|
UNWRAP(UDPWrap)
|
||||||
|
|
||||||
int addrlen = sizeof(address);
|
assert(args[0]->IsObject());
|
||||||
int r = uv_udp_getsockname(&wrap->handle_,
|
Local<Object> obj = args[0].As<Object>();
|
||||||
reinterpret_cast<sockaddr*>(&address),
|
|
||||||
&addrlen);
|
|
||||||
if (r) return SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
|
|
||||||
const sockaddr* addr = reinterpret_cast<const sockaddr*>(&address);
|
int addrlen = sizeof(address);
|
||||||
args.GetReturnValue().Set(AddressToJS(addr));
|
int err = uv_udp_getsockname(&wrap->handle_,
|
||||||
|
reinterpret_cast<sockaddr*>(&address),
|
||||||
|
&addrlen);
|
||||||
|
|
||||||
|
if (err == 0) {
|
||||||
|
const sockaddr* addr = reinterpret_cast<const sockaddr*>(&address);
|
||||||
|
AddressToJS(addr, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
args.GetReturnValue().Set(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -330,12 +340,8 @@ void UDPWrap::OnSend(uv_udp_send_t* req, int status) {
|
|||||||
assert(req_wrap->persistent().IsEmpty() == false);
|
assert(req_wrap->persistent().IsEmpty() == false);
|
||||||
assert(wrap->persistent().IsEmpty() == false);
|
assert(wrap->persistent().IsEmpty() == false);
|
||||||
|
|
||||||
if (status) {
|
|
||||||
SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
}
|
|
||||||
|
|
||||||
Local<Object> req_wrap_obj = req_wrap->object();
|
Local<Object> req_wrap_obj = req_wrap->object();
|
||||||
Local<Value> argv[4] = {
|
Local<Value> argv[] = {
|
||||||
Integer::New(status, node_isolate),
|
Integer::New(status, node_isolate),
|
||||||
wrap->object(),
|
wrap->object(),
|
||||||
req_wrap_obj,
|
req_wrap_obj,
|
||||||
@ -362,34 +368,34 @@ void UDPWrap::OnRecv(uv_udp_t* handle,
|
|||||||
uv_buf_t buf,
|
uv_buf_t buf,
|
||||||
struct sockaddr* addr,
|
struct sockaddr* addr,
|
||||||
unsigned flags) {
|
unsigned flags) {
|
||||||
HandleScope scope(node_isolate);
|
|
||||||
|
|
||||||
UDPWrap* wrap = reinterpret_cast<UDPWrap*>(handle->data);
|
|
||||||
|
|
||||||
if (nread < 0) {
|
|
||||||
if (buf.base != NULL)
|
|
||||||
free(buf.base);
|
|
||||||
Local<Object> wrap_obj = wrap->object();
|
|
||||||
Local<Value> argv[] = { wrap_obj };
|
|
||||||
SetErrno(uv_last_error(uv_default_loop()));
|
|
||||||
MakeCallback(wrap_obj, onmessage_sym, ARRAY_SIZE(argv), argv);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nread == 0) {
|
if (nread == 0) {
|
||||||
if (buf.base != NULL)
|
if (buf.base != NULL)
|
||||||
free(buf.base);
|
free(buf.base);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
buf.base = static_cast<char*>(realloc(buf.base, nread));
|
UDPWrap* wrap = reinterpret_cast<UDPWrap*>(handle->data);
|
||||||
|
|
||||||
|
HandleScope scope(node_isolate);
|
||||||
Local<Object> wrap_obj = wrap->object();
|
Local<Object> wrap_obj = wrap->object();
|
||||||
Local<Value> argv[] = {
|
Local<Value> argv[] = {
|
||||||
|
Integer::New(nread, node_isolate),
|
||||||
wrap_obj,
|
wrap_obj,
|
||||||
Buffer::Use(buf.base, nread),
|
Undefined(),
|
||||||
AddressToJS(addr)
|
Undefined()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (nread < 0) {
|
||||||
|
if (buf.base != NULL)
|
||||||
|
free(buf.base);
|
||||||
|
MakeCallback(wrap_obj, onmessage_sym, ARRAY_SIZE(argv), argv);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.base = static_cast<char*>(realloc(buf.base, nread));
|
||||||
|
|
||||||
|
argv[2] = Buffer::Use(buf.base, nread);
|
||||||
|
argv[3] = AddressToJS(addr);
|
||||||
MakeCallback(wrap_obj, onmessage_sym, ARRAY_SIZE(argv), argv);
|
MakeCallback(wrap_obj, onmessage_sym, ARRAY_SIZE(argv), argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user