Switch symlink function to also use libc on Linux

This uses a portable way to do symlinks, unlike /bin/ln, which only
works on systems that have this executable.
The libc loading is done exactly the same as other code parts, only the
name is different.
This commit is contained in:
Mynacol 2026-08-26 15:19:36 +00:00
parent e50679c455
commit b0d6fe0ea1

View file

@ -233,32 +233,23 @@ export let OS = {
);
try {
if (Services.appinfo.OS === "Darwin") {
const libc = ctypes.open(
Services.appinfo.OS === "Darwin" ? "libSystem.B.dylib" : "libc.so"
);
const symlink = libc.declare(
"symlink",
ctypes.default_abi,
ctypes.int, // return value
ctypes.char.ptr, // target
ctypes.char.ptr //linkpath
);
if (symlink(pathTarget, pathCreate)) {
throw new Error("Failed to create symlink at " + pathCreate);
}
}
// The above is failing with "invalid ELF header" for libc.so on GitHub Actions, so
// just use ln -s on non-macOS systems
else {
let ln = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
ln.initWithPath("/bin/ln");
let process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess);
process.init(ln);
let args = ["-s", pathTarget, pathCreate];
process.run(true, args, args.length);
// "libc.so" is usually a linker script rather than a real shared object, which
// fails with "invalid ELF header", and on some distros (e.g., NixOS) it doesn't
// exist at a standard path at all, so use the versioned name
const libc = ctypes.open(
Services.appinfo.OS === "Darwin" ? "libSystem.B.dylib" : "libc.so.6"
);
const symlink = libc.declare(
"symlink",
ctypes.default_abi,
ctypes.int, // return value
ctypes.char.ptr, // target
ctypes.char.ptr //linkpath
);
if (symlink(pathTarget, pathCreate)) {
throw new Error("Failed to create symlink at " + pathCreate);
}
}
catch (e) {