Termux:Widget and Emacs: can't start subprocesses I have some tasks that I like to do using Emacs on several different operating systems.
I have been using Termux so that I can access these tasks on my Android phone.
To reduce setting-up typing in the file-editing part of this workflow, I've installed Termux:Widget and written a two-line widget script that does

filename=$(a little shell logic)
emacs $filename


So now my phone has a button on the home screen that I can push and it opens up the file that I want in the editor.  That part all works fine.

Frequently, once I've started editing, it's convenient to run a shell script.  It's nice to be able to run the shell script in an Emacs buffer so that I can use the regular buffer-switching commands to interact with it.  If I open a fresh Termux session and type emacs at the prompt, then I can do M-x async-shell-command, use relative filenames and tab completion to find the name of the script that I want (e.g. ../my-script.sh), and execute it from within Emacs.  That part works fine.

However, if I've started Emacs from Termux:Widget, Emacs is unable to spawn subprocesses.  I get errors like

/data/data/com.termux/files/usr/bin/sh:  1: ../my-script.sh: not found
/data/data/com.termux/files/usr/bin/sh:  1: /data/data/com.termux/files/home/whatever/my-script.sh: not found


I believe the relative and absolute path names are correct because I am using tab-completion to check them before asking to execute.

This seems like the kind of problem that termux-exec was invented to fix.  However, it isn't working by magic, and I'm finding myself confused by the documentation.
I solved this while I was trying to be thorough while writing the question: it was in the documentation, I just couldn't figure it out.
I needed to set LD_PRELOAD, as documented by termux-exec, so that Emacs runs with the modified version of the exec() system call.  My two-line script is now

PREFIX=/data/data/com.termux/files/usr
TERMUX_EXEC=${PREFIX}/lib/libtermux-exec.so
[ -e $TERMUX_EXEC ] &amp;&amp; export LD_PRELOAD=$TERMUX_EXEC
filename=$(a little shell logic)
emacs $filename


The extra existence-checking cruft is so that LD_PRELOAD remains unset (or unmodified) where I run this same convenient script on my non-Termux systems.