Skip to content

Commit

Permalink
Add filesystem-based checks for libc family only #1
Browse files Browse the repository at this point in the history
  • Loading branch information
lovell committed Jul 13, 2017
1 parent 7b36e34 commit 0381ad7
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 5 deletions.
2 changes: 2 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.nyc_output
.travis.yml
coverage
test.js
node_modules
21 changes: 18 additions & 3 deletions lib/detect-libc.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

const platform = require('os').platform();
const spawnSync = require('child_process').spawnSync;
const readdirSync = require('fs').readdirSync;

const GLIBC = 'glibc';
const MUSL = 'musl';
Expand All @@ -11,6 +12,12 @@ const spawnOptions = {
env: process.env
};

function contains (needle) {
return function (haystack) {
return haystack.indexOf(needle) !== -1;
};
}

let family = '';
let version = '';

Expand All @@ -23,10 +30,18 @@ if (platform === 'linux') {
} else {
// Try ldd
const ldd = spawnSync('ldd', ['--version'], spawnOptions);
if (ldd.status === 0) {
if (ldd.stdout.indexOf('musl') !== -1) {
if (ldd.status === 0 && ldd.stdout.indexOf('musl') !== -1) {
family = MUSL;
version = ldd.stdout.split(/[\r\n]+/)[1].trim().split(/\s/)[1];
} else {
// Try filesystem (family only)
const lib = readdirSync('/lib');
if (lib.some(contains('-linux-gnu'))) {
family = GLIBC;
} else if (lib.some(contains('libc.musl-'))) {
family = MUSL;
} else if (lib.some(contains('ld-musl-'))) {
family = MUSL;
version = ldd.stdout.split(/[\r\n]+/)[1].trim().split(/\s/)[1];
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"name": "detect-libc",
"version": "0.1.0",
"version": "0.2.0",
"description": "Node.js module to detect the C standard library (libc) implementation family and version",
"main": "lib/detect-libc.js",
"bin": {
"detect-libc": "./bin/detect-libc.js"
},
"scripts": {
"test": "semistandard && ava"
"test": "semistandard && nyc --reporter=lcov ava"
},
"repository": {
"type": "git",
Expand All @@ -22,6 +22,7 @@
"license": "Apache-2.0",
"devDependencies": {
"ava": "^0.20.0",
"nyc": "^11.0.3",
"proxyquire": "^1.8.0",
"semistandard": "^11.0.0"
},
Expand Down
112 changes: 112 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,115 @@ ava('win32 is ignored', function (t) {
t.is('', libc.version);
t.false(libc.isNonGlibcLinux);
});

ava('Linux detect glibc from filesystem', function (t) {
t.plan(5);

const libc = proxyquire('./', {
os: {
platform: function () {
return 'linux';
}
},
child_process: {
spawnSync: function () {
return { status: -1 };
}
},
fs: {
readdirSync: function () {
return ['init', 'modprobe.d', 'modules', 'resolvconf', 'systemd', 'udev', 'x86_64-linux-gnu', 'xtables'];
}
}
});

t.is('glibc', libc.GLIBC);
t.is('musl', libc.MUSL);
t.is(libc.GLIBC, libc.family);
t.is('', libc.version);
t.false(libc.isNonGlibcLinux);
});

ava('Linux detect musl from filesystem', function (t) {
t.plan(5);

const libc = proxyquire('./', {
os: {
platform: function () {
return 'linux';
}
},
child_process: {
spawnSync: function () {
return { status: -1 };
}
},
fs: {
readdirSync: function () {
return ['apk', 'firmware', 'ld-musl-x86_64.so.1', 'libc.musl-x86_64.so.1', 'libz.so.1', 'libz.so.1.2.11', 'mdev'];
}
}
});

t.is('glibc', libc.GLIBC);
t.is('musl', libc.MUSL);
t.is(libc.MUSL, libc.family);
t.is('', libc.version);
t.true(libc.isNonGlibcLinux);
});

ava('NodeOS detect musl from filesystem', function (t) {
t.plan(5);

const libc = proxyquire('./', {
os: {
platform: function () {
return 'linux';
}
},
child_process: {
spawnSync: function () {
return { status: -1 };
}
},
fs: {
readdirSync: function () {
return ['ld-musl-x86_64.so.1', 'libc.so', 'libfuse.so', 'libfuse.so.2', 'libfuse.so.2.9.7', 'libgcc_s.so.1', 'libstdc++.so.6', 'libstdc++.so.6.0.21', 'node_modules'];
}
}
});

t.is('glibc', libc.GLIBC);
t.is('musl', libc.MUSL);
t.is(libc.MUSL, libc.family);
t.is('', libc.version);
t.true(libc.isNonGlibcLinux);
});

ava('Linux fail to detect from filesystem', function (t) {
t.plan(5);

const libc = proxyquire('./', {
os: {
platform: function () {
return 'linux';
}
},
child_process: {
spawnSync: function () {
return { status: -1 };
}
},
fs: {
readdirSync: function () {
return [];
}
}
});

t.is('glibc', libc.GLIBC);
t.is('musl', libc.MUSL);
t.is('', libc.family);
t.is('', libc.version);
t.false(libc.isNonGlibcLinux);
});

0 comments on commit 0381ad7

Please sign in to comment.