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:
Родитель
0161ec87af
Коммит
ca9eb718fb
|
@ -23,10 +23,13 @@ var StringDecoder = require('string_decoder').StringDecoder;
|
|||
var EventEmitter = require('events').EventEmitter;
|
||||
var net = require('net');
|
||||
var dgram = require('dgram');
|
||||
var Process = process.binding('process_wrap').Process;
|
||||
var assert = require('assert');
|
||||
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 handleWraps = {};
|
||||
|
@ -326,7 +329,8 @@ function setupChannel(target, channel) {
|
|||
var decoder = new StringDecoder('utf8');
|
||||
var jsonBuffer = '';
|
||||
channel.buffering = false;
|
||||
channel.onread = function(pool, recvHandle) {
|
||||
channel.onread = function(nread, pool, recvHandle) {
|
||||
// TODO(bnoordhuis) Check that nread > 0.
|
||||
if (pool) {
|
||||
jsonBuffer += decoder.write(pool);
|
||||
|
||||
|
@ -449,22 +453,18 @@ function setupChannel(target, channel) {
|
|||
return;
|
||||
}
|
||||
|
||||
var req = { oncomplete: nop };
|
||||
var string = JSON.stringify(message) + '\n';
|
||||
var writeReq = channel.writeUtf8String(string, handle);
|
||||
var err = channel.writeUtf8String(req, string, handle);
|
||||
|
||||
if (!writeReq) {
|
||||
var er = errnoException(process._errno,
|
||||
'write',
|
||||
'cannot write to IPC channel.');
|
||||
this.emit('error', er);
|
||||
if (err) {
|
||||
this.emit('error', errnoException(err, 'write'));
|
||||
} else if (handle && !this._handleQueue) {
|
||||
this._handleQueue = [];
|
||||
}
|
||||
|
||||
if (obj && obj.postSend) {
|
||||
writeReq.oncomplete = obj.postSend.bind(null, handle);
|
||||
} else {
|
||||
writeReq.oncomplete = nop;
|
||||
req.oncomplete = obj.postSend.bind(null, handle);
|
||||
}
|
||||
|
||||
/* 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 timeoutId;
|
||||
|
||||
var err;
|
||||
var ex;
|
||||
|
||||
function exithandler(code, signal) {
|
||||
if (exited) return;
|
||||
|
@ -630,21 +630,21 @@ exports.execFile = function(file /* args, options, callback */) {
|
|||
|
||||
if (!callback) return;
|
||||
|
||||
if (err) {
|
||||
callback(err, stdout, stderr);
|
||||
if (ex) {
|
||||
callback(ex, stdout, stderr);
|
||||
} else if (code === 0 && signal === null) {
|
||||
callback(null, stdout, stderr);
|
||||
} else {
|
||||
var e = new Error('Command failed: ' + stderr);
|
||||
e.killed = child.killed || killed;
|
||||
e.code = code;
|
||||
e.signal = signal;
|
||||
callback(e, stdout, stderr);
|
||||
ex = new Error('Command failed: ' + stderr);
|
||||
ex.killed = child.killed || killed;
|
||||
ex.code = code < 0 ? uv.errname(code) : code;
|
||||
ex.signal = signal;
|
||||
callback(ex, stdout, stderr);
|
||||
}
|
||||
}
|
||||
|
||||
function errorhandler(e) {
|
||||
err = e;
|
||||
ex = e;
|
||||
child.stdout.destroy();
|
||||
child.stderr.destroy();
|
||||
exithandler();
|
||||
|
@ -658,7 +658,7 @@ exports.execFile = function(file /* args, options, callback */) {
|
|||
try {
|
||||
child.kill(options.killSignal);
|
||||
} catch (e) {
|
||||
err = e;
|
||||
ex = e;
|
||||
exithandler();
|
||||
}
|
||||
}
|
||||
|
@ -676,7 +676,7 @@ exports.execFile = function(file /* args, options, callback */) {
|
|||
child.stdout.addListener('data', function(chunk) {
|
||||
stdout += chunk;
|
||||
if (stdout.length > options.maxBuffer) {
|
||||
err = new Error('stdout maxBuffer exceeded.');
|
||||
ex = new Error('stdout maxBuffer exceeded.');
|
||||
kill();
|
||||
}
|
||||
});
|
||||
|
@ -684,7 +684,7 @@ exports.execFile = function(file /* args, options, callback */) {
|
|||
child.stderr.addListener('data', function(chunk) {
|
||||
stderr += chunk;
|
||||
if (stderr.length > options.maxBuffer) {
|
||||
err = new Error('stderr maxBuffer exceeded.');
|
||||
ex = new Error('stderr maxBuffer exceeded.');
|
||||
kill();
|
||||
}
|
||||
});
|
||||
|
@ -767,9 +767,9 @@ function ChildProcess() {
|
|||
//
|
||||
// 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) {
|
||||
self.signalCode = signalCode;
|
||||
|
@ -784,7 +784,7 @@ function ChildProcess() {
|
|||
self._handle.close();
|
||||
self._handle = null;
|
||||
|
||||
if (exitCode == -1) {
|
||||
if (exitCode < 0) {
|
||||
self.emit('error', err);
|
||||
} else {
|
||||
self.emit('exit', self.exitCode, self.signalCode);
|
||||
|
@ -913,9 +913,9 @@ ChildProcess.prototype.spawn = function(options) {
|
|||
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
|
||||
stdio.forEach(function(stdio) {
|
||||
if (stdio.type === 'pipe') {
|
||||
|
@ -925,7 +925,7 @@ ChildProcess.prototype.spawn = function(options) {
|
|||
|
||||
this._handle.close();
|
||||
this._handle = null;
|
||||
throw errnoException(process._errno, 'spawn');
|
||||
throw errnoException(err, 'spawn');
|
||||
}
|
||||
|
||||
this.pid = this._handle.pid;
|
||||
|
@ -966,7 +966,7 @@ ChildProcess.prototype.spawn = function(options) {
|
|||
// Add .send() method and start listening for IPC data
|
||||
if (ipc !== undefined) setupChannel(this, ipc);
|
||||
|
||||
return r;
|
||||
return err;
|
||||
};
|
||||
|
||||
|
||||
|
@ -990,19 +990,20 @@ ChildProcess.prototype.kill = function(sig) {
|
|||
}
|
||||
|
||||
if (this._handle) {
|
||||
var r = this._handle.kill(signal);
|
||||
if (r == 0) {
|
||||
var err = this._handle.kill(signal);
|
||||
if (err === 0) {
|
||||
/* Success. */
|
||||
this.killed = true;
|
||||
return true;
|
||||
} else if (process._errno == 'ESRCH') {
|
||||
}
|
||||
if (err === uv.UV_ESRCH) {
|
||||
/* 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. */
|
||||
throw errnoException(process._errno, 'kill');
|
||||
throw errnoException(err, 'kill');
|
||||
} else {
|
||||
/* 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.errno = '';
|
||||
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')
|
||||
this.handle = dgram._createSocketHandle(address, port, addressType, fd);
|
||||
rval = dgram._createSocketHandle(address, port, addressType, fd);
|
||||
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) {
|
||||
|
@ -116,10 +123,15 @@ RoundRobinHandle.prototype.add = function(worker, send) {
|
|||
|
||||
var self = this;
|
||||
function done() {
|
||||
if (self.handle.getsockname)
|
||||
send(null, { sockname: self.handle.getsockname() }, null);
|
||||
else
|
||||
if (self.handle.getsockname) {
|
||||
var out = {};
|
||||
var err = self.handle.getsockname(out);
|
||||
// TODO(bnoordhuis) Check err.
|
||||
send(null, { sockname: out }, null);
|
||||
}
|
||||
else {
|
||||
send(null, null, null); // UNIX socket.
|
||||
}
|
||||
self.handoff(worker); // In case there are connections pending.
|
||||
}
|
||||
|
||||
|
@ -143,7 +155,7 @@ RoundRobinHandle.prototype.remove = function(worker) {
|
|||
return true;
|
||||
};
|
||||
|
||||
RoundRobinHandle.prototype.distribute = function(handle) {
|
||||
RoundRobinHandle.prototype.distribute = function(err, handle) {
|
||||
this.handles.push(handle);
|
||||
var worker = this.free.shift();
|
||||
if (worker) this.handoff(worker);
|
||||
|
@ -164,7 +176,7 @@ RoundRobinHandle.prototype.handoff = function(worker) {
|
|||
if (reply.accepted)
|
||||
handle.close();
|
||||
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);
|
||||
});
|
||||
};
|
||||
|
@ -476,8 +488,9 @@ function workerInit() {
|
|||
|
||||
function onerror(message, cb) {
|
||||
function listen(backlog) {
|
||||
process._errno = message.errno;
|
||||
return -1;
|
||||
// Translate 'EADDRINUSE' error back to numeric value. This function
|
||||
// is called as sock._handle.listen().
|
||||
return process.binding('uv')['UV_' + message.errno];
|
||||
}
|
||||
function close() {
|
||||
}
|
||||
|
@ -503,10 +516,8 @@ function workerInit() {
|
|||
delete handles[key];
|
||||
key = undefined;
|
||||
}
|
||||
function getsockname() {
|
||||
var rv = {};
|
||||
if (key) return util._extend(rv, message.sockname);
|
||||
return rv;
|
||||
function getsockname(out) {
|
||||
if (key) util._extend(out, message.sockname);
|
||||
}
|
||||
// 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
|
||||
|
@ -530,7 +541,7 @@ function workerInit() {
|
|||
var server = handles[key];
|
||||
var accepted = (typeof server !== 'undefined');
|
||||
send({ ack: message.seq, accepted: accepted });
|
||||
if (accepted) server.onconnection(handle);
|
||||
if (accepted) server.onconnection(0, handle);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (port || address) {
|
||||
var r = handle.bind(address, port || 0, 0);
|
||||
if (r == -1) {
|
||||
var err = handle.bind(address, port || 0, 0);
|
||||
if (err) {
|
||||
handle.close();
|
||||
handle = null;
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -204,8 +204,9 @@ Socket.prototype.bind = function(/*port, address, callback*/) {
|
|||
if (!self._handle)
|
||||
return; // handle has been closed in the mean time
|
||||
|
||||
if (self._handle.bind(ip, port || 0, /*flags=*/ 0)) {
|
||||
self.emit('error', errnoException(process._errno, 'bind'));
|
||||
var err = self._handle.bind(ip, port || 0, /*flags=*/ 0);
|
||||
if (err) {
|
||||
self.emit('error', errnoException(err, 'bind'));
|
||||
self._bindState = BIND_STATE_UNBOUND;
|
||||
// Todo: close?
|
||||
return;
|
||||
|
@ -276,22 +277,18 @@ Socket.prototype.send = function(buffer,
|
|||
return;
|
||||
}
|
||||
|
||||
self._handle.lookup(address, function(err, ip) {
|
||||
if (err) {
|
||||
if (callback) callback(err);
|
||||
self.emit('error', err);
|
||||
self._handle.lookup(address, function(ex, ip) {
|
||||
if (ex) {
|
||||
if (callback) callback(ex);
|
||||
self.emit('error', ex);
|
||||
}
|
||||
else if (self._handle) {
|
||||
var req = self._handle.send(buffer, offset, length, port, ip);
|
||||
if (req) {
|
||||
req.oncomplete = afterSend;
|
||||
req.cb = callback;
|
||||
}
|
||||
else {
|
||||
var req = { cb: callback, oncomplete: afterSend };
|
||||
var err = self._handle.send(req, buffer, offset, length, port, ip);
|
||||
if (err) {
|
||||
// don't emit as error, dgram_legacy.js compatibility
|
||||
var err = errnoException(process._errno, 'send');
|
||||
process.nextTick(function() {
|
||||
callback(err);
|
||||
callback(errnoException(err, 'send'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -319,17 +316,20 @@ Socket.prototype.close = function() {
|
|||
Socket.prototype.address = function() {
|
||||
this._healthCheck();
|
||||
|
||||
var address = this._handle.getsockname();
|
||||
if (!address)
|
||||
throw errnoException(process._errno, 'getsockname');
|
||||
var out = {};
|
||||
var err = this._handle.getsockname(out);
|
||||
if (err) {
|
||||
throw errnoException(err, 'getsockname');
|
||||
}
|
||||
|
||||
return address;
|
||||
return out;
|
||||
};
|
||||
|
||||
|
||||
Socket.prototype.setBroadcast = function(arg) {
|
||||
if (this._handle.setBroadcast((arg) ? 1 : 0)) {
|
||||
throw errnoException(process._errno, 'setBroadcast');
|
||||
var err = this._handle.setBroadcast(arg ? 1 : 0);
|
||||
if (err) {
|
||||
throw errnoException(err, 'setBroadcast');
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -339,8 +339,9 @@ Socket.prototype.setTTL = function(arg) {
|
|||
throw new TypeError('Argument must be a number');
|
||||
}
|
||||
|
||||
if (this._handle.setTTL(arg)) {
|
||||
throw errnoException(process._errno, 'setTTL');
|
||||
var err = this._handle.setTTL(arg);
|
||||
if (err) {
|
||||
throw errnoException(err, 'setTTL');
|
||||
}
|
||||
|
||||
return arg;
|
||||
|
@ -352,8 +353,9 @@ Socket.prototype.setMulticastTTL = function(arg) {
|
|||
throw new TypeError('Argument must be a number');
|
||||
}
|
||||
|
||||
if (this._handle.setMulticastTTL(arg)) {
|
||||
throw errnoException(process._errno, 'setMulticastTTL');
|
||||
var err = this._handle.setMulticastTTL(arg);
|
||||
if (err) {
|
||||
throw errnoException(err, 'setMulticastTTL');
|
||||
}
|
||||
|
||||
return arg;
|
||||
|
@ -361,10 +363,9 @@ Socket.prototype.setMulticastTTL = function(arg) {
|
|||
|
||||
|
||||
Socket.prototype.setMulticastLoopback = function(arg) {
|
||||
arg = arg ? 1 : 0;
|
||||
|
||||
if (this._handle.setMulticastLoopback(arg)) {
|
||||
throw errnoException(process._errno, 'setMulticastLoopback');
|
||||
var err = this._handle.setMulticastLoopback(arg ? 1 : 0);
|
||||
if (err) {
|
||||
throw errnoException(err, 'setMulticastLoopback');
|
||||
}
|
||||
|
||||
return arg; // 0.4 compatibility
|
||||
|
@ -379,8 +380,9 @@ Socket.prototype.addMembership = function(multicastAddress,
|
|||
throw new Error('multicast address must be specified');
|
||||
}
|
||||
|
||||
if (this._handle.addMembership(multicastAddress, interfaceAddress)) {
|
||||
throw new errnoException(process._errno, 'addMembership');
|
||||
var err = this._handle.addMembership(multicastAddress, interfaceAddress);
|
||||
if (err) {
|
||||
throw new errnoException(err, 'addMembership');
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -393,8 +395,9 @@ Socket.prototype.dropMembership = function(multicastAddress,
|
|||
throw new Error('multicast address must be specified');
|
||||
}
|
||||
|
||||
if (this._handle.dropMembership(multicastAddress, interfaceAddress)) {
|
||||
throw new errnoException(process._errno, 'dropMembership');
|
||||
var err = this._handle.dropMembership(multicastAddress, interfaceAddress);
|
||||
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;
|
||||
if (!buf) {
|
||||
return self.emit('error', errnoException(process._errno, 'recvmsg'));
|
||||
if (nread < 0) {
|
||||
return self.emit('error', errnoException(nread, 'recvmsg'));
|
||||
}
|
||||
rinfo.size = buf.length; // compatibility
|
||||
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
|
||||
// USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
var cares = process.binding('cares_wrap');
|
||||
var net = require('net');
|
||||
var util = require('util');
|
||||
|
||||
var errnoException = util._errnoException;
|
||||
var cares = process.binding('cares_wrap');
|
||||
var uv = process.binding('uv');
|
||||
|
||||
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,
|
||||
// but the dns API should always invoke a callback asynchronously.
|
||||
//
|
||||
|
@ -98,28 +115,28 @@ exports.lookup = function(domain, family, callback) {
|
|||
return {};
|
||||
}
|
||||
|
||||
function onanswer(addresses) {
|
||||
if (addresses) {
|
||||
if (family) {
|
||||
callback(null, addresses[0], family);
|
||||
} else {
|
||||
callback(null, addresses[0], addresses[0].indexOf(':') >= 0 ? 6 : 4);
|
||||
}
|
||||
function onanswer(err, addresses) {
|
||||
if (err) {
|
||||
return callback(errnoException(err, 'getaddrinfo'));
|
||||
}
|
||||
if (family) {
|
||||
callback(null, addresses[0], family);
|
||||
} 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) {
|
||||
throw errnoException(process._errno, 'getaddrinfo');
|
||||
if (err) {
|
||||
throw errnoException(err, 'getaddrinfo');
|
||||
}
|
||||
|
||||
wrap.oncomplete = onanswer;
|
||||
req.oncomplete = onanswer;
|
||||
|
||||
callback.immediately = true;
|
||||
return wrap;
|
||||
return req;
|
||||
};
|
||||
|
||||
|
||||
|
@ -127,22 +144,22 @@ function resolver(bindingName) {
|
|||
var binding = cares[bindingName];
|
||||
|
||||
return function query(name, callback) {
|
||||
function onanswer(status, result) {
|
||||
if (!status) {
|
||||
function onanswer(err, result) {
|
||||
if (err)
|
||||
callback(errnoException(err, bindingName));
|
||||
else
|
||||
callback(null, result);
|
||||
} else {
|
||||
callback(errnoException(process._errno, bindingName));
|
||||
}
|
||||
}
|
||||
|
||||
callback = makeAsync(callback);
|
||||
var wrap = binding(name, onanswer);
|
||||
if (!wrap) {
|
||||
throw errnoException(process._errno, bindingName);
|
||||
var req = {};
|
||||
var err = binding(req, name, onanswer);
|
||||
if (err) {
|
||||
throw errnoException(err, bindingName);
|
||||
}
|
||||
|
||||
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.onchange = function(status, event, filename) {
|
||||
if (status) {
|
||||
if (status < 0) {
|
||||
self._handle.close();
|
||||
self.emit('error', errnoException(process._errno, 'watch'));
|
||||
self.emit('error', errnoException(status, 'watch'));
|
||||
} else {
|
||||
self.emit('change', event, filename);
|
||||
}
|
||||
|
@ -1016,11 +1016,10 @@ util.inherits(FSWatcher, EventEmitter);
|
|||
|
||||
FSWatcher.prototype.start = function(filename, persistent) {
|
||||
nullCheck(filename);
|
||||
var r = this._handle.start(pathModule._makeLong(filename), persistent);
|
||||
|
||||
if (r) {
|
||||
var err = this._handle.start(pathModule._makeLong(filename), persistent);
|
||||
if (err) {
|
||||
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 assert = require('assert');
|
||||
var cares = process.binding('cares_wrap');
|
||||
var uv = process.binding('uv');
|
||||
|
||||
var cluster;
|
||||
var errnoException = util._errnoException;
|
||||
|
@ -206,12 +207,11 @@ function onSocketFinish() {
|
|||
if (!this._handle || !this._handle.shutdown)
|
||||
return this.destroy();
|
||||
|
||||
var shutdownReq = this._handle.shutdown();
|
||||
var req = { oncomplete: afterShutdown };
|
||||
var err = this._handle.shutdown(req);
|
||||
|
||||
if (!shutdownReq)
|
||||
return this._destroy(errnoException(process._errno, 'shutdown'));
|
||||
|
||||
shutdownReq.oncomplete = afterShutdown;
|
||||
if (err)
|
||||
return this._destroy(errnoException(err, 'shutdown'));
|
||||
}
|
||||
|
||||
|
||||
|
@ -338,7 +338,10 @@ Socket.prototype.setKeepAlive = function(setting, msecs) {
|
|||
|
||||
Socket.prototype.address = function() {
|
||||
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;
|
||||
};
|
||||
|
@ -381,9 +384,9 @@ Socket.prototype._read = function(n) {
|
|||
// not already reading, start the flow
|
||||
debug('Socket._read readStart');
|
||||
this._handle.reading = true;
|
||||
var r = this._handle.readStart();
|
||||
if (r)
|
||||
this._destroy(errnoException(process._errno, 'read'));
|
||||
var err = this._handle.readStart();
|
||||
if (err)
|
||||
this._destroy(errnoException(err, 'read'));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -486,17 +489,16 @@ Socket.prototype.destroy = function(exception) {
|
|||
|
||||
// This function is called whenever the handle gets a
|
||||
// buffer, or when there's an error reading.
|
||||
function onread(buffer) {
|
||||
function onread(nread, buffer) {
|
||||
var handle = this;
|
||||
var self = handle.owner;
|
||||
var length = !!buffer ? buffer.length : 0;
|
||||
assert(handle === self._handle, 'handle != self._handle');
|
||||
|
||||
timers._unrefActive(self);
|
||||
|
||||
debug('onread', process._errno, length);
|
||||
debug('onread', nread);
|
||||
|
||||
if (buffer) {
|
||||
if (nread > 0) {
|
||||
debug('got data');
|
||||
|
||||
// read success.
|
||||
|
@ -504,16 +506,9 @@ function onread(buffer) {
|
|||
// will prevent this from being called again until _read() gets
|
||||
// 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()
|
||||
// again right away.
|
||||
self.bytesRead += length;
|
||||
self.bytesRead += nread;
|
||||
|
||||
// Optimization: emit the original buffer with end points
|
||||
var ret = true;
|
||||
|
@ -523,33 +518,41 @@ function onread(buffer) {
|
|||
if (handle.reading && !ret) {
|
||||
handle.reading = false;
|
||||
debug('readStop');
|
||||
var r = handle.readStop();
|
||||
if (r)
|
||||
self._destroy(errnoException(process._errno, 'read'));
|
||||
var err = handle.readStop();
|
||||
if (err)
|
||||
self._destroy(errnoException(err, 'read'));
|
||||
}
|
||||
|
||||
} 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'));
|
||||
return;
|
||||
}
|
||||
|
||||
// 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 {};
|
||||
}
|
||||
if (!this._peername) {
|
||||
this._peername = this._handle.getpeername();
|
||||
if (!this._peername) {
|
||||
return {};
|
||||
}
|
||||
var out = {};
|
||||
var err = this._handle.getpeername(out);
|
||||
if (err) return {}; // FIXME(bnoordhuis) Throw?
|
||||
this._peername = out;
|
||||
}
|
||||
return this._peername;
|
||||
};
|
||||
|
@ -582,10 +585,10 @@ Socket.prototype._getsockname = function() {
|
|||
return {};
|
||||
}
|
||||
if (!this._sockname) {
|
||||
this._sockname = this._handle.getsockname();
|
||||
if (!this._sockname) {
|
||||
return {};
|
||||
}
|
||||
var out = {};
|
||||
var err = this._handle.getsockname(out);
|
||||
if (err) return {}; // FIXME(bnoordhuis) Throw?
|
||||
this._sockname = out;
|
||||
}
|
||||
return this._sockname;
|
||||
};
|
||||
|
@ -630,7 +633,9 @@ Socket.prototype._writeGeneric = function(writev, data, encoding, cb) {
|
|||
return false;
|
||||
}
|
||||
|
||||
var writeReq;
|
||||
var req = { oncomplete: afterWrite };
|
||||
var err;
|
||||
|
||||
if (writev) {
|
||||
var chunks = new Array(data.length << 1);
|
||||
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 + 1] = enc;
|
||||
}
|
||||
var writeReq = this._handle.writev(chunks);
|
||||
err = this._handle.writev(req, chunks);
|
||||
|
||||
// Retain chunks
|
||||
if (writeReq)
|
||||
writeReq._chunks = chunks;
|
||||
if (err === 0) req._chunks = chunks;
|
||||
} else {
|
||||
var enc = Buffer.isBuffer(data) ? 'buffer' : encoding;
|
||||
var writeReq = createWriteReq(this._handle, data, enc);
|
||||
err = createWriteReq(req, this._handle, data, enc);
|
||||
}
|
||||
|
||||
if (!writeReq)
|
||||
return this._destroy(errnoException(process._errno, 'write'), cb);
|
||||
if (err)
|
||||
return this._destroy(errnoException(err, 'write'), cb);
|
||||
|
||||
writeReq.oncomplete = afterWrite;
|
||||
this._bytesDispatched += writeReq.bytes;
|
||||
this._bytesDispatched += req.bytes;
|
||||
|
||||
// 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.
|
||||
if (this._handle.writeQueueSize === 0)
|
||||
cb();
|
||||
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) {
|
||||
case 'buffer':
|
||||
return handle.writeBuffer(data);
|
||||
return handle.writeBuffer(req, data);
|
||||
|
||||
case 'utf8':
|
||||
case 'utf-8':
|
||||
return handle.writeUtf8String(data);
|
||||
return handle.writeUtf8String(req, data);
|
||||
|
||||
case 'ascii':
|
||||
return handle.writeAsciiString(data);
|
||||
return handle.writeAsciiString(req, data);
|
||||
|
||||
case 'ucs2':
|
||||
case 'ucs-2':
|
||||
case 'utf16le':
|
||||
case 'utf-16le':
|
||||
return handle.writeUcs2String(data);
|
||||
return handle.writeUcs2String(req, data);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (status) {
|
||||
debug('write failure', errnoException(process._errno, 'write'));
|
||||
self._destroy(errnoException(process._errno, 'write'), req.cb);
|
||||
if (status < 0) {
|
||||
var ex = errnoException(status, 'write');
|
||||
debug('write failure', ex);
|
||||
self._destroy(ex, req.cb);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -780,33 +784,31 @@ function connect(self, address, port, addressType, localAddress) {
|
|||
|
||||
assert.ok(self._connecting);
|
||||
|
||||
var err;
|
||||
if (localAddress) {
|
||||
var r;
|
||||
if (addressType == 6) {
|
||||
r = self._handle.bind6(localAddress);
|
||||
err = self._handle.bind6(localAddress);
|
||||
} else {
|
||||
r = self._handle.bind(localAddress);
|
||||
err = self._handle.bind(localAddress);
|
||||
}
|
||||
|
||||
if (r) {
|
||||
self._destroy(errnoException(process._errno, 'bind'));
|
||||
if (err) {
|
||||
self._destroy(errnoException(err, 'bind'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var connectReq;
|
||||
var req = { oncomplete: afterConnect };
|
||||
if (addressType == 6) {
|
||||
connectReq = self._handle.connect6(address, port);
|
||||
err = self._handle.connect6(req, address, port);
|
||||
} else if (addressType == 4) {
|
||||
connectReq = self._handle.connect(address, port);
|
||||
err = self._handle.connect(req, address, port);
|
||||
} else {
|
||||
connectReq = self._handle.connect(address, afterConnect);
|
||||
err = self._handle.connect(req, address, afterConnect);
|
||||
}
|
||||
|
||||
if (connectReq !== null) {
|
||||
connectReq.oncomplete = afterConnect;
|
||||
} else {
|
||||
self._destroy(errnoException(process._errno, 'connect'));
|
||||
if (err) {
|
||||
self._destroy(errnoException(err, 'connect'));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -937,7 +939,7 @@ function afterConnect(status, handle, req, readable, writable) {
|
|||
|
||||
} else {
|
||||
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 =
|
||||
function(address, port, addressType, fd) {
|
||||
var r = 0;
|
||||
var err = 0;
|
||||
// assign handle in listen, and clean up if bind or listen fails
|
||||
var handle;
|
||||
|
||||
|
@ -1003,8 +1005,7 @@ var createServerHandle = exports._createServerHandle =
|
|||
catch (e) {
|
||||
// Not a fd we can listen on. This will trigger an error.
|
||||
debug('listen invalid fd=' + fd + ': ' + e.message);
|
||||
process._errno = 'EINVAL'; // hack, callers expect that errno is set
|
||||
return null;
|
||||
return uv.UV_EINVAL;
|
||||
}
|
||||
handle.open(fd);
|
||||
handle.readable = true;
|
||||
|
@ -1026,15 +1027,15 @@ var createServerHandle = exports._createServerHandle =
|
|||
if (address || port) {
|
||||
debug('bind to ' + address);
|
||||
if (addressType == 6) {
|
||||
r = handle.bind6(address, port);
|
||||
err = handle.bind6(address, port);
|
||||
} else {
|
||||
r = handle.bind(address, port);
|
||||
err = handle.bind(address, port);
|
||||
}
|
||||
}
|
||||
|
||||
if (r) {
|
||||
if (err) {
|
||||
handle.close();
|
||||
handle = null;
|
||||
return err;
|
||||
}
|
||||
|
||||
return handle;
|
||||
|
@ -1044,20 +1045,20 @@ var createServerHandle = exports._createServerHandle =
|
|||
Server.prototype._listen2 = function(address, port, addressType, backlog, fd) {
|
||||
debug('listen2', address, port, addressType, backlog);
|
||||
var self = this;
|
||||
var r = 0;
|
||||
|
||||
// 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.
|
||||
if (!self._handle) {
|
||||
debug('_listen2: create a handle');
|
||||
self._handle = createServerHandle(address, port, addressType, fd);
|
||||
if (!self._handle) {
|
||||
var error = errnoException(process._errno, 'listen');
|
||||
var rval = createServerHandle(address, port, addressType, fd);
|
||||
if (typeof rval === 'number') {
|
||||
var error = errnoException(rval, 'listen');
|
||||
process.nextTick(function() {
|
||||
self.emit('error', error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
self._handle = rval;
|
||||
} else {
|
||||
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
|
||||
// the kernel does: backlogsize = roundup_pow_of_two(backlogsize + 1);
|
||||
// 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) {
|
||||
var ex = errnoException(process._errno, 'listen');
|
||||
if (err) {
|
||||
var ex = errnoException(err, 'listen');
|
||||
self._handle.close();
|
||||
self._handle = null;
|
||||
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
|
||||
// we requested and if not, raise an error. The exception is when port == 0
|
||||
// because that means "any random port".
|
||||
if (port && handle.getsockname && port != handle.getsockname().port) {
|
||||
self.emit('error', errnoException('EADDRINUSE', 'bind'));
|
||||
return;
|
||||
if (port && handle.getsockname) {
|
||||
var out = {};
|
||||
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;
|
||||
|
@ -1176,7 +1183,10 @@ Server.prototype.listen = function() {
|
|||
|
||||
Server.prototype.address = function() {
|
||||
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) {
|
||||
return this._pipeName;
|
||||
} else {
|
||||
|
@ -1184,14 +1194,14 @@ Server.prototype.address = function() {
|
|||
}
|
||||
};
|
||||
|
||||
function onconnection(clientHandle) {
|
||||
function onconnection(err, clientHandle) {
|
||||
var handle = this;
|
||||
var self = handle.owner;
|
||||
|
||||
debug('onconnection');
|
||||
|
||||
if (!clientHandle) {
|
||||
self.emit('error', errnoException(process._errno, 'accept'));
|
||||
if (err) {
|
||||
self.emit('error', errnoException(err, 'accept'));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
12
lib/tty.js
12
lib/tty.js
|
@ -79,8 +79,9 @@ function WriteStream(fd) {
|
|||
writable: true
|
||||
});
|
||||
|
||||
var winSize = this._handle.getWindowSize();
|
||||
if (winSize) {
|
||||
var winSize = [];
|
||||
var err = this._handle.getWindowSize(winSize);
|
||||
if (!err) {
|
||||
this.columns = winSize[0];
|
||||
this.rows = winSize[1];
|
||||
}
|
||||
|
@ -95,9 +96,10 @@ WriteStream.prototype.isTTY = true;
|
|||
WriteStream.prototype._refreshSize = function() {
|
||||
var oldCols = this.columns;
|
||||
var oldRows = this.rows;
|
||||
var winSize = this._handle.getWindowSize();
|
||||
if (!winSize) {
|
||||
this.emit('error', errnoException(process._errno, 'getWindowSize'));
|
||||
var winSize = [];
|
||||
var err = this._handle.getWindowSize(winSize);
|
||||
if (err) {
|
||||
this.emit('error', errnoException(err, 'getWindowSize'));
|
||||
return;
|
||||
}
|
||||
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 {
|
||||
public:
|
||||
QueryWrap() {
|
||||
QueryWrap(Local<Object> req_wrap_obj) {
|
||||
HandleScope scope(node_isolate);
|
||||
persistent().Reset(node_isolate, Object::New());
|
||||
persistent().Reset(node_isolate, req_wrap_obj);
|
||||
}
|
||||
|
||||
virtual ~QueryWrap() {
|
||||
|
@ -355,10 +310,10 @@ class QueryWrap {
|
|||
|
||||
void ParseError(int status) {
|
||||
assert(status != ARES_SUCCESS);
|
||||
SetAresErrno(status);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -378,6 +333,9 @@ class QueryWrap {
|
|||
|
||||
class QueryAWrap: public QueryWrap {
|
||||
public:
|
||||
QueryAWrap(Local<Object> req_wrap_obj) : QueryWrap(req_wrap_obj) {
|
||||
}
|
||||
|
||||
int Send(const char* name) {
|
||||
ares_query(ares_channel, name, ns_c_in, ns_t_a, Callback, GetQueryArg());
|
||||
return 0;
|
||||
|
@ -405,6 +363,9 @@ class QueryAWrap: public QueryWrap {
|
|||
|
||||
class QueryAaaaWrap: public QueryWrap {
|
||||
public:
|
||||
QueryAaaaWrap(Local<Object> req_wrap_obj) : QueryWrap(req_wrap_obj) {
|
||||
}
|
||||
|
||||
int Send(const char* name) {
|
||||
ares_query(ares_channel,
|
||||
name,
|
||||
|
@ -437,6 +398,9 @@ class QueryAaaaWrap: public QueryWrap {
|
|||
|
||||
class QueryCnameWrap: public QueryWrap {
|
||||
public:
|
||||
QueryCnameWrap(Local<Object> req_wrap_obj) : QueryWrap(req_wrap_obj) {
|
||||
}
|
||||
|
||||
int Send(const char* name) {
|
||||
ares_query(ares_channel,
|
||||
name,
|
||||
|
@ -472,6 +436,9 @@ class QueryCnameWrap: public QueryWrap {
|
|||
|
||||
class QueryMxWrap: public QueryWrap {
|
||||
public:
|
||||
QueryMxWrap(Local<Object> req_wrap_obj) : QueryWrap(req_wrap_obj) {
|
||||
}
|
||||
|
||||
int Send(const char* name) {
|
||||
ares_query(ares_channel, name, ns_c_in, ns_t_mx, Callback, GetQueryArg());
|
||||
return 0;
|
||||
|
@ -511,6 +478,9 @@ class QueryMxWrap: public QueryWrap {
|
|||
|
||||
class QueryNsWrap: public QueryWrap {
|
||||
public:
|
||||
QueryNsWrap(Local<Object> req_wrap_obj) : QueryWrap(req_wrap_obj) {
|
||||
}
|
||||
|
||||
int Send(const char* name) {
|
||||
ares_query(ares_channel, name, ns_c_in, ns_t_ns, Callback, GetQueryArg());
|
||||
return 0;
|
||||
|
@ -536,6 +506,9 @@ class QueryNsWrap: public QueryWrap {
|
|||
|
||||
class QueryTxtWrap: public QueryWrap {
|
||||
public:
|
||||
QueryTxtWrap(Local<Object> req_wrap_obj) : QueryWrap(req_wrap_obj) {
|
||||
}
|
||||
|
||||
int Send(const char* name) {
|
||||
ares_query(ares_channel, name, ns_c_in, ns_t_txt, Callback, GetQueryArg());
|
||||
return 0;
|
||||
|
@ -568,6 +541,9 @@ class QueryTxtWrap: public QueryWrap {
|
|||
|
||||
class QuerySrvWrap: public QueryWrap {
|
||||
public:
|
||||
QuerySrvWrap(Local<Object> req_wrap_obj) : QueryWrap(req_wrap_obj) {
|
||||
}
|
||||
|
||||
int Send(const char* name) {
|
||||
ares_query(ares_channel,
|
||||
name,
|
||||
|
@ -617,6 +593,9 @@ class QuerySrvWrap: public QueryWrap {
|
|||
|
||||
class QueryNaptrWrap: public QueryWrap {
|
||||
public:
|
||||
QueryNaptrWrap(Local<Object> req_wrap_obj) : QueryWrap(req_wrap_obj) {
|
||||
}
|
||||
|
||||
int Send(const char* name) {
|
||||
ares_query(ares_channel,
|
||||
name,
|
||||
|
@ -679,18 +658,21 @@ class QueryNaptrWrap: public QueryWrap {
|
|||
|
||||
class GetHostByAddrWrap: public QueryWrap {
|
||||
public:
|
||||
GetHostByAddrWrap(Local<Object> req_wrap_obj) : QueryWrap(req_wrap_obj) {
|
||||
}
|
||||
|
||||
int Send(const char* name) {
|
||||
int length, family;
|
||||
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);
|
||||
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);
|
||||
family = AF_INET6;
|
||||
} else {
|
||||
return ARES_ENOTIMP;
|
||||
return UV_EINVAL; // So errnoException() reports a proper error.
|
||||
}
|
||||
|
||||
ares_gethostbyaddr(ares_channel,
|
||||
|
@ -713,6 +695,9 @@ class GetHostByAddrWrap: public QueryWrap {
|
|||
|
||||
class GetHostByNameWrap: public QueryWrap {
|
||||
public:
|
||||
GetHostByNameWrap(Local<Object> req_wrap_obj) : QueryWrap(req_wrap_obj) {
|
||||
}
|
||||
|
||||
int Send(const char* name, int family) {
|
||||
ares_gethostbyname(ares_channel, name, family, Callback, GetQueryArg());
|
||||
return 0;
|
||||
|
@ -735,26 +720,27 @@ static void Query(const FunctionCallbackInfo<Value>& args) {
|
|||
HandleScope scope(node_isolate);
|
||||
|
||||
assert(!args.IsConstructCall());
|
||||
assert(args.Length() >= 2);
|
||||
assert(args[1]->IsFunction());
|
||||
assert(args[0]->IsObject());
|
||||
assert(args[1]->IsString());
|
||||
assert(args[2]->IsFunction());
|
||||
|
||||
Wrap* wrap = new Wrap();
|
||||
wrap->SetOnComplete(args[1]);
|
||||
Local<Object> req_wrap_obj = args[0].As<Object>();
|
||||
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
|
||||
// callback from the wrap->Send stack. This will destroy the wrap's internal
|
||||
// object reference, causing wrap->object() to return an empty handle.
|
||||
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);
|
||||
if (r) {
|
||||
SetAresErrno(r);
|
||||
delete wrap;
|
||||
} else {
|
||||
args.GetReturnValue().Set(object);
|
||||
}
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
|
||||
|
@ -763,27 +749,29 @@ static void QueryWithFamily(const FunctionCallbackInfo<Value>& args) {
|
|||
HandleScope scope(node_isolate);
|
||||
|
||||
assert(!args.IsConstructCall());
|
||||
assert(args.Length() >= 3);
|
||||
assert(args[2]->IsFunction());
|
||||
assert(args[0]->IsObject());
|
||||
assert(args[1]->IsString());
|
||||
assert(args[2]->IsInt32());
|
||||
assert(args[3]->IsFunction());
|
||||
|
||||
Wrap* wrap = new Wrap();
|
||||
wrap->SetOnComplete(args[2]);
|
||||
Local<Object> req_wrap_obj = args[0].As<Object>();
|
||||
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
|
||||
// callback from the wrap->Send stack. This will destroy the wrap's internal
|
||||
// object reference, causing wrap->object() to return an empty handle.
|
||||
Local<Object> object = Local<Object>::New(node_isolate, wrap->persistent());
|
||||
|
||||
String::Utf8Value name(args[0]);
|
||||
int family = args[1]->Int32Value();
|
||||
String::Utf8Value name(string);
|
||||
int err = wrap->Send(*name, family);
|
||||
if (err) delete wrap;
|
||||
|
||||
int r = wrap->Send(*name, family);
|
||||
if (r) {
|
||||
SetAresErrno(r);
|
||||
delete wrap;
|
||||
} else {
|
||||
args.GetReturnValue().Set(object);
|
||||
}
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
|
||||
|
@ -792,13 +780,12 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
|
|||
|
||||
GetAddrInfoReqWrap* req_wrap = (GetAddrInfoReqWrap*) req->data;
|
||||
|
||||
Local<Value> argv[1];
|
||||
Local<Value> argv[] = {
|
||||
Integer::New(status, node_isolate),
|
||||
Null(node_isolate)
|
||||
};
|
||||
|
||||
if (status) {
|
||||
// Error
|
||||
SetErrno(uv_last_error(uv_default_loop()));
|
||||
argv[0] = Null(node_isolate);
|
||||
} else {
|
||||
if (status == 0) {
|
||||
// Success
|
||||
struct addrinfo *address;
|
||||
int n = 0;
|
||||
|
@ -826,11 +813,11 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
|
|||
if (address->ai_family == AF_INET) {
|
||||
// Juggle pointers
|
||||
addr = (char*) &((struct sockaddr_in*) address->ai_addr)->sin_addr;
|
||||
uv_err_t err = uv_inet_ntop(address->ai_family,
|
||||
addr,
|
||||
ip,
|
||||
INET6_ADDRSTRLEN);
|
||||
if (err.code != UV_OK)
|
||||
int err = uv_inet_ntop(address->ai_family,
|
||||
addr,
|
||||
ip,
|
||||
INET6_ADDRSTRLEN);
|
||||
if (err)
|
||||
continue;
|
||||
|
||||
// Create JavaScript string
|
||||
|
@ -852,11 +839,11 @@ void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) {
|
|||
if (address->ai_family == AF_INET6) {
|
||||
// Juggle pointers
|
||||
addr = (char*) &((struct sockaddr_in6*) address->ai_addr)->sin6_addr;
|
||||
uv_err_t err = uv_inet_ntop(address->ai_family,
|
||||
addr,
|
||||
ip,
|
||||
INET6_ADDRSTRLEN);
|
||||
if (err.code != UV_OK)
|
||||
int err = uv_inet_ntop(address->ai_family,
|
||||
addr,
|
||||
ip,
|
||||
INET6_ADDRSTRLEN);
|
||||
if (err)
|
||||
continue;
|
||||
|
||||
// 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);
|
||||
|
@ -889,9 +876,9 @@ static void IsIP(const FunctionCallbackInfo<Value>& args) {
|
|||
char address_buffer[sizeof(struct in6_addr)];
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
args.GetReturnValue().Set(rc);
|
||||
|
@ -901,42 +888,45 @@ static void IsIP(const FunctionCallbackInfo<Value>& args) {
|
|||
static void GetAddrInfo(const FunctionCallbackInfo<Value>& args) {
|
||||
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;
|
||||
if (args[1]->IsInt32()) {
|
||||
switch (args[1]->Int32Value()) {
|
||||
case 6:
|
||||
fam = AF_INET6;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
fam = AF_INET;
|
||||
break;
|
||||
}
|
||||
int family;
|
||||
switch (args[2]->Int32Value()) {
|
||||
case 0:
|
||||
family = AF_UNSPEC;
|
||||
break;
|
||||
case 4:
|
||||
family = AF_INET;
|
||||
break;
|
||||
case 6:
|
||||
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;
|
||||
memset(&hints, 0, sizeof(struct addrinfo));
|
||||
hints.ai_family = fam;
|
||||
hints.ai_family = family;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
int r = uv_getaddrinfo(uv_default_loop(),
|
||||
&req_wrap->req_,
|
||||
AfterGetAddrInfo,
|
||||
*hostname,
|
||||
NULL,
|
||||
&hints);
|
||||
int err = uv_getaddrinfo(uv_default_loop(),
|
||||
&req_wrap->req_,
|
||||
AfterGetAddrInfo,
|
||||
*hostname,
|
||||
NULL,
|
||||
&hints);
|
||||
req_wrap->Dispatched();
|
||||
if (err) delete req_wrap;
|
||||
|
||||
if (r) {
|
||||
SetErrno(uv_last_error(uv_default_loop()));
|
||||
delete req_wrap;
|
||||
} else {
|
||||
args.GetReturnValue().Set(req_wrap->persistent());
|
||||
}
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
|
||||
|
@ -956,8 +946,8 @@ static void GetServers(const FunctionCallbackInfo<Value>& args) {
|
|||
char ip[INET6_ADDRSTRLEN];
|
||||
|
||||
const void* caddr = static_cast<const void*>(&cur->addr);
|
||||
uv_err_t err = uv_inet_ntop(cur->family, caddr, ip, sizeof(ip));
|
||||
assert(err.code == UV_OK);
|
||||
int err = uv_inet_ntop(cur->family, caddr, ip, sizeof(ip));
|
||||
assert(err == 0);
|
||||
|
||||
Local<String> addr = String::New(ip);
|
||||
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* last = NULL;
|
||||
|
||||
uv_err_t uv_ret;
|
||||
int err;
|
||||
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
assert(arr->Get(i)->IsArray());
|
||||
|
@ -1004,18 +994,18 @@ static void SetServers(const FunctionCallbackInfo<Value>& args) {
|
|||
switch (fam) {
|
||||
case 4:
|
||||
cur->family = AF_INET;
|
||||
uv_ret = uv_inet_pton(AF_INET, *ip, &cur->addr);
|
||||
err = uv_inet_pton(AF_INET, *ip, &cur->addr);
|
||||
break;
|
||||
case 6:
|
||||
cur->family = AF_INET6;
|
||||
uv_ret = uv_inet_pton(AF_INET6, *ip, &cur->addr);
|
||||
err = uv_inet_pton(AF_INET6, *ip, &cur->addr);
|
||||
break;
|
||||
default:
|
||||
assert(0 && "Bad address family.");
|
||||
abort();
|
||||
}
|
||||
|
||||
if (uv_ret.code != UV_OK)
|
||||
if (err)
|
||||
break;
|
||||
|
||||
cur->next = NULL;
|
||||
|
@ -1026,16 +1016,14 @@ static void SetServers(const FunctionCallbackInfo<Value>& args) {
|
|||
last = cur;
|
||||
}
|
||||
|
||||
int r;
|
||||
|
||||
if (uv_ret.code == UV_OK)
|
||||
r = ares_set_servers(ares_channel, &servers[0]);
|
||||
if (err == 0)
|
||||
err = ares_set_servers(ares_channel, &servers[0]);
|
||||
else
|
||||
r = ARES_EBADSTR;
|
||||
err = ARES_EBADSTR;
|
||||
|
||||
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]);
|
||||
|
||||
int r = uv_fs_event_init(uv_default_loop(), &wrap->handle_, *path, OnEvent, 0);
|
||||
if (r == 0) {
|
||||
int err = uv_fs_event_init(uv_default_loop(),
|
||||
&wrap->handle_,
|
||||
*path,
|
||||
OnEvent,
|
||||
0);
|
||||
if (err == 0) {
|
||||
// Check for persistent argument
|
||||
if (!args[1]->IsTrue()) {
|
||||
uv_unref(reinterpret_cast<uv_handle_t*>(&wrap->handle_));
|
||||
}
|
||||
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
|
||||
// unreasonable, right? Still, we should revisit this before v1.0.
|
||||
if (status) {
|
||||
SetErrno(uv_last_error(uv_default_loop()));
|
||||
eventStr = String::Empty(node_isolate);
|
||||
}
|
||||
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
|
||||
Local<Value> UVException(int errorno,
|
||||
const char *syscall,
|
||||
|
@ -803,9 +787,9 @@ Local<Value> UVException(int errorno,
|
|||
}
|
||||
|
||||
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> cons1 = String::Concat(estring, String::NewSymbol(", "));
|
||||
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) {
|
||||
HandleScope scope(node_isolate);
|
||||
|
||||
|
@ -1356,11 +1321,9 @@ static void Chdir(const FunctionCallbackInfo<Value>& args) {
|
|||
}
|
||||
|
||||
String::Utf8Value path(args[0]);
|
||||
|
||||
uv_err_t r = uv_chdir(*path);
|
||||
|
||||
if (r.code != UV_OK) {
|
||||
return ThrowUVException(r.code, "uv_chdir");
|
||||
int err = uv_chdir(*path);
|
||||
if (err) {
|
||||
return ThrowUVException(err, "uv_chdir");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1374,9 +1337,9 @@ static void Cwd(const FunctionCallbackInfo<Value>& args) {
|
|||
char buf[PATH_MAX + 1];
|
||||
#endif
|
||||
|
||||
uv_err_t r = uv_cwd(buf, ARRAY_SIZE(buf) - 1);
|
||||
if (r.code != UV_OK) {
|
||||
return ThrowUVException(r.code, "uv_cwd");
|
||||
int err = uv_cwd(buf, ARRAY_SIZE(buf) - 1);
|
||||
if (err) {
|
||||
return ThrowUVException(err, "uv_cwd");
|
||||
}
|
||||
|
||||
buf[ARRAY_SIZE(buf) - 1] = '\0';
|
||||
|
@ -1698,7 +1661,7 @@ void Exit(const FunctionCallbackInfo<Value>& args) {
|
|||
static void Uptime(const FunctionCallbackInfo<Value>& args) {
|
||||
HandleScope scope(node_isolate);
|
||||
double uptime;
|
||||
if (uv_uptime(&uptime).code != UV_OK) return;
|
||||
if (uv_uptime(&uptime)) return;
|
||||
args.GetReturnValue().Set(uptime - prog_start_time);
|
||||
}
|
||||
|
||||
|
@ -1708,10 +1671,9 @@ void MemoryUsage(const FunctionCallbackInfo<Value>& args) {
|
|||
|
||||
size_t rss;
|
||||
|
||||
uv_err_t err = uv_resident_set_memory(&rss);
|
||||
|
||||
if (err.code != UV_OK) {
|
||||
return ThrowUVException(err.code, "uv_resident_set_memory");
|
||||
int err = uv_resident_set_memory(&rss);
|
||||
if (err) {
|
||||
return ThrowUVException(err, "uv_resident_set_memory");
|
||||
}
|
||||
|
||||
Local<Object> info = Object::New();
|
||||
|
@ -1747,12 +1709,8 @@ void Kill(const FunctionCallbackInfo<Value>& args) {
|
|||
|
||||
int pid = args[0]->IntegerValue();
|
||||
int sig = args[1]->Int32Value();
|
||||
uv_err_t err = uv_kill(pid, sig);
|
||||
|
||||
if (err.code != UV_OK) {
|
||||
SetErrno(err);
|
||||
args.GetReturnValue().Set(-1);
|
||||
}
|
||||
int err = uv_kill(pid, sig);
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
// 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 SetErrno(uv_err_t err);
|
||||
|
||||
} // namespace node
|
||||
|
||||
#endif // SRC_NODE_H_
|
||||
|
|
16
src/node.js
16
src/node.js
|
@ -626,23 +626,23 @@
|
|||
};
|
||||
|
||||
process.kill = function(pid, sig) {
|
||||
var r;
|
||||
var err;
|
||||
|
||||
// preserve null signal
|
||||
if (0 === sig) {
|
||||
r = process._kill(pid, 0);
|
||||
err = process._kill(pid, 0);
|
||||
} else {
|
||||
sig = sig || 'SIGTERM';
|
||||
if (startup.lazyConstants()[sig]) {
|
||||
r = process._kill(pid, startup.lazyConstants()[sig]);
|
||||
err = process._kill(pid, startup.lazyConstants()[sig]);
|
||||
} else {
|
||||
throw new Error('Unknown signal: ' + sig);
|
||||
}
|
||||
}
|
||||
|
||||
if (r) {
|
||||
if (err) {
|
||||
var errnoException = NativeModule.require('util')._errnoException;
|
||||
throw errnoException(process._errno, 'kill');
|
||||
throw errnoException(err, 'kill');
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -673,11 +673,11 @@
|
|||
wrap.onsignal = function() { process.emit(type); };
|
||||
|
||||
var signum = startup.lazyConstants()[type];
|
||||
var r = wrap.start(signum);
|
||||
if (r) {
|
||||
var err = wrap.start(signum);
|
||||
if (err) {
|
||||
wrap.close();
|
||||
var errnoException = NativeModule.require('util')._errnoException;
|
||||
throw errnoException(process._errno, 'uv_signal_start');
|
||||
throw errnoException(err, 'uv_signal_start');
|
||||
}
|
||||
|
||||
signalWraps[type] = wrap;
|
||||
|
|
|
@ -104,17 +104,12 @@ static void After(uv_fs_t *req) {
|
|||
// (Feel free to increase this if you need more)
|
||||
Local<Value> argv[2];
|
||||
|
||||
// NOTE: This may be needed to be changed if something returns a -1
|
||||
// for a success, which is possible.
|
||||
if (req->result == -1) {
|
||||
if (req->result < 0) {
|
||||
// If the request doesn't have a path parameter set.
|
||||
|
||||
if (!req->path) {
|
||||
argv[0] = UVException(req->errorno,
|
||||
NULL,
|
||||
req_wrap->syscall());
|
||||
if (req->path == NULL) {
|
||||
argv[0] = UVException(req->result, NULL, req_wrap->syscall());
|
||||
} else {
|
||||
argv[0] = UVException(req->errorno,
|
||||
argv[0] = UVException(req->result,
|
||||
NULL,
|
||||
req_wrap->syscall(),
|
||||
static_cast<const char*>(req->path));
|
||||
|
@ -225,30 +220,29 @@ struct fs_req_wrap {
|
|||
|
||||
#define ASYNC_CALL(func, callback, ...) \
|
||||
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); \
|
||||
req_wrap->object()->Set(oncomplete_sym, callback); \
|
||||
req_wrap->Dispatched(); \
|
||||
if (r < 0) { \
|
||||
if (err < 0) { \
|
||||
uv_fs_t* req = &req_wrap->req_; \
|
||||
req->result = r; \
|
||||
req->result = err; \
|
||||
req->path = NULL; \
|
||||
req->errorno = uv_last_error(uv_default_loop()).code; \
|
||||
After(req); \
|
||||
} \
|
||||
args.GetReturnValue().Set(req_wrap->persistent());
|
||||
|
||||
#define SYNC_CALL(func, path, ...) \
|
||||
fs_req_wrap req_wrap; \
|
||||
int result = uv_fs_##func(uv_default_loop(), &req_wrap.req, __VA_ARGS__, NULL); \
|
||||
if (result < 0) { \
|
||||
int code = uv_last_error(uv_default_loop()).code; \
|
||||
return ThrowUVException(code, #func, "", path); \
|
||||
}
|
||||
int err = uv_fs_ ## func(uv_default_loop(), \
|
||||
&req_wrap.req, \
|
||||
__VA_ARGS__, \
|
||||
NULL); \
|
||||
if (err < 0) return ThrowUVException(err, #func, NULL, path); \
|
||||
|
||||
#define SYNC_REQ req_wrap.req
|
||||
|
||||
#define SYNC_RESULT result
|
||||
#define SYNC_RESULT err
|
||||
|
||||
|
||||
static void Close(const FunctionCallbackInfo<Value>& args) {
|
||||
|
|
|
@ -131,8 +131,8 @@ static void GetCPUInfo(const FunctionCallbackInfo<Value>& args) {
|
|||
uv_cpu_info_t* cpu_infos;
|
||||
int count, i;
|
||||
|
||||
uv_err_t err = uv_cpu_info(&cpu_infos, &count);
|
||||
if (err.code != UV_OK) return;
|
||||
int err = uv_cpu_info(&cpu_infos, &count);
|
||||
if (err) return;
|
||||
|
||||
Local<Array> cpus = Array::New();
|
||||
for (i = 0; i < count; i++) {
|
||||
|
@ -180,9 +180,8 @@ static void GetTotalMemory(const FunctionCallbackInfo<Value>& args) {
|
|||
static void GetUptime(const FunctionCallbackInfo<Value>& args) {
|
||||
HandleScope scope(node_isolate);
|
||||
double uptime;
|
||||
uv_err_t err = uv_uptime(&uptime);
|
||||
if (err.code != UV_OK) return;
|
||||
args.GetReturnValue().Set(uptime);
|
||||
int err = uv_uptime(&uptime);
|
||||
if (err == 0) args.GetReturnValue().Set(uptime);
|
||||
}
|
||||
|
||||
|
||||
|
@ -208,9 +207,9 @@ static void GetInterfaceAddresses(const FunctionCallbackInfo<Value>& args) {
|
|||
Local<String> name, family;
|
||||
Local<Array> ifarr;
|
||||
|
||||
uv_err_t err = uv_interface_addresses(&interfaces, &count);
|
||||
if (err.code != UV_OK) {
|
||||
return ThrowUVException(err.code, "uv_interface_addresses");
|
||||
int err = uv_interface_addresses(&interfaces, &count);
|
||||
if (err) {
|
||||
return ThrowUVException(err, "uv_interface_addresses");
|
||||
}
|
||||
|
||||
ret = Object::New();
|
||||
|
|
|
@ -86,9 +86,6 @@ void StatWatcher::Callback(uv_fs_poll_t* handle,
|
|||
argv[0] = BuildStatsObject(curr);
|
||||
argv[1] = BuildStatsObject(prev);
|
||||
argv[2] = Integer::New(status, node_isolate);
|
||||
if (status == -1) {
|
||||
SetErrno(uv_last_error(wrap->watcher_->loop));
|
||||
}
|
||||
if (onchange_sym.IsEmpty()) {
|
||||
onchange_sym = String::New("onchange");
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ using v8::Object;
|
|||
using v8::Persistent;
|
||||
using v8::PropertyAttribute;
|
||||
using v8::String;
|
||||
using v8::Undefined;
|
||||
using v8::Value;
|
||||
|
||||
static Persistent<Function> pipeConstructor;
|
||||
|
@ -145,13 +146,8 @@ void PipeWrap::Bind(const FunctionCallbackInfo<Value>& args) {
|
|||
UNWRAP(PipeWrap)
|
||||
|
||||
String::AsciiValue name(args[0]);
|
||||
|
||||
int r = uv_pipe_bind(&wrap->handle_, *name);
|
||||
|
||||
// Error starting the pipe.
|
||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
||||
|
||||
args.GetReturnValue().Set(r);
|
||||
int err = uv_pipe_bind(&wrap->handle_, *name);
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
|
||||
|
@ -174,15 +170,10 @@ void PipeWrap::Listen(const FunctionCallbackInfo<Value>& args) {
|
|||
UNWRAP(PipeWrap)
|
||||
|
||||
int backlog = args[0]->Int32Value();
|
||||
|
||||
int r = uv_listen(reinterpret_cast<uv_stream_t*>(&wrap->handle_),
|
||||
backlog,
|
||||
OnConnection);
|
||||
|
||||
// Error starting the pipe.
|
||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
||||
|
||||
args.GetReturnValue().Set(r);
|
||||
int err = uv_listen(reinterpret_cast<uv_stream_t*>(&wrap->handle_),
|
||||
backlog,
|
||||
OnConnection);
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
|
||||
|
@ -197,9 +188,13 @@ void PipeWrap::OnConnection(uv_stream_t* handle, int status) {
|
|||
// uv_close() on the handle.
|
||||
assert(wrap->persistent().IsEmpty() == false);
|
||||
|
||||
Local<Value> argv[] = {
|
||||
Integer::New(status, node_isolate),
|
||||
Undefined()
|
||||
};
|
||||
|
||||
if (status != 0) {
|
||||
SetErrno(uv_last_error(uv_default_loop()));
|
||||
MakeCallback(wrap->object(), "onconnection", 0, NULL);
|
||||
MakeCallback(wrap->object(), "onconnection", ARRAY_SIZE(argv), argv);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -215,7 +210,7 @@ void PipeWrap::OnConnection(uv_stream_t* handle, int status) {
|
|||
if (uv_accept(handle, client_handle)) return;
|
||||
|
||||
// Successful accept. Call the onconnection callback in JavaScript land.
|
||||
Local<Value> argv[1] = { client_obj };
|
||||
argv[1] = client_obj;
|
||||
if (onconnection_sym.IsEmpty()) {
|
||||
onconnection_sym = String::New("onconnection");
|
||||
}
|
||||
|
@ -236,7 +231,6 @@ void PipeWrap::AfterConnect(uv_connect_t* req, int status) {
|
|||
bool readable, writable;
|
||||
|
||||
if (status) {
|
||||
SetErrno(uv_last_error(uv_default_loop()));
|
||||
readable = writable = 0;
|
||||
} else {
|
||||
readable = uv_is_readable(req->handle) != 0;
|
||||
|
@ -277,18 +271,20 @@ void PipeWrap::Connect(const FunctionCallbackInfo<Value>& args) {
|
|||
|
||||
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_,
|
||||
&wrap->handle_,
|
||||
*name,
|
||||
AfterConnect);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int r = uv_spawn(uv_default_loop(), &wrap->process_, options);
|
||||
int err = uv_spawn(uv_default_loop(), &wrap->process_, options);
|
||||
|
||||
if (r) {
|
||||
SetErrno(uv_last_error(uv_default_loop()));
|
||||
}
|
||||
else {
|
||||
if (err == 0) {
|
||||
assert(wrap->process_.data == wrap);
|
||||
wrap->object()->Set(String::New("pid"),
|
||||
Integer::New(wrap->process_.pid, node_isolate));
|
||||
|
@ -240,7 +237,7 @@ class ProcessWrap : public HandleWrap {
|
|||
|
||||
delete[] options.stdio;
|
||||
|
||||
args.GetReturnValue().Set(r);
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
static void Kill(const FunctionCallbackInfo<Value>& args) {
|
||||
|
@ -248,9 +245,8 @@ class ProcessWrap : public HandleWrap {
|
|||
UNWRAP(ProcessWrap)
|
||||
|
||||
int signal = args[0]->Int32Value();
|
||||
int r = uv_process_kill(&wrap->process_, signal);
|
||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
||||
args.GetReturnValue().Set(r);
|
||||
int err = uv_process_kill(&wrap->process_, signal);
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
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->process_ == handle);
|
||||
|
||||
Local<Value> argv[2] = {
|
||||
Local<Value> argv[] = {
|
||||
Integer::New(exit_status, node_isolate),
|
||||
String::New(signo_string(term_signal))
|
||||
};
|
||||
|
||||
if (exit_status == -1) {
|
||||
SetErrno(uv_last_error(uv_default_loop()));
|
||||
}
|
||||
|
||||
if (onexit_sym.IsEmpty()) {
|
||||
onexit_sym = String::New("onexit");
|
||||
}
|
||||
|
|
|
@ -86,18 +86,16 @@ class SignalWrap : public HandleWrap {
|
|||
UNWRAP(SignalWrap)
|
||||
|
||||
int signum = args[0]->Int32Value();
|
||||
int r = uv_signal_start(&wrap->handle_, OnSignal, signum);
|
||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
||||
args.GetReturnValue().Set(r);
|
||||
int err = uv_signal_start(&wrap->handle_, OnSignal, signum);
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
static void Stop(const FunctionCallbackInfo<Value>& args) {
|
||||
HandleScope scope(node_isolate);
|
||||
UNWRAP(SignalWrap)
|
||||
|
||||
int r = uv_signal_stop(&wrap->handle_);
|
||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
||||
args.GetReturnValue().Set(r);
|
||||
int err = uv_signal_stop(&wrap->handle_);
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
static void OnSignal(uv_signal_t* handle, int signum) {
|
||||
|
|
|
@ -45,6 +45,7 @@ using v8::Number;
|
|||
using v8::Object;
|
||||
using v8::PropertyCallbackInfo;
|
||||
using v8::String;
|
||||
using v8::Undefined;
|
||||
using v8::Value;
|
||||
|
||||
|
||||
|
@ -106,17 +107,14 @@ void StreamWrap::ReadStart(const FunctionCallbackInfo<Value>& args) {
|
|||
|
||||
bool ipc_pipe = wrap->stream_->type == UV_NAMED_PIPE &&
|
||||
reinterpret_cast<uv_pipe_t*>(wrap->stream_)->ipc;
|
||||
int r;
|
||||
int err;
|
||||
if (ipc_pipe) {
|
||||
r = uv_read2_start(wrap->stream_, OnAlloc, OnRead2);
|
||||
err = uv_read2_start(wrap->stream_, OnAlloc, OnRead2);
|
||||
} else {
|
||||
r = uv_read_start(wrap->stream_, OnAlloc, OnRead);
|
||||
err = uv_read_start(wrap->stream_, OnAlloc, OnRead);
|
||||
}
|
||||
|
||||
// Error starting the tcp.
|
||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
||||
|
||||
args.GetReturnValue().Set(r);
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
|
||||
|
@ -125,12 +123,8 @@ void StreamWrap::ReadStop(const FunctionCallbackInfo<Value>& args) {
|
|||
|
||||
UNWRAP(StreamWrap)
|
||||
|
||||
int r = uv_read_stop(wrap->stream_);
|
||||
|
||||
// Error starting the tcp.
|
||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
||||
|
||||
args.GetReturnValue().Set(r);
|
||||
int err = uv_read_stop(wrap->stream_);
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
|
||||
|
@ -215,48 +209,50 @@ void StreamWrap::WriteBuffer(const FunctionCallbackInfo<Value>& args) {
|
|||
|
||||
UNWRAP(StreamWrap)
|
||||
|
||||
// The first argument is a buffer.
|
||||
assert(args.Length() >= 1 && Buffer::HasInstance(args[0]));
|
||||
size_t length = Buffer::Length(args[0]);
|
||||
char* storage = new char[sizeof(WriteWrap)];
|
||||
WriteWrap* req_wrap = new (storage) WriteWrap(wrap);
|
||||
assert(args[0]->IsObject());
|
||||
assert(Buffer::HasInstance(args[1]));
|
||||
|
||||
Local<Object> req_wrap_obj = req_wrap->object();
|
||||
req_wrap_obj->SetHiddenValue(buffer_sym, args[0]);
|
||||
Local<Object> req_wrap_obj = args[0].As<Object>();
|
||||
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;
|
||||
WriteBuffer(args[0], &buf);
|
||||
|
||||
int r = wrap->callbacks_->DoWrite(req_wrap,
|
||||
&buf,
|
||||
1,
|
||||
NULL,
|
||||
StreamWrap::AfterWrite);
|
||||
WriteBuffer(buf_obj, &buf);
|
||||
|
||||
int err = wrap->callbacks_->DoWrite(req_wrap,
|
||||
&buf,
|
||||
1,
|
||||
NULL,
|
||||
StreamWrap::AfterWrite);
|
||||
req_wrap->Dispatched();
|
||||
req_wrap_obj->Set(bytes_sym, Integer::NewFromUnsigned(length, node_isolate));
|
||||
|
||||
if (r) {
|
||||
SetErrno(uv_last_error(uv_default_loop()));
|
||||
if (err) {
|
||||
req_wrap->~WriteWrap();
|
||||
delete[] storage;
|
||||
} else {
|
||||
args.GetReturnValue().Set(req_wrap->persistent());
|
||||
}
|
||||
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
|
||||
template <enum encoding encoding>
|
||||
void StreamWrap::WriteStringImpl(const FunctionCallbackInfo<Value>& args) {
|
||||
HandleScope scope(node_isolate);
|
||||
int r;
|
||||
int err;
|
||||
|
||||
UNWRAP(StreamWrap)
|
||||
|
||||
if (args.Length() < 1)
|
||||
return ThrowTypeError("Not enough arguments");
|
||||
assert(args[0]->IsObject());
|
||||
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.
|
||||
// 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);
|
||||
|
||||
if (storage_size > INT_MAX) {
|
||||
uv_err_t err;
|
||||
err.code = UV_ENOBUFS;
|
||||
SetErrno(err);
|
||||
args.GetReturnValue().Set(UV_ENOBUFS);
|
||||
return;
|
||||
}
|
||||
|
||||
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(
|
||||
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;
|
||||
|
||||
if (!ipc_pipe) {
|
||||
r = wrap->callbacks_->DoWrite(req_wrap,
|
||||
&buf,
|
||||
1,
|
||||
NULL,
|
||||
StreamWrap::AfterWrite);
|
||||
err = wrap->callbacks_->DoWrite(req_wrap,
|
||||
&buf,
|
||||
1,
|
||||
NULL,
|
||||
StreamWrap::AfterWrite);
|
||||
} else {
|
||||
uv_handle_t* send_handle = NULL;
|
||||
|
||||
if (args[1]->IsObject()) {
|
||||
Local<Object> send_handle_obj = args[1]->ToObject();
|
||||
if (args[2]->IsObject()) {
|
||||
Local<Object> send_handle_obj = args[2]->ToObject();
|
||||
assert(send_handle_obj->InternalFieldCount() > 0);
|
||||
HandleWrap* send_handle_wrap = static_cast<HandleWrap*>(
|
||||
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);
|
||||
}
|
||||
|
||||
r = wrap->callbacks_->DoWrite(req_wrap,
|
||||
&buf,
|
||||
1,
|
||||
reinterpret_cast<uv_stream_t*>(send_handle),
|
||||
StreamWrap::AfterWrite);
|
||||
err = wrap->callbacks_->DoWrite(req_wrap,
|
||||
&buf,
|
||||
1,
|
||||
reinterpret_cast<uv_stream_t*>(send_handle),
|
||||
StreamWrap::AfterWrite);
|
||||
}
|
||||
|
||||
req_wrap->Dispatched();
|
||||
req_wrap->object()->Set(bytes_sym, Number::New(node_isolate, data_size));
|
||||
|
||||
if (r) {
|
||||
SetErrno(uv_last_error(uv_default_loop()));
|
||||
if (err) {
|
||||
req_wrap->~WriteWrap();
|
||||
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)
|
||||
|
||||
if (args.Length() < 1)
|
||||
return ThrowTypeError("Not enough arguments");
|
||||
assert(args[0]->IsObject());
|
||||
assert(args[1]->IsArray());
|
||||
|
||||
if (!args[0]->IsArray())
|
||||
return ThrowTypeError("Argument should be array");
|
||||
|
||||
Handle<Array> chunks = args[0].As<Array>();
|
||||
Local<Object> req_wrap_obj = args[0].As<Object>();
|
||||
Local<Array> chunks = args[1].As<Array>();
|
||||
size_t count = chunks->Length() >> 1;
|
||||
|
||||
uv_buf_t bufs_[16];
|
||||
|
@ -377,9 +368,7 @@ void StreamWrap::Writev(const FunctionCallbackInfo<Value>& args) {
|
|||
}
|
||||
|
||||
if (storage_size > INT_MAX) {
|
||||
uv_err_t err;
|
||||
err.code = UV_ENOBUFS;
|
||||
SetErrno(err);
|
||||
args.GetReturnValue().Set(UV_ENOBUFS);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -388,7 +377,7 @@ void StreamWrap::Writev(const FunctionCallbackInfo<Value>& args) {
|
|||
|
||||
storage_size += sizeof(WriteWrap);
|
||||
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;
|
||||
size_t offset = sizeof(WriteWrap);
|
||||
|
@ -418,11 +407,11 @@ void StreamWrap::Writev(const FunctionCallbackInfo<Value>& args) {
|
|||
bytes += str_size;
|
||||
}
|
||||
|
||||
int r = wrap->callbacks_->DoWrite(req_wrap,
|
||||
bufs,
|
||||
count,
|
||||
NULL,
|
||||
StreamWrap::AfterWrite);
|
||||
int err = wrap->callbacks_->DoWrite(req_wrap,
|
||||
bufs,
|
||||
count,
|
||||
NULL,
|
||||
StreamWrap::AfterWrite);
|
||||
|
||||
// Deallocate space
|
||||
if (bufs != bufs_)
|
||||
|
@ -431,13 +420,12 @@ void StreamWrap::Writev(const FunctionCallbackInfo<Value>& args) {
|
|||
req_wrap->Dispatched();
|
||||
req_wrap->object()->Set(bytes_sym, Number::New(node_isolate, bytes));
|
||||
|
||||
if (r) {
|
||||
SetErrno(uv_last_error(uv_default_loop()));
|
||||
if (err) {
|
||||
req_wrap->~WriteWrap();
|
||||
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);
|
||||
}
|
||||
|
||||
if (status) {
|
||||
SetErrno(uv_last_error(uv_default_loop()));
|
||||
}
|
||||
|
||||
wrap->callbacks_->AfterWrite(req_wrap);
|
||||
|
||||
Local<Value> argv[] = {
|
||||
|
@ -496,24 +480,20 @@ void StreamWrap::Shutdown(const FunctionCallbackInfo<Value>& args) {
|
|||
|
||||
UNWRAP(StreamWrap)
|
||||
|
||||
ShutdownWrap* req_wrap = new ShutdownWrap();
|
||||
|
||||
int r = wrap->callbacks_->DoShutdown(req_wrap, AfterShutdown);
|
||||
assert(args[0]->IsObject());
|
||||
Local<Object> req_wrap_obj = args[0].As<Object>();
|
||||
|
||||
ShutdownWrap* req_wrap = new ShutdownWrap(req_wrap_obj);
|
||||
int err = wrap->callbacks_->DoShutdown(req_wrap, AfterShutdown);
|
||||
req_wrap->Dispatched();
|
||||
|
||||
if (r) {
|
||||
SetErrno(uv_last_error(uv_default_loop()));
|
||||
delete req_wrap;
|
||||
} else {
|
||||
args.GetReturnValue().Set(req_wrap->persistent());
|
||||
}
|
||||
if (err) delete req_wrap;
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
|
||||
void StreamWrap::AfterShutdown(uv_shutdown_t* req, int status) {
|
||||
ReqWrap<uv_shutdown_t>* req_wrap = (ReqWrap<uv_shutdown_t>*) req->data;
|
||||
StreamWrap* wrap = (StreamWrap*) req->handle->data;
|
||||
ShutdownWrap* req_wrap = static_cast<ShutdownWrap*>(req->data);
|
||||
StreamWrap* wrap = static_cast<StreamWrap*>(req->handle->data);
|
||||
|
||||
// The wrap and request objects should still be there.
|
||||
assert(req_wrap->persistent().IsEmpty() == false);
|
||||
|
@ -521,10 +501,6 @@ void StreamWrap::AfterShutdown(uv_shutdown_t* req, int status) {
|
|||
|
||||
HandleScope scope(node_isolate);
|
||||
|
||||
if (status) {
|
||||
SetErrno(uv_last_error(uv_default_loop()));
|
||||
}
|
||||
|
||||
Local<Object> req_wrap_obj = req_wrap->object();
|
||||
Local<Value> argv[3] = {
|
||||
Integer::New(status, node_isolate),
|
||||
|
@ -589,11 +565,16 @@ void StreamWrapCallbacks::DoRead(uv_stream_t* handle,
|
|||
uv_handle_type pending) {
|
||||
HandleScope scope(node_isolate);
|
||||
|
||||
Local<Value> argv[] = {
|
||||
Integer::New(nread, node_isolate),
|
||||
Undefined(),
|
||||
Undefined()
|
||||
};
|
||||
|
||||
if (nread < 0) {
|
||||
if (buf.base != NULL)
|
||||
free(buf.base);
|
||||
SetErrno(uv_last_error(uv_default_loop()));
|
||||
MakeCallback(Self(), onread_sym, 0, NULL);
|
||||
MakeCallback(Self(), onread_sym, ARRAY_SIZE(argv), argv);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -604,13 +585,8 @@ void StreamWrapCallbacks::DoRead(uv_stream_t* handle,
|
|||
}
|
||||
|
||||
buf.base = static_cast<char*>(realloc(buf.base, nread));
|
||||
|
||||
assert(static_cast<size_t>(nread) <= buf.len);
|
||||
|
||||
int argc = 1;
|
||||
Local<Value> argv[2] = {
|
||||
Buffer::Use(buf.base, nread)
|
||||
};
|
||||
argv[1] = Buffer::Use(buf.base, nread);
|
||||
|
||||
Local<Object> pending_obj;
|
||||
if (pending == UV_TCP) {
|
||||
|
@ -624,11 +600,10 @@ void StreamWrapCallbacks::DoRead(uv_stream_t* handle,
|
|||
}
|
||||
|
||||
if (!pending_obj.IsEmpty()) {
|
||||
argv[1] = pending_obj;
|
||||
argc++;
|
||||
argv[2] = pending_obj;
|
||||
}
|
||||
|
||||
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> {
|
||||
public:
|
||||
explicit WriteWrap(StreamWrap* wrap) {
|
||||
explicit WriteWrap(v8::Local<v8::Object> obj, StreamWrap* wrap)
|
||||
: ReqWrap<uv_write_t>(obj) {
|
||||
wrap_ = wrap;
|
||||
}
|
||||
|
||||
|
|
145
src/tcp_wrap.cc
145
src/tcp_wrap.cc
|
@ -39,11 +39,11 @@ using v8::Handle;
|
|||
using v8::HandleScope;
|
||||
using v8::Integer;
|
||||
using v8::Local;
|
||||
using v8::Null;
|
||||
using v8::Object;
|
||||
using v8::Persistent;
|
||||
using v8::PropertyAttribute;
|
||||
using v8::String;
|
||||
using v8::Undefined;
|
||||
using v8::Value;
|
||||
|
||||
static Persistent<Function> tcpConstructor;
|
||||
|
@ -168,14 +168,19 @@ void TCPWrap::GetSockName(const FunctionCallbackInfo<Value>& args) {
|
|||
|
||||
UNWRAP(TCPWrap)
|
||||
|
||||
int addrlen = sizeof(address);
|
||||
int r = uv_tcp_getsockname(&wrap->handle_,
|
||||
reinterpret_cast<sockaddr*>(&address),
|
||||
&addrlen);
|
||||
if (r) return SetErrno(uv_last_error(uv_default_loop()));
|
||||
assert(args[0]->IsObject());
|
||||
Local<Object> out = args[0].As<Object>();
|
||||
|
||||
const sockaddr* addr = reinterpret_cast<const sockaddr*>(&address);
|
||||
args.GetReturnValue().Set(AddressToJS(addr));
|
||||
int addrlen = sizeof(address);
|
||||
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)
|
||||
|
||||
int addrlen = sizeof(address);
|
||||
int r = uv_tcp_getpeername(&wrap->handle_,
|
||||
reinterpret_cast<sockaddr*>(&address),
|
||||
&addrlen);
|
||||
if (r) return SetErrno(uv_last_error(uv_default_loop()));
|
||||
assert(args[0]->IsObject());
|
||||
Local<Object> out = args[0].As<Object>();
|
||||
|
||||
const sockaddr* addr = reinterpret_cast<const sockaddr*>(&address);
|
||||
args.GetReturnValue().Set(AddressToJS(addr));
|
||||
int addrlen = sizeof(address);
|
||||
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)
|
||||
|
||||
int enable = static_cast<int>(args[0]->BooleanValue());
|
||||
int r = uv_tcp_nodelay(&wrap->handle_, enable);
|
||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
||||
int err = uv_tcp_nodelay(&wrap->handle_, enable);
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
|
||||
|
@ -215,8 +225,8 @@ void TCPWrap::SetKeepAlive(const FunctionCallbackInfo<Value>& args) {
|
|||
int enable = args[0]->Int32Value();
|
||||
unsigned int delay = args[1]->Uint32Value();
|
||||
|
||||
int r = uv_tcp_keepalive(&wrap->handle_, enable, delay);
|
||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
||||
int err = uv_tcp_keepalive(&wrap->handle_, enable, delay);
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
|
||||
|
@ -227,8 +237,8 @@ void TCPWrap::SetSimultaneousAccepts(const FunctionCallbackInfo<Value>& args) {
|
|||
UNWRAP(TCPWrap)
|
||||
|
||||
bool enable = args[0]->BooleanValue();
|
||||
int r = uv_tcp_simultaneous_accepts(&wrap->handle_, enable ? 1 : 0);
|
||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
||||
int err = uv_tcp_simultaneous_accepts(&wrap->handle_, enable);
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -250,12 +260,9 @@ void TCPWrap::Bind(const FunctionCallbackInfo<Value>& args) {
|
|||
int port = args[1]->Int32Value();
|
||||
|
||||
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.
|
||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
||||
|
||||
args.GetReturnValue().Set(r);
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
|
||||
|
@ -268,12 +275,9 @@ void TCPWrap::Bind6(const FunctionCallbackInfo<Value>& args) {
|
|||
int port = args[1]->Int32Value();
|
||||
|
||||
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.
|
||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
||||
|
||||
args.GetReturnValue().Set(r);
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
|
||||
|
@ -283,15 +287,10 @@ void TCPWrap::Listen(const FunctionCallbackInfo<Value>& args) {
|
|||
UNWRAP(TCPWrap)
|
||||
|
||||
int backlog = args[0]->Int32Value();
|
||||
|
||||
int r = uv_listen(reinterpret_cast<uv_stream_t*>(&wrap->handle_),
|
||||
backlog,
|
||||
OnConnection);
|
||||
|
||||
// Error starting the tcp.
|
||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
||||
|
||||
args.GetReturnValue().Set(r);
|
||||
int err = uv_listen(reinterpret_cast<uv_stream_t*>(&wrap->handle_),
|
||||
backlog,
|
||||
OnConnection);
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
|
||||
|
@ -305,7 +304,10 @@ void TCPWrap::OnConnection(uv_stream_t* handle, int status) {
|
|||
// uv_close() on the handle.
|
||||
assert(wrap->persistent().IsEmpty() == false);
|
||||
|
||||
Local<Value> argv[1];
|
||||
Local<Value> argv[2] = {
|
||||
Integer::New(status, node_isolate),
|
||||
Undefined()
|
||||
};
|
||||
|
||||
if (status == 0) {
|
||||
// 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;
|
||||
|
||||
// Successful accept. Call the onconnection callback in JavaScript land.
|
||||
argv[0] = client_obj;
|
||||
} else {
|
||||
SetErrno(uv_last_error(uv_default_loop()));
|
||||
argv[0] = Null(node_isolate);
|
||||
argv[1] = client_obj;
|
||||
}
|
||||
|
||||
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(wrap->persistent().IsEmpty() == false);
|
||||
|
||||
if (status) {
|
||||
SetErrno(uv_last_error(uv_default_loop()));
|
||||
}
|
||||
|
||||
Local<Object> req_wrap_obj = req_wrap->object();
|
||||
Local<Value> argv[5] = {
|
||||
Integer::New(status, node_isolate),
|
||||
|
@ -364,27 +359,29 @@ void TCPWrap::Connect(const FunctionCallbackInfo<Value>& args) {
|
|||
|
||||
UNWRAP(TCPWrap)
|
||||
|
||||
String::AsciiValue ip_address(args[0]);
|
||||
int port = args[1]->Int32Value();
|
||||
assert(args[0]->IsObject());
|
||||
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);
|
||||
|
||||
// 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
|
||||
// just do some type munging.
|
||||
ConnectWrap* req_wrap = new ConnectWrap();
|
||||
|
||||
int r = uv_tcp_connect(&req_wrap->req_, &wrap->handle_, address,
|
||||
AfterConnect);
|
||||
ConnectWrap* req_wrap = new ConnectWrap(req_wrap_obj);
|
||||
|
||||
int err = uv_tcp_connect(&req_wrap->req_,
|
||||
&wrap->handle_,
|
||||
address,
|
||||
AfterConnect);
|
||||
req_wrap->Dispatched();
|
||||
if (err) delete req_wrap;
|
||||
|
||||
if (r) {
|
||||
SetErrno(uv_last_error(uv_default_loop()));
|
||||
delete req_wrap;
|
||||
} else {
|
||||
args.GetReturnValue().Set(req_wrap->persistent());
|
||||
}
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
|
||||
|
@ -393,24 +390,26 @@ void TCPWrap::Connect6(const FunctionCallbackInfo<Value>& args) {
|
|||
|
||||
UNWRAP(TCPWrap)
|
||||
|
||||
String::AsciiValue ip_address(args[0]);
|
||||
int port = args[1]->Int32Value();
|
||||
assert(args[0]->IsObject());
|
||||
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);
|
||||
|
||||
ConnectWrap* req_wrap = new ConnectWrap();
|
||||
|
||||
int r = uv_tcp_connect6(&req_wrap->req_, &wrap->handle_, address,
|
||||
AfterConnect);
|
||||
ConnectWrap* req_wrap = new ConnectWrap(req_wrap_obj);
|
||||
|
||||
int err = uv_tcp_connect6(&req_wrap->req_,
|
||||
&wrap->handle_,
|
||||
address,
|
||||
AfterConnect);
|
||||
req_wrap->Dispatched();
|
||||
if (err) delete req_wrap;
|
||||
|
||||
if (r) {
|
||||
SetErrno(uv_last_error(uv_default_loop()));
|
||||
delete req_wrap;
|
||||
} else {
|
||||
args.GetReturnValue().Set(req_wrap->persistent());
|
||||
}
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -90,27 +90,24 @@ class TimerWrap : public HandleWrap {
|
|||
|
||||
int64_t timeout = args[0]->IntegerValue();
|
||||
int64_t repeat = args[1]->IntegerValue();
|
||||
int r = uv_timer_start(&wrap->handle_, OnTimeout, timeout, repeat);
|
||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
||||
args.GetReturnValue().Set(r);
|
||||
int err = uv_timer_start(&wrap->handle_, OnTimeout, timeout, repeat);
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
static void Stop(const FunctionCallbackInfo<Value>& args) {
|
||||
HandleScope scope(node_isolate);
|
||||
UNWRAP(TimerWrap)
|
||||
|
||||
int r = uv_timer_stop(&wrap->handle_);
|
||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
||||
args.GetReturnValue().Set(r);
|
||||
int err = uv_timer_stop(&wrap->handle_);
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
static void Again(const FunctionCallbackInfo<Value>& args) {
|
||||
HandleScope scope(node_isolate);
|
||||
UNWRAP(TimerWrap)
|
||||
|
||||
int r = uv_timer_again(&wrap->handle_);
|
||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
||||
args.GetReturnValue().Set(r);
|
||||
int err = uv_timer_again(&wrap->handle_);
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
static void SetRepeat(const FunctionCallbackInfo<Value>& args) {
|
||||
|
@ -127,7 +124,6 @@ class TimerWrap : public HandleWrap {
|
|||
UNWRAP(TimerWrap)
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
|
|
@ -418,7 +418,6 @@ void TLSCallbacks::EncOutCb(uv_write_t* req, int status) {
|
|||
return;
|
||||
|
||||
// Notify about error
|
||||
SetErrno(uv_last_error(uv_default_loop()));
|
||||
Local<Value> arg = String::Concat(
|
||||
String::New("write cb error, status: "),
|
||||
Integer::New(status, node_isolate)->ToString());
|
||||
|
@ -483,8 +482,11 @@ void TLSCallbacks::ClearOut() {
|
|||
do {
|
||||
read = SSL_read(ssl_, out, sizeof(out));
|
||||
if (read > 0) {
|
||||
Handle<Value> buf = Buffer::New(out, read);
|
||||
MakeCallback(Self(), onread_sym, 1, &buf);
|
||||
Local<Value> argv[] = {
|
||||
Integer::New(read, node_isolate),
|
||||
Buffer::New(out, read)
|
||||
};
|
||||
MakeCallback(Self(), onread_sym, ARRAY_SIZE(argv), argv);
|
||||
}
|
||||
} while (read > 0);
|
||||
|
||||
|
@ -621,12 +623,10 @@ void TLSCallbacks::DoRead(uv_stream_t* handle,
|
|||
uv_buf_t buf,
|
||||
uv_handle_type pending) {
|
||||
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
|
||||
ClearOut();
|
||||
MakeCallback(Self(), onread_sym, 0, NULL);
|
||||
Local<Value> arg = Integer::New(nread, node_isolate);
|
||||
MakeCallback(Self(), onread_sym, 1, &arg);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
namespace node {
|
||||
|
||||
using v8::Array;
|
||||
using v8::Function;
|
||||
using v8::FunctionCallbackInfo;
|
||||
using v8::FunctionTemplate;
|
||||
|
@ -131,15 +132,18 @@ void TTYWrap::GetWindowSize(const FunctionCallbackInfo<Value>& args) {
|
|||
HandleScope scope(node_isolate);
|
||||
|
||||
UNWRAP(TTYWrap)
|
||||
assert(args[0]->IsArray());
|
||||
|
||||
int width, height;
|
||||
int r = uv_tty_get_winsize(&wrap->handle_, &width, &height);
|
||||
if (r) return SetErrno(uv_last_error(uv_default_loop()));
|
||||
int err = uv_tty_get_winsize(&wrap->handle_, &width, &height);
|
||||
|
||||
Local<v8::Array> a = v8::Array::New(2);
|
||||
a->Set(0, Integer::New(width, node_isolate));
|
||||
a->Set(1, Integer::New(height, node_isolate));
|
||||
args.GetReturnValue().Set(a);
|
||||
if (err == 0) {
|
||||
Local<v8::Array> a = args[0].As<Array>();
|
||||
a->Set(0, Integer::New(width, node_isolate));
|
||||
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)
|
||||
|
||||
int r = uv_tty_set_mode(&wrap->handle_, args[0]->IsTrue());
|
||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
||||
args.GetReturnValue().Set(r);
|
||||
int err = uv_tty_set_mode(&wrap->handle_, args[0]->IsTrue());
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
|
||||
|
|
146
src/udp_wrap.cc
146
src/udp_wrap.cc
|
@ -43,6 +43,7 @@ using v8::PropertyAttribute;
|
|||
using v8::PropertyCallbackInfo;
|
||||
using v8::String;
|
||||
using v8::Uint32;
|
||||
using v8::Undefined;
|
||||
using v8::Value;
|
||||
|
||||
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) {
|
||||
HandleScope scope(node_isolate);
|
||||
int r;
|
||||
int err;
|
||||
|
||||
UNWRAP(UDPWrap)
|
||||
|
||||
|
@ -141,18 +142,17 @@ void UDPWrap::DoBind(const FunctionCallbackInfo<Value>& args, int family) {
|
|||
|
||||
switch (family) {
|
||||
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;
|
||||
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;
|
||||
default:
|
||||
assert(0 && "unexpected address family");
|
||||
abort();
|
||||
}
|
||||
|
||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
||||
args.GetReturnValue().Set(r);
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
|
||||
|
@ -172,9 +172,8 @@ void UDPWrap::Bind6(const FunctionCallbackInfo<Value>& args) {
|
|||
UNWRAP(UDPWrap) \
|
||||
assert(args.Length() == 1); \
|
||||
int flag = args[0]->Int32Value(); \
|
||||
int r = fn(&wrap->handle_, flag); \
|
||||
if (r) SetErrno(uv_last_error(uv_default_loop())); \
|
||||
args.GetReturnValue().Set(r); \
|
||||
int err = fn(&wrap->handle_, flag); \
|
||||
args.GetReturnValue().Set(err); \
|
||||
}
|
||||
|
||||
X(SetTTL, uv_udp_set_ttl)
|
||||
|
@ -200,12 +199,11 @@ void UDPWrap::SetMembership(const FunctionCallbackInfo<Value>& args,
|
|||
iface_cstr = NULL;
|
||||
}
|
||||
|
||||
int r = uv_udp_set_membership(&wrap->handle_,
|
||||
*address,
|
||||
iface_cstr,
|
||||
membership);
|
||||
if (r) SetErrno(uv_last_error(uv_default_loop()));
|
||||
args.GetReturnValue().Set(r);
|
||||
int err = uv_udp_set_membership(&wrap->handle_,
|
||||
*address,
|
||||
iface_cstr,
|
||||
membership);
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
|
||||
|
@ -221,38 +219,50 @@ void UDPWrap::DropMembership(const FunctionCallbackInfo<Value>& args) {
|
|||
|
||||
void UDPWrap::DoSend(const FunctionCallbackInfo<Value>& args, int family) {
|
||||
HandleScope scope(node_isolate);
|
||||
int r;
|
||||
|
||||
// send(buffer, offset, length, port, address)
|
||||
assert(args.Length() == 5);
|
||||
int err;
|
||||
|
||||
UNWRAP(UDPWrap)
|
||||
|
||||
assert(Buffer::HasInstance(args[0]));
|
||||
Local<Object> buffer_obj = args[0]->ToObject();
|
||||
// send(req, buffer, offset, length, port, address)
|
||||
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(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);
|
||||
|
||||
uv_buf_t buf = uv_buf_init(Buffer::Data(buffer_obj) + offset,
|
||||
length);
|
||||
|
||||
const unsigned short port = args[3]->Uint32Value();
|
||||
String::Utf8Value address(args[4]);
|
||||
|
||||
switch (family) {
|
||||
case AF_INET:
|
||||
r = uv_udp_send(&req_wrap->req_, &wrap->handle_, &buf, 1,
|
||||
uv_ip4_addr(*address, port), OnSend);
|
||||
err = uv_udp_send(&req_wrap->req_,
|
||||
&wrap->handle_,
|
||||
&buf,
|
||||
1,
|
||||
uv_ip4_addr(*address, port),
|
||||
OnSend);
|
||||
break;
|
||||
case AF_INET6:
|
||||
r = uv_udp_send6(&req_wrap->req_, &wrap->handle_, &buf, 1,
|
||||
uv_ip6_addr(*address, port), OnSend);
|
||||
err = uv_udp_send6(&req_wrap->req_,
|
||||
&wrap->handle_,
|
||||
&buf,
|
||||
1,
|
||||
uv_ip6_addr(*address, port),
|
||||
OnSend);
|
||||
break;
|
||||
default:
|
||||
assert(0 && "unexpected address family");
|
||||
|
@ -260,14 +270,9 @@ void UDPWrap::DoSend(const FunctionCallbackInfo<Value>& args, int family) {
|
|||
}
|
||||
|
||||
req_wrap->Dispatched();
|
||||
if (err) delete req_wrap;
|
||||
|
||||
if (r) {
|
||||
SetErrno(uv_last_error(uv_default_loop()));
|
||||
delete req_wrap;
|
||||
}
|
||||
else {
|
||||
args.GetReturnValue().Set(req_wrap->persistent());
|
||||
}
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
|
||||
|
@ -285,11 +290,10 @@ void UDPWrap::RecvStart(const FunctionCallbackInfo<Value>& args) {
|
|||
HandleScope scope(node_isolate);
|
||||
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
|
||||
int r = uv_udp_recv_start(&wrap->handle_, OnAlloc, OnRecv);
|
||||
bool ok = r == 0 || uv_last_error(uv_default_loop()).code == UV_EALREADY;
|
||||
if (ok == false) SetErrno(uv_last_error(uv_default_loop()));
|
||||
args.GetReturnValue().Set(ok);
|
||||
if (err == UV_EALREADY) err = 0;
|
||||
args.GetReturnValue().Set(err);
|
||||
}
|
||||
|
||||
|
||||
|
@ -307,14 +311,20 @@ void UDPWrap::GetSockName(const FunctionCallbackInfo<Value>& args) {
|
|||
struct sockaddr_storage address;
|
||||
UNWRAP(UDPWrap)
|
||||
|
||||
int addrlen = sizeof(address);
|
||||
int r = uv_udp_getsockname(&wrap->handle_,
|
||||
reinterpret_cast<sockaddr*>(&address),
|
||||
&addrlen);
|
||||
if (r) return SetErrno(uv_last_error(uv_default_loop()));
|
||||
assert(args[0]->IsObject());
|
||||
Local<Object> obj = args[0].As<Object>();
|
||||
|
||||
const sockaddr* addr = reinterpret_cast<const sockaddr*>(&address);
|
||||
args.GetReturnValue().Set(AddressToJS(addr));
|
||||
int addrlen = sizeof(address);
|
||||
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(wrap->persistent().IsEmpty() == false);
|
||||
|
||||
if (status) {
|
||||
SetErrno(uv_last_error(uv_default_loop()));
|
||||
}
|
||||
|
||||
Local<Object> req_wrap_obj = req_wrap->object();
|
||||
Local<Value> argv[4] = {
|
||||
Local<Value> argv[] = {
|
||||
Integer::New(status, node_isolate),
|
||||
wrap->object(),
|
||||
req_wrap_obj,
|
||||
|
@ -362,34 +368,34 @@ void UDPWrap::OnRecv(uv_udp_t* handle,
|
|||
uv_buf_t buf,
|
||||
struct sockaddr* addr,
|
||||
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 (buf.base != NULL)
|
||||
free(buf.base);
|
||||
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<Value> argv[] = {
|
||||
Integer::New(nread, node_isolate),
|
||||
wrap_obj,
|
||||
Buffer::Use(buf.base, nread),
|
||||
AddressToJS(addr)
|
||||
Undefined(),
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче