Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Zsh spins in endless loop with SIGHUP + read in zshexit
- X-seq: zsh-users 26735
- From: Peter Stephenson <p.w.stephenson@xxxxxxxxxxxx>
- To: Jörg Sommer <joerg@xxxxxxxx>, zsh-users@xxxxxxx
- Subject: Re: Zsh spins in endless loop with SIGHUP + read in zshexit
- Date: Thu, 13 May 2021 16:51:14 +0100 (BST)
- Archived-at: <https://zsh.org/users/26735>
- Importance: Medium
- In-reply-to: <20210513101751.j5vo2dbrd5uzwju4@jo-so.de>
- List-id: <zsh-users.zsh.org>
- References: <20210513101751.j5vo2dbrd5uzwju4@jo-so.de>
> On 13 May 2021 at 11:17 Jörg Sommer <joerg@xxxxxxxx> wrote:
> I'm using `read` in `zshexit` and when my terminal crashes (e.g. XTerm gets
> killed or ssh connection dies) Zsh spins in an endless loop until I kill it
> with SIGKILL (SIGTERM doesn't work).
>
> ```
> zshexit()
> {
> if [[ ${#${(M)${(f)"$(</proc/self/mountinfo)"}#*/ / rw,}} == 1 ]]
> then
> if read -rq junk"?Root filesystem is still read-write. Remount ro? (y/N) "
> then
> echo
> mount -o remount,ro / || sleep 4
> else
> echo
> fi
> fi
> }
> ```
Yes, that's a clear bug. Bart's been mulling over some error handling oddities
down here, not sure if that's one of them. This is a bit of a special case ---
how about this? Possibly other calls to zexit() might need similar treatment.
(More zsh-workers this time round, as it turns out.)
Warning: I'm currently in webmailland, too, but the diff is originally from a
proper Linux set up.
pws
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index 0561c3b3b..e8d1260b1 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -905,7 +905,8 @@ getbyte(long do_keytmout, int *timeout, int full)
if ((zlereadflags & ZLRF_IGNOREEOF) && icnt++ < 20)
continue;
stopmsg = 1;
- zexit(1, ZEXIT_NORMAL);
+ if (zexit(1, ZEXIT_NORMAL))
+ return lastchar = EOF;
}
icnt = 0;
if (errno == EINTR) {
@@ -928,14 +929,15 @@ getbyte(long do_keytmout, int *timeout, int full)
} else if (errno != 0) {
zerr("error on TTY read: %e", errno);
stopmsg = 1;
- zexit(1, ZEXIT_NORMAL);
+ if (zexit(1, ZEXIT_NORMAL))
+ return lastchar = EOF;
}
}
if (cc == '\r') /* undo the exchange of \n and \r determined by */
cc = '\n'; /* zsetterm() */
else if (cc == '\n')
cc = '\r';
-
+
ret = STOUC(cc);
}
/*
diff --git a/Src/builtin.c b/Src/builtin.c
index b7ceefd55..aefd1436f 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -5816,10 +5816,14 @@ _realexit(void)
* ZEXIT_DEFERRED if we can't actually exit yet (e.g., functions need
* terminating) but should perform the usual interactive
* tests.
+ *
+ * If this returns 1, we are already exiting the shell: deeply
+ * embedded calls to this function should give up at that point
+ * and return an error indication.
*/
/**/
-mod_export void
+mod_export int
zexit(int val, enum zexit_t from_where)
{
/*
@@ -5829,7 +5833,7 @@ zexit(int val, enum zexit_t from_where)
*/
exit_val = val;
if (shell_exiting == -1)
- return;
+ return 1;
if (isset(MONITOR) && !stopmsg && from_where != ZEXIT_SIGNAL) {
scanjobs(); /* check if jobs need printing */
@@ -5837,13 +5841,13 @@ zexit(int val, enum zexit_t from_where)
checkjobs(); /* check if any jobs are running/stopped */
if (stopmsg) {
stopmsg = 2;
- return;
+ return 0;
}
}
/* Positive shell_exiting means we have been here before */
if (from_where == ZEXIT_DEFERRED ||
(shell_exiting++ && from_where != ZEXIT_NORMAL))
- return;
+ return 0;
/*
* We're now committed to exiting. Set shell_exiting to -1 to
@@ -5893,6 +5897,8 @@ zexit(int val, enum zexit_t from_where)
_exit(exit_val);
else
exit(exit_val);
+ /*NOTREACHED*/ /* I hope */
+ return 0;
}
/* . (dot), source */
Messages sorted by:
Reverse Date,
Date,
Thread,
Author