'use strict'; var platform = require('os').platform(); var spawnSync = require('child_process').spawnSync; var readdirSync = require('fs').readdirSync; var GLIBC = 'glibc'; var MUSL = 'musl'; var spawnOptions = { encoding: 'utf8', env: process.env }; if (!spawnSync) { spawnSync = function () { return { status: 126, stdout: '', stderr: '' }; }; } function contains (needle) { return function (haystack) { return haystack.indexOf(needle) !== -1; }; } function versionFromMuslLdd (out) { return out.split(/[\r\n]+/)[1].trim().split(/\s/)[1]; } function safeReaddirSync (path) { try { return readdirSync(path); } catch (e) {} return []; } var family = ''; var version = ''; var method = ''; if (platform === 'linux') { // Try getconf var glibc = spawnSync('getconf', ['GNU_LIBC_VERSION'], spawnOptions); if (glibc.status === 0) { family = GLIBC; version = glibc.stdout.trim().split(' ')[1]; method = 'getconf'; } else { // Try ldd var ldd = spawnSync('ldd', ['--version'], spawnOptions); if (ldd.status === 0 && ldd.stdout.indexOf(MUSL) !== -1) { family = MUSL; version = versionFromMuslLdd(ldd.stdout); method = 'ldd'; } else if (ldd.status === 1 && ldd.stderr.indexOf(MUSL) !== -1) { family = MUSL; version = versionFromMuslLdd(ldd.stderr); method = 'ldd'; } else { // Try filesystem (family only) var lib = safeReaddirSync('/lib'); if (lib.some(contains('-linux-gnu'))) { family = GLIBC; method = 'filesystem'; } else if (lib.some(contains('libc.musl-'))) { family = MUSL; method = 'filesystem'; } else if (lib.some(contains('ld-musl-'))) { family = MUSL; method = 'filesystem'; } else { var usrSbin = safeReaddirSync('/usr/sbin'); if (usrSbin.some(contains('glibc'))) { family = GLIBC; method = 'filesystem'; } } } } } var isNonGlibcLinux = (family !== '' && family !== GLIBC); module.exports = { GLIBC: GLIBC, MUSL: MUSL, family: family, version: version, method: method, isNonGlibcLinux: isNonGlibcLinux };