detect-libc.js 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. 'use strict';
  2. var platform = require('os').platform();
  3. var spawnSync = require('child_process').spawnSync;
  4. var readdirSync = require('fs').readdirSync;
  5. var GLIBC = 'glibc';
  6. var MUSL = 'musl';
  7. var spawnOptions = {
  8. encoding: 'utf8',
  9. env: process.env
  10. };
  11. if (!spawnSync) {
  12. spawnSync = function () {
  13. return { status: 126, stdout: '', stderr: '' };
  14. };
  15. }
  16. function contains (needle) {
  17. return function (haystack) {
  18. return haystack.indexOf(needle) !== -1;
  19. };
  20. }
  21. function versionFromMuslLdd (out) {
  22. return out.split(/[\r\n]+/)[1].trim().split(/\s/)[1];
  23. }
  24. function safeReaddirSync (path) {
  25. try {
  26. return readdirSync(path);
  27. } catch (e) {}
  28. return [];
  29. }
  30. var family = '';
  31. var version = '';
  32. var method = '';
  33. if (platform === 'linux') {
  34. // Try getconf
  35. var glibc = spawnSync('getconf', ['GNU_LIBC_VERSION'], spawnOptions);
  36. if (glibc.status === 0) {
  37. family = GLIBC;
  38. version = glibc.stdout.trim().split(' ')[1];
  39. method = 'getconf';
  40. } else {
  41. // Try ldd
  42. var ldd = spawnSync('ldd', ['--version'], spawnOptions);
  43. if (ldd.status === 0 && ldd.stdout.indexOf(MUSL) !== -1) {
  44. family = MUSL;
  45. version = versionFromMuslLdd(ldd.stdout);
  46. method = 'ldd';
  47. } else if (ldd.status === 1 && ldd.stderr.indexOf(MUSL) !== -1) {
  48. family = MUSL;
  49. version = versionFromMuslLdd(ldd.stderr);
  50. method = 'ldd';
  51. } else {
  52. // Try filesystem (family only)
  53. var lib = safeReaddirSync('/lib');
  54. if (lib.some(contains('-linux-gnu'))) {
  55. family = GLIBC;
  56. method = 'filesystem';
  57. } else if (lib.some(contains('libc.musl-'))) {
  58. family = MUSL;
  59. method = 'filesystem';
  60. } else if (lib.some(contains('ld-musl-'))) {
  61. family = MUSL;
  62. method = 'filesystem';
  63. } else {
  64. var usrSbin = safeReaddirSync('/usr/sbin');
  65. if (usrSbin.some(contains('glibc'))) {
  66. family = GLIBC;
  67. method = 'filesystem';
  68. }
  69. }
  70. }
  71. }
  72. }
  73. var isNonGlibcLinux = (family !== '' && family !== GLIBC);
  74. module.exports = {
  75. GLIBC: GLIBC,
  76. MUSL: MUSL,
  77. family: family,
  78. version: version,
  79. method: method,
  80. isNonGlibcLinux: isNonGlibcLinux
  81. };