donsetch 3.2.1 → 3.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/install.js +60 -10
- package/package.json +1 -1
package/install.js
CHANGED
|
@@ -60,17 +60,67 @@ if (!plat) {
|
|
|
60
60
|
// The Linux binaries are glibc-linked. On musl systems they install
|
|
61
61
|
// fine but can never exec (missing ld-linux loader) — fail HERE with
|
|
62
62
|
// the actual cause instead of a cryptic spawn error on first run.
|
|
63
|
+
//
|
|
64
|
+
// Checking for /lib/ld-musl-*.so.1 existence is a false positive on
|
|
65
|
+
// glibc systems that also have musl installed as a secondary libc
|
|
66
|
+
// (e.g. Arch/Manjaro with the `musl` package). Instead, check what
|
|
67
|
+
// the RUNNING Node process actually uses: read /proc/self/exe's ELF
|
|
68
|
+
// interpreter (.interp section). On glibc it's ld-linux-*.so.2, on
|
|
69
|
+
// musl it's ld-musl-*.so.1. An env var escape hatch is also provided.
|
|
63
70
|
if (process.platform === 'linux') {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
// Escape hatch: force glibc path even on a musl system (user knows
|
|
72
|
+
// the binary will run, e.g. via gcompat or a glibc chroot).
|
|
73
|
+
if (process.env.DONSETCH_FORCE_GLIBC === '1') {
|
|
74
|
+
// skip musl check
|
|
75
|
+
} else {
|
|
76
|
+
let isMusl = false;
|
|
77
|
+
try {
|
|
78
|
+
// Read the ELF interpreter of /proc/self/exe (this Node process).
|
|
79
|
+
// The .interp section starts at offset 0x18 in the ELF header
|
|
80
|
+
// for the program header table, but the reliable way is to parse
|
|
81
|
+
// the program headers for PT_INTERP.
|
|
82
|
+
const exe = '/proc/self/exe';
|
|
83
|
+
const fd = fs.openSync(exe, 'r');
|
|
84
|
+
// ELF header: first 64 bytes for 64-bit.
|
|
85
|
+
const hdr = Buffer.alloc(64);
|
|
86
|
+
fs.readSync(fd, hdr, 0, 64, 0);
|
|
87
|
+
// e_phoff at offset 0x20 (64-bit), e_phentsize at 0x36, e_phnum at 0x38.
|
|
88
|
+
const e_phoff = hdr.readBigUInt64LE(0x20);
|
|
89
|
+
const e_phentsize = hdr.readUInt16LE(0x36);
|
|
90
|
+
const e_phnum = hdr.readUInt16LE(0x38);
|
|
91
|
+
for (let i = 0; i < e_phnum; i++) {
|
|
92
|
+
const ph = Buffer.alloc(e_phentsize);
|
|
93
|
+
fs.readSync(fd, ph, 0, e_phentsize, Number(e_phoff) + i * e_phentsize);
|
|
94
|
+
// PT_INTERP = 3
|
|
95
|
+
if (ph.readUInt32LE(0) === 3) {
|
|
96
|
+
// p_offset at 0x08 (64-bit), p_filesz at 0x20.
|
|
97
|
+
const p_offset = Number(ph.readBigUInt64LE(0x08));
|
|
98
|
+
const p_filesz = ph.readBigUInt64LE(0x20);
|
|
99
|
+
const interp = Buffer.alloc(Number(p_filesz));
|
|
100
|
+
fs.readSync(fd, interp, 0, Number(p_filesz), p_offset);
|
|
101
|
+
fs.closeSync(fd);
|
|
102
|
+
const loaderPath = interp.toString('ascii').replace(/\0/g, '').trim();
|
|
103
|
+
isMusl = loaderPath.includes('ld-musl');
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (!isMusl) fs.closeSync(fd);
|
|
108
|
+
} catch (_) {
|
|
109
|
+
// /proc/self/exe not readable (some containers). Fall back to
|
|
110
|
+
// the old existence check, but only as a last resort.
|
|
111
|
+
isMusl = fs.existsSync('/lib/ld-musl-x86_64.so.1')
|
|
112
|
+
|| fs.existsSync('/lib/ld-musl-aarch64.so.1');
|
|
113
|
+
}
|
|
114
|
+
if (isMusl) {
|
|
115
|
+
console.error('donsetch: musl libc detected (Alpine?).');
|
|
116
|
+
console.error('The prebuilt Linux binaries are glibc-linked and will not run.');
|
|
117
|
+
console.error('');
|
|
118
|
+
console.error('Options:');
|
|
119
|
+
console.error(' - build from source: git clone https://github.com/' + REPO + ' && cargo build --release');
|
|
120
|
+
console.error(' - use a glibc-based image/dist (debian, ubuntu, fedora)');
|
|
121
|
+
console.error(' - set DONSETCH_FORCE_GLIBC=1 if you have a glibc compat layer (gcompat)');
|
|
122
|
+
process.exit(1);
|
|
123
|
+
}
|
|
74
124
|
}
|
|
75
125
|
}
|
|
76
126
|
|