Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Functions registered with zle -F stop being run after a job finishes
- X-seq: zsh-workers 44167
- From: Roman Perepelitsa <roman.perepelitsa@xxxxxxxxx>
- To: zsh-workers@xxxxxxx
- Subject: Functions registered with zle -F stop being run after a job finishes
- Date: Sat, 23 Mar 2019 14:55:40 +0100
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=oq87YsOTPUJM88PAmwBb2xtRTNY7sBpy4BwwcRSCV9A=; b=eFEpCYkiOnfeRgzqVXDCtnrpyBZYAHB/EcdjLJGOUn2fuU8LsYYmZoCgRaCE4gLjfe jm7q047vAREXxRqHGviT81weKKh23ACulxSMOv/GBU0zYOrT7hclaTA6R2quFXtjtnqA p6zg8LOG/hvrmBDMNGLCScDly0JYT99lof0hJpfljs/PcuDJbYsHSUnVHKJTJY/AQD0p 0ngrJAI5ZIQpAycMAM3Ey5Qohu0fFuDOVePOCPuDgXNZkD3ZxAFcqUXFHdLxCTZwQew0 A+k4Dt4oCz3Vbe3Ix38RhqqnhIcJybX0cRbi0Ja9fvhgYZFV+IRZaXpSzHf+88hTsg2+ BzyA==
- List-help: <mailto:zsh-workers-help@zsh.org>
- List-id: Zsh Workers List <zsh-workers.zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- List-unsubscribe: <mailto:zsh-workers-unsubscribe@zsh.org>
- Mailing-list: contact zsh-workers-help@xxxxxxx; run by ezmlm
Hi,
tl;dr: There appears to be a bug in zsh. When a background job finishes,
functions registered with zle -F stop running until the user presses a key
(say, [enter] or [esc]) or the shell receives a signal (any signal at all).
Assuming the pristine environment granted by zsh -df, consider the
following piece of code.
mkfifo /tmp/fifoexec {fd}<>/tmp/fifo
( for ((i=1;;++i)); do sleep 1; echo $i; done ) >&$fd &
function f() { zle -I && read -eu $fd }
zle -F $fd f
sleep 5&
( sleep 10; kill -WINCH $$ ) &
It creates a fifo, to which a background job writes consecutive numbers
once a second. It then uses zle -F to register a function that gets called
whenever there is something in the fifo. The function reads and prints the
content of the fifo.
This part of the code produces the following output:
adam%
1
adam%
2
adam%
3
And so on, with one line every second. The code also creates a background
job that doesn’t do anything and finishes after 5 seconds. The expected
behavior is that we’ll keep seeing consecutive numbers on the screen after
this job finishes but that’s not what happens. In fact, the output stops.
adam%
4
adam%
[2] + done sleep 5
adam%
If we hit [esc] or [enter] at this point, the missing numbers will appear
all at once and the new numbers will continue being printed once a second.
Instead of pressing a key we can send our shell a signal. It’ll have the
same effect. Any signal will do as long as it doesn’t kill the process. For
example, we can define a signal handler for SIGUSR1 and execute kill -USR1
$pid from another shell. Or, like the code snippet does, we can send
SIGWINCH, taking advantage of its having the default handler that does
nothing.
Here’s the complete output where you can see everything in action:
adam% mkfifo /tmp/fifo
exec {fd}<>/tmp/fifo
( for ((i=1;;++i)); do sleep 1; echo $i; done ) >&$fd &
function f() { zle -I && read -eu $fd }
zle -F $fd f
sleep 5&
( sleep 10; kill -WINCH $$ ) &
[1] 9468
[2] 9469
[3] 9471
adam%
1
adam%
2
adam%
3
adam%
4
adam%
[2] - done sleep 5
adam%
5
[3] + done ( sleep 10; kill -WINCH $$; )
adam% adam%
6
adam%
7
adam%
8
adam%
9
adam%
10
adam%
11
adam%
12
adam%
And so on.
Roman.
Messages sorted by:
Reverse Date,
Date,
Thread,
Author