55
66const childProcess = require ( 'child_process' ) ;
77const { isLinux, getReport } = require ( './process' ) ;
8+ const { LDD_PATH , readFile, readFileSync } = require ( './filesystem' ) ;
9+
10+ let cachedFamilyFilesystem ;
11+ let cachedVersionFilesystem ;
812
913const command = 'getconf GNU_LIBC_VERSION 2>&1 || true; ldd --version 2>&1 || true' ;
1014let commandOut = '' ;
@@ -39,13 +43,31 @@ const safeCommandSync = () => {
3943 */
4044const GLIBC = 'glibc' ;
4145
46+ /**
47+ * A Regexp constant to get the GLIBC Version.
48+ * @type {string }
49+ */
50+ const RE_GLIBC_VERSION = / G L I B C \s ( \d + \. \d + ) / ;
51+
4252/**
4353 * A String constant containing the value `musl`.
4454 * @type {string }
4555 * @public
4656 */
4757const MUSL = 'musl' ;
4858
59+ /**
60+ * This string is used to find if the {@link LDD_PATH} is GLIBC
61+ * @type {string }
62+ */
63+ const GLIBC_ON_LDD = GLIBC . toUpperCase ( ) ;
64+
65+ /**
66+ * This string is used to find if the {@link LDD_PATH} is musl
67+ * @type {string }
68+ */
69+ const MUSL_ON_LDD = MUSL . toLowerCase ( ) ;
70+
4971const isFileMusl = ( f ) => f . includes ( 'libc.musl-' ) || f . includes ( 'ld-musl-' ) ;
5072
5173const familyFromReport = ( ) => {
@@ -72,14 +94,51 @@ const familyFromCommand = (out) => {
7294 return null ;
7395} ;
7496
97+ const getFamilyFromLddContent = ( content ) => {
98+ if ( content . includes ( MUSL_ON_LDD ) ) {
99+ return MUSL ;
100+ }
101+ if ( content . includes ( GLIBC_ON_LDD ) ) {
102+ return GLIBC ;
103+ }
104+ return null ;
105+ } ;
106+
107+ const familyFromFilesystem = async ( ) => {
108+ if ( cachedFamilyFilesystem !== undefined ) {
109+ return cachedFamilyFilesystem ;
110+ }
111+ cachedFamilyFilesystem = null ;
112+ try {
113+ const lddContent = await readFile ( LDD_PATH ) ;
114+ cachedFamilyFilesystem = getFamilyFromLddContent ( lddContent ) ;
115+ } catch ( e ) { }
116+ return cachedFamilyFilesystem ;
117+ } ;
118+
119+ const familyFromFilesystemSync = ( ) => {
120+ if ( cachedFamilyFilesystem !== undefined ) {
121+ return cachedFamilyFilesystem ;
122+ }
123+ cachedFamilyFilesystem = null ;
124+ try {
125+ const lddContent = readFileSync ( LDD_PATH ) ;
126+ cachedFamilyFilesystem = getFamilyFromLddContent ( lddContent ) ;
127+ } catch ( e ) { }
128+ return cachedFamilyFilesystem ;
129+ } ;
130+
75131/**
76132 * Resolves with the libc family when it can be determined, `null` otherwise.
77133 * @returns {Promise<?string> }
78134 */
79135const family = async ( ) => {
80136 let family = null ;
81137 if ( isLinux ( ) ) {
82- family = familyFromReport ( ) ;
138+ family = await familyFromFilesystem ( ) ;
139+ if ( ! family ) {
140+ family = familyFromReport ( ) ;
141+ }
83142 if ( ! family ) {
84143 const out = await safeCommand ( ) ;
85144 family = familyFromCommand ( out ) ;
@@ -95,7 +154,10 @@ const family = async () => {
95154const familySync = ( ) => {
96155 let family = null ;
97156 if ( isLinux ( ) ) {
98- family = familyFromReport ( ) ;
157+ family = familyFromFilesystemSync ( ) ;
158+ if ( ! family ) {
159+ family = familyFromReport ( ) ;
160+ }
99161 if ( ! family ) {
100162 const out = safeCommandSync ( ) ;
101163 family = familyFromCommand ( out ) ;
@@ -116,6 +178,38 @@ const isNonGlibcLinux = async () => isLinux() && await family() !== GLIBC;
116178 */
117179const isNonGlibcLinuxSync = ( ) => isLinux ( ) && familySync ( ) !== GLIBC ;
118180
181+ const versionFromFilesystem = async ( ) => {
182+ if ( cachedVersionFilesystem !== undefined ) {
183+ return cachedVersionFilesystem ;
184+ }
185+ cachedVersionFilesystem = null ;
186+ try {
187+ const lddContent = await readFile ( LDD_PATH ) ;
188+ const versionMatch = lddContent . match ( RE_GLIBC_VERSION ) ;
189+
190+ if ( versionMatch ) {
191+ cachedVersionFilesystem = versionMatch [ 1 ] ;
192+ }
193+ } catch ( e ) { }
194+ return cachedVersionFilesystem ;
195+ } ;
196+
197+ const versionFromFilesystemSync = ( ) => {
198+ if ( cachedVersionFilesystem !== undefined ) {
199+ return cachedVersionFilesystem ;
200+ }
201+ cachedVersionFilesystem = null ;
202+ try {
203+ const lddContent = readFileSync ( LDD_PATH ) ;
204+ const versionMatch = lddContent . match ( RE_GLIBC_VERSION ) ;
205+
206+ if ( versionMatch ) {
207+ cachedVersionFilesystem = versionMatch [ 1 ] ;
208+ }
209+ } catch ( e ) { }
210+ return cachedVersionFilesystem ;
211+ } ;
212+
119213const versionFromReport = ( ) => {
120214 const report = getReport ( ) ;
121215 if ( report . header && report . header . glibcVersionRuntime ) {
@@ -144,7 +238,10 @@ const versionFromCommand = (out) => {
144238const version = async ( ) => {
145239 let version = null ;
146240 if ( isLinux ( ) ) {
147- version = versionFromReport ( ) ;
241+ version = await versionFromFilesystem ( ) ;
242+ if ( ! version ) {
243+ version = versionFromReport ( ) ;
244+ }
148245 if ( ! version ) {
149246 const out = await safeCommand ( ) ;
150247 version = versionFromCommand ( out ) ;
@@ -160,7 +257,10 @@ const version = async () => {
160257const versionSync = ( ) => {
161258 let version = null ;
162259 if ( isLinux ( ) ) {
163- version = versionFromReport ( ) ;
260+ version = versionFromFilesystemSync ( ) ;
261+ if ( ! version ) {
262+ version = versionFromReport ( ) ;
263+ }
164264 if ( ! version ) {
165265 const out = safeCommandSync ( ) ;
166266 version = versionFromCommand ( out ) ;
0 commit comments