The prebuilt qjs-linux-<arch> binaries from quickjs-ng releases work on Android to some extent, because they are statically linked. However, the popen function (used by the runtime) always returns NULL on Android.
Root cause:
- On Linux,
popen internally calls posix_spawn(&child_pid, "/bin/sh", …), which hardcodes the path to /bin/sh.
- On Android, the standard shell is located at
/system/bin/sh, not /bin/sh.
- Therefore, any attempt to use
popen (e.g., via qjs executing shell commands) fails and returns NULL.
Expected behavior:
popen should work on Android by respecting the system’s actual shell location (e.g., /system/bin/sh), or it should be configurable to support different environments.
Suggested solution (for maintainers):
- Modify the internal
popen implementation or the shell path used in posix_spawn to be configurable (e.g., via an environment variable like QJS_SHELL or a compile-time option).
- Alternatively, use
execvp with sh and rely on PATH lookup, which might locate /system/bin/sh on Android.
- As a workaround, consider documenting that users on Android can set
PATH to include /system/bin before calling popen, but the current hardcoded path remains the real fix.
Environment:
- quickjs-ng release: e.g.,
qjs-linux-x86_64 (or any qjs-linux-* binary)
- Android: tested on Android 10+ (Termux or native environment)
Steps to reproduce:
- Download a
qjs-linux-<arch> binary from the releases page.
- Run it on Android (using e.g., Termux or an Android shell).
- Execute a simple JavaScript command that uses
popen, such as:
const file = std.popen("ping 127.0.0.1", "r");
console.log('file:',file);
Or any built‑in function that relies on popen.
- Observe that the command returns
null or fails silently.
Additional note:
This issue does not occur when building quickjs‑ng natively for Android (e.g., with $PREFIX/bin/sh properly resolved), only when using the prebuilt Linux‑targeted binaries on Android.
Thank you for maintaining quickjs‑ng! I’d appreciate any guidance or a fix for this cross‑platform compatibility issue.
The prebuilt
qjs-linux-<arch>binaries from quickjs-ng releases work on Android to some extent, because they are statically linked. However, thepopenfunction (used by the runtime) always returnsNULLon Android.Root cause:
popeninternally callsposix_spawn(&child_pid, "/bin/sh", …), which hardcodes the path to/bin/sh./system/bin/sh, not/bin/sh.popen(e.g., viaqjsexecuting shell commands) fails and returnsNULL.Expected behavior:
popenshould work on Android by respecting the system’s actual shell location (e.g.,/system/bin/sh), or it should be configurable to support different environments.Suggested solution (for maintainers):
popenimplementation or the shell path used inposix_spawnto be configurable (e.g., via an environment variable likeQJS_SHELLor a compile-time option).execvpwithshand rely onPATHlookup, which might locate/system/bin/shon Android.PATHto include/system/binbefore callingpopen, but the current hardcoded path remains the real fix.Environment:
qjs-linux-x86_64(or anyqjs-linux-*binary)Steps to reproduce:
qjs-linux-<arch>binary from the releases page.popen, such as:popen.nullor fails silently.Additional note:
This issue does not occur when building quickjs‑ng natively for Android (e.g., with
$PREFIX/bin/shproperly resolved), only when using the prebuilt Linux‑targeted binaries on Android.Thank you for maintaining quickjs‑ng! I’d appreciate any guidance or a fix for this cross‑platform compatibility issue.