Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

detect-libc

Package Overview
Dependencies
Maintainers
1
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

detect-libc - npm Package Compare versions

Comparing version 1.0.3 to 2.0.0

index.d.ts

236

lib/detect-libc.js
'use strict';
var platform = require('os').platform();
var spawnSync = require('child_process').spawnSync;
var readdirSync = require('fs').readdirSync;
const childProcess = require('child_process');
const { isLinux, getReport } = require('./process');
var GLIBC = 'glibc';
var MUSL = 'musl';
const command = 'getconf GNU_LIBC_VERSION 2>&1 || true; ldd --version 2>&1 || true';
let commandOut = '';
var spawnOptions = {
encoding: 'utf8',
env: process.env
const safeCommand = () => {
if (!commandOut) {
return new Promise((resolve) => {
childProcess.exec(command, (err, out) => {
commandOut = err ? ' ' : out;
resolve(commandOut);
});
});
}
return commandOut;
};
if (!spawnSync) {
spawnSync = function () {
return { status: 126, stdout: '', stderr: '' };
};
}
const safeCommandSync = () => {
if (!commandOut) {
try {
commandOut = childProcess.execSync(command, { encoding: 'utf8' });
} catch (_err) {
commandOut = ' ';
}
}
return commandOut;
};
function contains (needle) {
return function (haystack) {
return haystack.indexOf(needle) !== -1;
};
}
/**
* A String constant containing the value `glibc`.
* @type {string}
* @public
*/
const GLIBC = 'glibc';
function versionFromMuslLdd (out) {
return out.split(/[\r\n]+/)[1].trim().split(/\s/)[1];
}
/**
* A String constant containing the value `musl`.
* @type {string}
* @public
*/
const MUSL = 'musl';
function safeReaddirSync (path) {
try {
return readdirSync(path);
} catch (e) {}
return [];
}
const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-');
var family = '';
var version = '';
var method = '';
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;
};
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';
}
}
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;
};
var isNonGlibcLinux = (family !== '' && family !== GLIBC);
/**
* 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: GLIBC,
MUSL: MUSL,
family: family,
version: version,
method: method,
isNonGlibcLinux: isNonGlibcLinux
GLIBC,
MUSL,
family,
familySync,
isNonGlibcLinux,
isNonGlibcLinuxSync,
version,
versionSync
};
{
"name": "detect-libc",
"version": "1.0.3",
"version": "2.0.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"
},
"files": [
"lib/",
"index.d.ts"
],
"scripts": {
"test": "semistandard && nyc --reporter=lcov ava"
"test": "semistandard && nyc --reporter=lcov --check-coverage --branches=100 ava test/unit.js"
},

@@ -27,10 +28,10 @@ "repository": {

"devDependencies": {
"ava": "^0.23.0",
"nyc": "^11.3.0",
"proxyquire": "^1.8.0",
"semistandard": "^11.0.0"
"ava": "^2.4.0",
"nyc": "^15.1.0",
"proxyquire": "^2.1.3",
"semistandard": "^14.2.3"
},
"engines": {
"node": ">=0.10"
"node": ">=8"
}
}
# detect-libc
Node.js module to detect the C standard library (libc) implementation
family and version in use on a given Linux system.
Node.js module to detect details of the C standard library (libc)
implementation provided by a given Linux system.
Provides a value suitable for use with the `LIBC` option of
[prebuild](https://www.npmjs.com/package/prebuild),
[prebuild-ci](https://www.npmjs.com/package/prebuild-ci) and
[prebuild-install](https://www.npmjs.com/package/prebuild-install),
therefore allowing build and provision of pre-compiled binaries
for musl-based Linux e.g. Alpine as well as glibc-based.
Currently supports detection of GNU glibc and MUSL libc.
Currently supports libc detection of `glibc` and `musl`.
Provides asychronous and synchronous functions for the
family (e.g. `glibc`, `musl`) and version (e.g. `1.23`, `1.2.3`).
For previous v1.x releases, please see the
[v1](https://github.com/lovell/detect-libc/tree/v1) branch.
## Install

@@ -21,51 +20,134 @@

## Usage
## API
### API
### GLIBC
```ts
const GLIBC: string = 'glibc';
```
A String constant containing the value `glibc`.
### MUSL
```ts
const MUSL: string = 'musl';
```
A String constant containing the value `musl`.
### family
```ts
function family(): Promise<string | null>;
```
Resolves asychronously with:
* `glibc` or `musl` when the libc family can be determined
* `null` when the libc family cannot be determined
* `null` when run on a non-Linux platform
```js
const { GLIBC, MUSL, family, version, isNonGlibcLinux } = require('detect-libc');
const { family, GLIBC, MUSL } = require('detect-libc');
switch (await family()) {
case GLIBC: ...
case MUSL: ...
case null: ...
}
```
* `GLIBC` is a String containing the value "glibc" for comparison with `family`.
* `MUSL` is a String containing the value "musl" for comparison with `family`.
* `family` is a String representing the system libc family.
* `version` is a String representing the system libc version number.
* `isNonGlibcLinux` is a Boolean representing whether the system is a non-glibc Linux, e.g. Alpine.
### familySync
### detect-libc command line tool
```ts
function familySync(): string | null;
```
When run on a Linux system with a non-glibc libc,
the child command will be run with the `LIBC` environment variable
set to the relevant value.
Synchronous version of `family()`.
On all other platforms will run the child command as-is.
```js
const { familySync, GLIBC, MUSL } = require('detect-libc');
The command line feature requires `spawnSync` provided by Node v0.12+.
switch (familySync()) {
case GLIBC: ...
case MUSL: ...
case null: ...
}
```
```sh
detect-libc child-command
### version
```ts
function version(): Promise<string | null>;
```
## Integrating with prebuild
Resolves asychronously with:
```json
"scripts": {
"install": "detect-libc prebuild-install || node-gyp rebuild",
"test": "mocha && detect-libc prebuild-ci"
},
"dependencies": {
"detect-libc": "^1.0.2",
"prebuild-install": "^2.2.0"
},
"devDependencies": {
"prebuild": "^6.2.1",
"prebuild-ci": "^2.2.3"
}
* The version when it can be determined
* `null` when the libc family cannot be determined
* `null` when run on a non-Linux platform
```js
const { version } = require('detect-libc');
const v = await version();
if (v) {
const [major, minor, patch] = v.split('.');
}
```
## Licence
### versionSync
Copyright 2017 Lovell Fuller
```ts
function versionSync(): string | null;
```
Synchronous version of `version()`.
```js
const { versionSync } = require('detect-libc');
const v = versionSync();
if (v) {
const [major, minor, patch] = v.split('.');
}
```
### isNonGlibcLinux
```ts
function isNonGlibcLinux(): Promise<boolean>;
```
Resolves asychronously with:
* `false` when the libc family is `glibc`
* `true` when the libc family is not `glibc`
* `false` when run on a non-Linux platform
```js
const { isNonGlibcLinux } = require('detect-libc');
if (await isNonGlibcLinux()) { ... }
```
### isNonGlibcLinuxSync
```ts
function isNonGlibcLinuxSync(): boolean;
```
Synchronous version of `isNonGlibcLinux()`.
```js
const { isNonGlibcLinuxSync } = require('detect-libc');
if (isNonGlibcLinuxSync()) { ... }
```
## Licensing
Copyright 2017, 2022 Lovell Fuller
Licensed under the Apache License, Version 2.0 (the "License");

@@ -72,0 +154,0 @@ you may not use this file except in compliance with the License.

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc