Skip to content

Commit

Permalink
Refactor for node v4 (#10)
Browse files Browse the repository at this point in the history
* Initial replace ffi with ffi-napi

* Include node 9 & 10 for travis

* Repalce ref with ref-napi

* Update package.json and readme

* Sync appveyor and travis configs

* Refactor for node v4 and later

* Initial replace ffi with ffi-napi

* Repalce ref with ref-napi

* Update package.json and readme

* Refactor for node v4 and later

* Refactoring

* Refactoring
  • Loading branch information
hertzg authored Jul 1, 2018
1 parent 10d9374 commit df05f62
Show file tree
Hide file tree
Showing 10 changed files with 141 additions and 145 deletions.
2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
module.exports = require('./lib');
module.exports = require('./lib')
58 changes: 26 additions & 32 deletions lib/commons.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,40 @@
var UV = null
, Util = require('util')

function tryGetUV() {
if (UV === null) {
try {
UV = typeof process.binding === "function" ? process.binding('uv') : undefined
} catch (ex) {
"use strict"

const Util = require('util')

const tryGetUV = (() => {
let UV = null
return () => {
if (UV === null) {
try {
UV = typeof process.binding === "function" ? process.binding('uv') : undefined
} catch (ex) {
}
}
return UV
}
return UV
}
})()

function uvErrName(errno) {
var UV = tryGetUV()
, errName = "UNKNOWN"

if (UV && UV.errname) {
errName = UV.errname(errno)
}

return errName
const uvErrName = (errno) => {
const UV = tryGetUV()
return UV && UV.errname ? UV.errname(errno) : "UNKNOWN"
}

function errnoException(errno, syscall, original) {
const errnoException = (errno, syscall, original) => {
if (Util._errnoException) {
return Util._errnoException(-errno, syscall, original)
}

var errname = uvErrName(-errno)
, message = syscall + " " + errname + " (" + errno + ")"

if (original) {
message += " " + original;
}
const errname = uvErrName(-errno)
, message = original ? `${syscall} ${errname} (${errno}) ${original}` : `${syscall} ${errname} (${errno})`

var e = new Error(message);
e.code = errname;
e.errno = errname;
e.syscall = syscall;
return e;
const e = new Error(message)
e.code = errname
e.errno = errname
e.syscall = syscall
return e
}

module.exports = {
errnoException: errnoException
errnoException
}
35 changes: 18 additions & 17 deletions lib/constants.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,30 @@
var OS = require('os')
"use strict"

var Constants = {
const OS = require('os')

const Constants = {
SOL_TCP: 6,
TCP_KEEPINTVL: undefined,
TCP_KEEPCNT: undefined
}

var platform = OS.platform();
switch(platform) {
switch (OS.platform()) {

case 'darwin':
Constants.TCP_KEEPINTVL = 0x101
Constants.TCP_KEEPCNT = 0x102
break
case 'darwin':
Constants.TCP_KEEPINTVL = 0x101
Constants.TCP_KEEPCNT = 0x102
break

case 'freebsd':
Constants.TCP_KEEPINTVL = 512
Constants.TCP_KEEPCNT = 1024
break
case 'freebsd':
Constants.TCP_KEEPINTVL = 512
Constants.TCP_KEEPCNT = 1024
break

case 'linux':
default:
Constants.TCP_KEEPINTVL = 5
Constants.TCP_KEEPCNT = 6
break
case 'linux':
default:
Constants.TCP_KEEPINTVL = 5
Constants.TCP_KEEPCNT = 6
break
}

module.exports = Constants
35 changes: 19 additions & 16 deletions lib/ffi-bindings.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,41 @@
var Ref = require('ref-napi')
"use strict"

const Ref = require('ref-napi')
, FFI = require('ffi-napi')
, Commons = require('./commons')


var ffi = FFI.Library(null, {
// name ret 1 2 3 4 5
setsockopt: [Ref.types.int, [Ref.types.int, Ref.types.int, Ref.types.int, Ref.refType(Ref.types.void), Ref.types.int]],
getsockopt: [Ref.types.int, [Ref.types.int, Ref.types.int, Ref.types.int, Ref.refType(Ref.types.void), Ref.refType(Ref.types.int)]]
});
const cInt = Ref.types.int
, cVoid = Ref.types.void

const ffi = FFI.Library(null, {
//name ret 1 2 3 4 5
setsockopt: [cInt, [cInt, cInt, cInt, Ref.refType(cVoid), cInt]],
getsockopt: [cInt, [cInt, cInt, cInt, Ref.refType(cVoid), Ref.refType(cInt)]]
})

function setsockopt(fd, level, name, value, valueLength) {
var err = ffi.setsockopt(fd, level, name, value, valueLength)
, errno
const setsockopt = (fd, level, name, value, valueLength) => {
const err = ffi.setsockopt(fd, level, name, value, valueLength)

if (err !== 0) {
errno = FFI.errno()
let errno = FFI.errno()
throw Commons.errnoException(errno, 'setsockopt')
}

return true
}

function getsockopt(fd, level, name, value, valueLength) {
var err = ffi.getsockopt(fd, level, name, value, valueLength)
, errno
const getsockopt = (fd, level, name, value, valueLength) => {
const err = ffi.getsockopt(fd, level, name, value, valueLength)

if (err !== 0) {
errno = FFI.errno()
let errno = FFI.errno()
throw Commons.errnoException(errno, 'getsockopt')
}
return true
}

module.exports = {
setsockopt: setsockopt,
getsockopt: getsockopt
setsockopt,
getsockopt
}
42 changes: 17 additions & 25 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
var Assert = require('assert')
"use strict"

const Assert = require('assert')
, Net = require('net')
, Constants = require('./constants')
, Ref = require('ref-napi')
, FFIBindings = require('./ffi-bindings')


function _isSocket(socket) {
return socket instanceof Net.Socket
}

function _getSocketFD(socket) {
var ref
, fd = (ref = socket._handle) != null ? ref.fd : void 0
const _isSocket = (socket) => socket instanceof Net.Socket

const _getSocketFD = (socket) => {
const fd = socket._handle != null ? socket._handle.fd : undefined
Assert(fd && fd !== -1, 'Unable to get socket fd')
return fd
}
Expand All @@ -26,7 +24,7 @@ function setKeepAliveInterval(socket, msecs) {
Assert.strictEqual(msecs != null ? msecs.constructor : void 0,
Number, 'setKeepAliveInterval requires msec to be a Number')

var fd = _getSocketFD(socket)
const fd = _getSocketFD(socket)
, seconds = ~~(msecs / 1000)
, intvlVal = Ref.alloc('int', seconds)
, intvlValLn = intvlVal.type.size
Expand All @@ -42,17 +40,14 @@ function getKeepAliveInterval(socket) {
'getKeepAliveInterval expects an instance of socket as its first ' +
'argument')

var fd = _getSocketFD(socket)
, intvl
const fd = _getSocketFD(socket)
, intvlVal = Ref.alloc(Ref.types.uint32)
, intvlValLn = Ref.alloc(Ref.types.uint32, intvlVal.type.size)

FFIBindings.getsockopt(fd, Constants.SOL_TCP,
Constants.TCP_KEEPINTVL, intvlVal, intvlValLn)

intvl = intvlVal.deref() * 1000;

return intvl
return intvlVal.deref() * 1000
}

function setKeepAliveProbes(socket, cnt) {
Expand All @@ -64,7 +59,7 @@ function setKeepAliveProbes(socket, cnt) {
Assert.strictEqual(cnt != null ? cnt.constructor : void 0,
Number, 'setKeepAliveProbes requires cnt to be a Number')

var fd = _getSocketFD(socket)
const fd = _getSocketFD(socket)
, count = ~~(cnt)
, cntVal = Ref.alloc('int', count)
, cntValLn = cntVal.type.size
Expand All @@ -80,22 +75,19 @@ function getKeepAliveProbes(socket) {
'getKeepAliveProbes expects an instance of socket as its first ' +
'argument')

var fd = _getSocketFD(socket)
, cnt
const fd = _getSocketFD(socket)
, cntVal = Ref.alloc(Ref.types.int)
, cntValLn = Ref.alloc(Ref.types.int, cntVal.type.size)

FFIBindings.getsockopt(fd, Constants.SOL_TCP,
Constants.TCP_KEEPCNT, cntVal, cntValLn)

cnt = cntVal.deref()

return cnt
return cntVal.deref()
}

module.exports = {
getKeepAliveInterval: getKeepAliveInterval,
setKeepAliveInterval: setKeepAliveInterval,
getKeepAliveProbes: getKeepAliveProbes,
setKeepAliveProbes: setKeepAliveProbes
};
getKeepAliveInterval,
setKeepAliveInterval,
getKeepAliveProbes,
setKeepAliveProbes
}
74 changes: 38 additions & 36 deletions test/test-commons.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
var Mockery = require('mockery')
"use strict"

const Mockery = require('mockery')
, Should = require('should')
, Sinon = require('sinon')

describe('commons', function(){
var sandbox
beforeEach(function(){
describe('commons', () => {

let sandbox
beforeEach(() => {
Mockery.enable({
warnOnReplace: true,
warnOnUnregistered: true,
Expand All @@ -14,22 +16,22 @@ describe('commons', function(){
Mockery.registerAllowable('../lib/commons')
sandbox = Sinon.createSandbox()
})
afterEach(function(){

afterEach(() => {
sandbox.restore()
Mockery.deregisterAllowable('../lib/commons')
Mockery.disable()
})
it('should export errnoException function and return exception', function(){

it('should export errnoException function and return exception', () => {
Mockery.registerAllowable('util')
require('../lib/commons').should.have.property('errnoException')
.which.is.a.Function()
Mockery.deregisterAllowable('util')
})
it('should return errnoException style Error', function(){
Mockery.registerAllowable('util')

it('should return errnoException style Error', () => {
Mockery.registerAllowable('util')
require('../lib/commons').errnoException(999, 'test_syscall_name', 'original')
.should.be.instanceOf(Error)
.and.have.properties(['message', 'code', 'errno', 'syscall'])
Expand All @@ -38,43 +40,43 @@ describe('commons', function(){
})
Mockery.deregisterAllowable('util')
})
it('should use util._errnoException when available', function(){
var _errnoExceptionStub = sandbox.stub()

it('should use util._errnoException when available', () => {

const _errnoExceptionStub = sandbox.stub()


Mockery.registerMock('util', {
_errnoException: _errnoExceptionStub
})

require('../lib/commons').errnoException(999, 'TEST_SYSCALL_NAME', 'original')

Mockery.deregisterMock('util')
sandbox.assert.calledOnce(_errnoExceptionStub)

sandbox.assert.calledOnce(_errnoExceptionStub)
sandbox.assert.calledWith(_errnoExceptionStub, -999, 'TEST_SYSCALL_NAME', 'original')
})
it('should try use libuv.errname otherwise', function(){

it('should try use libuv.errname otherwise', () => {

Mockery.registerMock('util', {})
sandbox.stub(process, 'binding')
var uvErrnameStub = Sinon.stub()

sandbox.stub(process, 'binding')
const uvErrnameStub = Sinon.stub()

process.binding.withArgs('uv')
.returns({errname: uvErrnameStub})
require('../lib/commons').errnoException(999, 'TEST_SYSCALL_NAME', 'original')
sandbox.assert.calledOnce(process.binding)

require('../lib/commons').errnoException(999, 'TEST_SYSCALL_NAME', 'original')

sandbox.assert.calledOnce(process.binding)
sandbox.assert.calledWith(process.binding, 'uv')
Sinon.assert.calledOnce(uvErrnameStub)

Sinon.assert.calledOnce(uvErrnameStub)
Sinon.assert.calledWith(uvErrnameStub, -999)
Mockery.deregisterMock('util')

Mockery.deregisterMock('util')
})

})
Loading

0 comments on commit df05f62

Please sign in to comment.