Control: retitle -1 emacsen-addon package installation may never comes to an end
Control: severity -1 critical
Control: affects -1 = emacsen-common, elpa-company, elpa-js2-mode,
elpa-markdown-mode, elpa-systemd, elpa-yasnippet
This bug report is about the failed error handling in installing emacsen-addons
like *elpa-markdown-mode* or
*elpa-yasnippet*, et. al..
Especially all addons using this code fragment in there installer.
````
${FLAVOR} -q -batch -l package \
--eval "(add-to-list 'package-directory-list \"$src_dir\")" \
-f package-initialize -f batch-byte-compile *.el > Install.log 2>&1
```
In addition **all** addons relying on `emacs --batch` could be affected by this
bug.
What is going wrong?
--------------------
The code fragment relies on the following assumption:
**Emacs in batch mode will terminate and not getting stuck**
Why is this assumption not valid – please consult the bug #886153.
Here is described hot a stale emacs lock related to *anything-el* make emacs
--batch never terminating.
→ https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=886153
As a serious side effect all error messages are buried in „Install.log“ and
will not become visible until emacs
terminates – which in may case never happened.
Why is this a critical and security related problems
----------------------------------------------------
The problematic code fragment is invoked e.g. by `apt-get dist-upgrade` or
`dpkg --configure -a`.
These tasks will also got stuck without any reason displayed on the console.
So `apt-get dist-upgrade` got broken and it is likely that the user terminates
`apt-get` via kill (or simply reboot the
machine).
In this case he will be trapped in the pit, that he can't install any package
without fixing the „broken“ installation
of the emacsen-addon package via `dpkg --configure -a`.
This is also the case now for security related updates.
Affected Packages
------------------
I found the problematic code on my system in the
`/usr/lib/emacsen-common/packages/install` files for
- elpa-company
- elpa-js2-mode
- elpa-markdown-mode
- elpa-systemd
- elpa-yasnippet
A „code review“ of other packages will surely result in some more defective
packages.
How can this problem mitigated or fixed?
----------------------------------------
- A fix of bug #886153 would remove the trigger for the actual occurrence of
this problem. But what is with the next
defect in an emacs addon (or user stuff) breaking the batch processing again?
- A fix of of emacs concerning the `--batch` functionality – but this is maybe
not in scope.
See
https://www.gnu.org/software/emacs/manual/html_node/emacs/Initial-Options.html#Initial-Options
> „Functions that normally read keyboard input from the minibuffer take their
input from the terminal's standard
> input stream (stdin) instead.“
- Implement the assumption „emacs in batch mode will terminate and not getting
stuck“ in a wrapper script. See below for
a code outline.
What else is wrong with this emacsen addon installers.
------------------------------------------------------
It is may only a single line, but is is copied and paste between several
packages including the minor flaw that (see
`man emacs`) it should be `--batch` with a **double** hyphen.
Here a simple wrapper script would help to :
- avoid copy and paste errors
- simplify the fix of this bug
- simple reuse
Code outline for an emacs batch wrapper
----------------------------------------
Assume a bash script *emacs_batch* replacing the `-q --batch` options.
It should take as 1st option the emacs flavour (e.g. emacs25) and pass trough
all other options except `-q`,
`--no-init-file` (alias to `-q`) and `--batch`.
The emacs call could be implemented in this way:
```
declare -r catchFile=$(mktemp) # create temporary file for
output
trap rm --force ${catchFile} # and ensure cleanup
${FLAVOUR} --batch "${cmdlineOptions[@]}" &>"${catchFile}" & # fork
declare -i emacsPid=$! # and remember
sleep ${emacsTimeOut} & # fork timeout watch
declare -i sleepPid=$! # and remember
wait -n ${emacsPid} ${sleepPid} # -n → wait for the next
ending job
declare -r rc=$? # don't forget the exit code
if ! $(kill ${sleepPid})
then # oops run in timeout
… add error handling here
else # emacs terminates without
timeout
cat ${catchFile} # forward console output
exit ${rc} # rc is originating from emacs
fi
```
Note: `--batch` implies `-q`
(→
https://www.gnu.org/software/emacs/manual/html_node/emacs/Initial-Options.html#Initial-Options)