Skip to content

Commit

Permalink
perf(detect-libc): faster musl check by looking for ldd file
Browse files Browse the repository at this point in the history
  • Loading branch information
H4ad committed Jun 16, 2023
1 parent 0d170db commit 55ee3e1
Show file tree
Hide file tree
Showing 4 changed files with 344 additions and 22 deletions.
56 changes: 44 additions & 12 deletions lib/detect-libc.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@

const childProcess = require('child_process');
const { isLinux, getReport } = require('./process');
const { LDD_PATH, readFile, readFileSync } = require('./filesystem');

let cachedFamily;
const command = 'getconf GNU_LIBC_VERSION 2>&1 || true; ldd --version 2>&1 || true';
let commandOut = '';

Expand Down Expand Up @@ -77,31 +79,61 @@ const familyFromCommand = (out) => {
* @returns {Promise<?string>}
*/
const family = async () => {
let family = null;
if (cachedFamily !== undefined) {
return cachedFamily;
}
cachedFamily = null;
if (isLinux()) {
family = familyFromReport();
if (!family) {
const out = await safeCommand();
family = familyFromCommand(out);
try {
cachedFamily = await readFile(LDD_PATH)
.then(content => content.includes(MUSL))
.then(isMusl => isMusl ? MUSL : GLIBC);
} catch (e) {
// if permission model block access, we fallback to the old version
if (e.code === 'ERR_ACCESS_DENIED') {
cachedFamily = familyFromReport();
if (!cachedFamily) {
const out = await safeCommand();
cachedFamily = familyFromCommand(out);
}
} else {
// If ldd don't exist, accords https://wiki.musl-libc.org/faq.html we can assume
// that the system is musl because ldd is always present on non-musl linux.
cachedFamily = MUSL;
}
}
}
return family;
return cachedFamily;
};

/**
* Returns the libc family when it can be determined, `null` otherwise.
* @returns {?string}
*/
const familySync = () => {
let family = null;
if (cachedFamily !== undefined) {
return cachedFamily;
}
cachedFamily = null;
if (isLinux()) {
family = familyFromReport();
if (!family) {
const out = safeCommandSync();
family = familyFromCommand(out);
try {
cachedFamily = readFileSync(LDD_PATH).includes(MUSL) ? MUSL : GLIBC;
} catch (e) {
// if permission model block access, we fallback to the old version
if (e.code === 'ERR_ACCESS_DENIED') {
cachedFamily = familyFromReport();
if (!cachedFamily) {
const out = safeCommandSync();
cachedFamily = familyFromCommand(out);
}
} else {
// If ldd don't exist, accords https://wiki.musl-libc.org/faq.html we can assume
// that the system is musl because ldd is always present on non-musl linux.
cachedFamily = MUSL;
}
}
}
return family;
return cachedFamily;
};

/**
Expand Down
36 changes: 36 additions & 0 deletions lib/filesystem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
const fs = require('fs');

/**
* The path where we can find the ldd
*/
const LDD_PATH = '/usr/bin/ldd';

/**
* Read the content of a file synchronous
*
* @param {string} path
* @returns {string}
*/
const readFileSync = path => fs.readFileSync(path, 'utf-8');

/**
* Read the content of a file
*
* @param {string} path
* @returns {Promise<string>}
*/
const readFile = path => new Promise((resolve, reject) => {
fs.readFile(path, 'utf-8', (err, data) => {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});

module.exports = {
LDD_PATH,
readFileSync,
readFile
};
1 change: 1 addition & 0 deletions test/fixtexture-file.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1
Loading

0 comments on commit 55ee3e1

Please sign in to comment.