123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- 'use strict';
- const childProcess = require('child_process');
- const { isLinux, getReport } = require('./process');
- const command = 'getconf GNU_LIBC_VERSION 2>&1 || true; ldd --version 2>&1 || true';
- let commandOut = '';
- const safeCommand = () => {
- if (!commandOut) {
- return new Promise((resolve) => {
- childProcess.exec(command, (err, out) => {
- commandOut = err ? ' ' : out;
- resolve(commandOut);
- });
- });
- }
- return commandOut;
- };
- const safeCommandSync = () => {
- if (!commandOut) {
- try {
- commandOut = childProcess.execSync(command, { encoding: 'utf8' });
- } catch (_err) {
- commandOut = ' ';
- }
- }
- return commandOut;
- };
- /**
- * A String constant containing the value `glibc`.
- * @type {string}
- * @public
- */
- const GLIBC = 'glibc';
- /**
- * A String constant containing the value `musl`.
- * @type {string}
- * @public
- */
- const MUSL = 'musl';
- const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-');
- const familyFromReport = () => {
- const report = getReport();
- if (report.header && report.header.glibcVersionRuntime) {
- return GLIBC;
- }
- if (Array.isArray(report.sharedObjects)) {
- if (report.sharedObjects.some(isFileMusl)) {
- return MUSL;
- }
- }
- return null;
- };
- const familyFromCommand = (out) => {
- const [getconf, ldd1] = out.split(/[\r\n]+/);
- if (getconf && getconf.includes(GLIBC)) {
- return GLIBC;
- }
- if (ldd1 && ldd1.includes(MUSL)) {
- return MUSL;
- }
- return null;
- };
- /**
- * Resolves with the libc family when it can be determined, `null` otherwise.
- * @returns {Promise<?string>}
- */
- const family = async () => {
- let family = null;
- if (isLinux()) {
- family = familyFromReport();
- if (!family) {
- const out = await safeCommand();
- family = familyFromCommand(out);
- }
- }
- return family;
- };
- /**
- * Returns the libc family when it can be determined, `null` otherwise.
- * @returns {?string}
- */
- const familySync = () => {
- let family = null;
- if (isLinux()) {
- family = familyFromReport();
- if (!family) {
- const out = safeCommandSync();
- family = familyFromCommand(out);
- }
- }
- return family;
- };
- /**
- * Resolves `true` only when the platform is Linux and the libc family is not `glibc`.
- * @returns {Promise<boolean>}
- */
- const isNonGlibcLinux = async () => isLinux() && await family() !== GLIBC;
- /**
- * Returns `true` only when the platform is Linux and the libc family is not `glibc`.
- * @returns {boolean}
- */
- const isNonGlibcLinuxSync = () => isLinux() && familySync() !== GLIBC;
- const versionFromReport = () => {
- const report = getReport();
- if (report.header && report.header.glibcVersionRuntime) {
- return report.header.glibcVersionRuntime;
- }
- return null;
- };
- const versionSuffix = (s) => s.trim().split(/\s+/)[1];
- const versionFromCommand = (out) => {
- const [getconf, ldd1, ldd2] = out.split(/[\r\n]+/);
- if (getconf && getconf.includes(GLIBC)) {
- return versionSuffix(getconf);
- }
- if (ldd1 && ldd2 && ldd1.includes(MUSL)) {
- return versionSuffix(ldd2);
- }
- return null;
- };
- /**
- * Resolves with the libc version when it can be determined, `null` otherwise.
- * @returns {Promise<?string>}
- */
- const version = async () => {
- let version = null;
- if (isLinux()) {
- version = versionFromReport();
- if (!version) {
- const out = await safeCommand();
- version = versionFromCommand(out);
- }
- }
- return version;
- };
- /**
- * Returns the libc version when it can be determined, `null` otherwise.
- * @returns {?string}
- */
- const versionSync = () => {
- let version = null;
- if (isLinux()) {
- version = versionFromReport();
- if (!version) {
- const out = safeCommandSync();
- version = versionFromCommand(out);
- }
- }
- return version;
- };
- module.exports = {
- GLIBC,
- MUSL,
- family,
- familySync,
- isNonGlibcLinux,
- isNonGlibcLinuxSync,
- version,
- versionSync
- };
|