Browse Source

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().
v0.11.5-release
Ben Noordhuis 12 years ago
parent
commit
ca9eb718fb
  1. 75
      lib/child_process.js
  2. 41
      lib/cluster.js
  3. 79
      lib/dgram.js
  4. 59
      lib/dns.js
  5. 11
      lib/fs.js
  6. 194
      lib/net.js
  7. 12
      lib/tty.js
  8. 230
      src/cares_wrap.cc
  9. 13
      src/fs_event_wrap.cc
  10. 70
      src/node.cc
  11. 2
      src/node.h
  12. 16
      src/node.js
  13. 32
      src/node_file.cc
  14. 15
      src/node_os.cc
  15. 3
      src/node_stat_watcher.cc
  16. 40
      src/pipe_wrap.cc
  17. 20
      src/process_wrap.cc
  18. 10
      src/signal_wrap.cc
  19. 151
      src/stream_wrap.cc
  20. 3
      src/stream_wrap.h
  21. 125
      src/tcp_wrap.cc
  22. 16
      src/timer_wrap.cc
  23. 14
      src/tls_wrap.cc
  24. 17
      src/tty_wrap.cc
  25. 130
      src/udp_wrap.cc

75
lib/child_process.js

@ -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'));
}
}

41
lib/cluster.js

@ -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

@ -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);

59
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) {
function onanswer(err, addresses) {
if (err) {
return callback(errnoException(err, 'getaddrinfo'));
}
if (family) {
callback(null, addresses[0], family);
} else {
callback(null, addresses[0], addresses[0].indexOf(':') >= 0 ? 6 : 4);
}
} else {
callback(errnoException(process._errno, 'getaddrinfo'));
}
}
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

@ -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');
}
};

194
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,12 +518,25 @@ 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'));
}
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'));
}
} else if (process._errno == 'EOF') {
debug('EOF');
if (self._readableState.length === 0) {
@ -545,11 +553,6 @@ function onread(buffer) {
// 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'));
}
}
@ -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

@ -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];

230
src/cares_wrap.cc

@ -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());
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();
wrap->SetOnComplete(args[1]);
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());
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();
wrap->SetOnComplete(args[2]);
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,
int err = uv_inet_ntop(address->ai_family,
addr,
ip,
INET6_ADDRSTRLEN);
if (err.code != UV_OK)
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,
int err = uv_inet_ntop(address->ai_family,
addr,
ip,
INET6_ADDRSTRLEN);
if (err.code != UV_OK)
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;
int family;
switch (args[2]->Int32Value()) {
case 0:
family = AF_UNSPEC;
break;
case 4:
fam = AF_INET;
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(),
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);
}

13
src/fs_event_wrap.cc

@ -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

@ -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

2
src/node.h

@ -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

@ -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;

32
src/node_file.cc

@ -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) {

15
src/node_os.cc

@ -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();

3
src/node_stat_watcher.cc

@ -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");
}

40
src/pipe_wrap.cc

@ -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_),
int err = 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);
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.
}

20
src/process_wrap.cc

@ -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");
}

10
src/signal_wrap.cc

@ -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) {

151
src/stream_wrap.cc

@ -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]);
assert(args[0]->IsObject());
assert(Buffer::HasInstance(args[1]));
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(wrap);
WriteWrap* req_wrap = new (storage) WriteWrap(req_wrap_obj, wrap);
Local<Object> req_wrap_obj = req_wrap->object();
req_wrap_obj->SetHiddenValue(buffer_sym, args[0]);
req_wrap_obj->SetHiddenValue(buffer_sym, buf_obj);
uv_buf_t buf;
WriteBuffer(args[0], &buf);
WriteBuffer(buf_obj, &buf);
int r = wrap->callbacks_->DoWrite(req_wrap,
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,7 +288,7 @@ void StreamWrap::WriteStringImpl(const FunctionCallbackInfo<Value>& args) {
reinterpret_cast<uv_pipe_t*>(wrap->stream_)->ipc;
if (!ipc_pipe) {
r = wrap->callbacks_->DoWrite(req_wrap,
err = wrap->callbacks_->DoWrite(req_wrap,
&buf,
1,
NULL,
@ -302,8 +296,8 @@ void StreamWrap::WriteStringImpl(const FunctionCallbackInfo<Value>& args) {
} 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,7 +312,7 @@ void StreamWrap::WriteStringImpl(const FunctionCallbackInfo<Value>& args) {
req_wrap->object()->Set(handle_sym, send_handle_obj);
}
r = wrap->callbacks_->DoWrite(req_wrap,
err = wrap->callbacks_->DoWrite(req_wrap,
&buf,
1,
reinterpret_cast<uv_stream_t*>(send_handle),
@ -328,13 +322,12 @@ void StreamWrap::WriteStringImpl(const FunctionCallbackInfo<Value>& args) {
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");
if (!args[0]->IsArray())
return ThrowTypeError("Argument should be array");
assert(args[0]->IsObject());
assert(args[1]->IsArray());
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,7 +407,7 @@ void StreamWrap::Writev(const FunctionCallbackInfo<Value>& args) {
bytes += str_size;
}
int r = wrap->callbacks_->DoWrite(req_wrap,
int err = wrap->callbacks_->DoWrite(req_wrap,
bufs,
count,
NULL,
@ -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);
}

3
src/stream_wrap.h

@ -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;
}

125
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)
assert(args[0]->IsObject());
Local<Object> out = args[0].As<Object>();
int addrlen = sizeof(address);
int r = uv_tcp_getsockname(&wrap->handle_,
int err = uv_tcp_getsockname(&wrap->handle_,
reinterpret_cast<sockaddr*>(&address),
&addrlen);
if (r) return SetErrno(uv_last_error(uv_default_loop()));
if (err == 0) {
const sockaddr* addr = reinterpret_cast<const sockaddr*>(&address);
args.GetReturnValue().Set(AddressToJS(addr));
AddressToJS(addr, out);
}
args.GetReturnValue().Set(err);
}
@ -185,14 +190,19 @@ void TCPWrap::GetPeerName(const FunctionCallbackInfo<Value>& args) {
UNWRAP(TCPWrap)
assert(args[0]->IsObject());
Local<Object> out = args[0].As<Object>();
int addrlen = sizeof(address);
int r = uv_tcp_getpeername(&wrap->handle_,
int err = uv_tcp_getpeername(&wrap->handle_,
reinterpret_cast<sockaddr*>(&address),
&addrlen);
if (r) return SetErrno(uv_last_error(uv_default_loop()));
if (err == 0) {
const sockaddr* addr = reinterpret_cast<const sockaddr*>(&address);
args.GetReturnValue().Set(AddressToJS(addr));
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);
// Error starting the tcp.
if (r) SetErrno(uv_last_error(uv_default_loop()));
int err = uv_tcp_bind6(&wrap->handle_, address);
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_),
int err = 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);
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();
ConnectWrap* req_wrap = new ConnectWrap(req_wrap_obj);
int r = uv_tcp_connect(&req_wrap->req_, &wrap->handle_, address,
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();
ConnectWrap* req_wrap = new ConnectWrap(req_wrap_obj);
int r = uv_tcp_connect6(&req_wrap->req_, &wrap->handle_, address,
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);
}

16
src/timer_wrap.cc

@ -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));
}

14
src/tls_wrap.cc

@ -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;
}

17
src/tty_wrap.cc

@ -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);
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(a);
}
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);
}

130
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_,
int err = uv_udp_set_membership(&wrap->handle_,
*address,
iface_cstr,
membership);
if (r) SetErrno(uv_last_error(uv_default_loop()));
args.GetReturnValue().Set(r);
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)
assert(args[0]->IsObject());
Local<Object> obj = args[0].As<Object>();
int addrlen = sizeof(address);
int r = uv_udp_getsockname(&wrap->handle_,
int err = uv_udp_getsockname(&wrap->handle_,
reinterpret_cast<sockaddr*>(&address),
&addrlen);
if (r) return SetErrno(uv_last_error(uv_default_loop()));
if (err == 0) {
const sockaddr* addr = reinterpret_cast<const sockaddr*>(&address);
args.GetReturnValue().Set(AddressToJS(addr));
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 (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) {
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,
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));
Local<Object> wrap_obj = wrap->object();
Local<Value> argv[] = {
wrap_obj,
Buffer::Use(buf.base, nread),
AddressToJS(addr)
};
argv[2] = Buffer::Use(buf.base, nread);
argv[3] = AddressToJS(addr);
MakeCallback(wrap_obj, onmessage_sym, ARRAY_SIZE(argv), argv);
}

Loading…
Cancel
Save