Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: PATCH: query terminal properties on ZLE startup



Bart Schaefer wrote:
> On Mon, Mar 3, 2025 at 1:07 PM Oliver Kiddle <opk@xxxxxxx> wrote:
> >
> > If someone comes up with a good name for a query timeout variable I can
>
> querywait?

A (partial) patch follows. Partial because I'm stuck on how to make it
respond to SIGINT and could use some help. Checking whether ch == 3
works but stty intr doesn't have to be Ctrl-C or someone might use kill.
getbyte() does use dont_queue_signals() before raw_getbyte(). I'd have
expected errflag to acquire a value of ERRFLAG_INT but I don't think the
signal handler ever gets called.

Signals are never the easiest things to understand. Most code bases,
I've dealt with only set a simple flag so zsh's is trickier. Even
aside from this issue, it has always seemed a miracle to me that traps
apparently work when signals are not queued given the very limited
permissible system calls from a signal handler.

The existing ZMAXTIMEOUT constant is broken for 64-bit systems because
it is derived from sizeof(time_t) but the parameter to poll is of type
int.

> I don't think ungetc() would help -- it just puts things back in the
> stdio buffer space, which will get discarded when the "exit" happens.

Of course, yes. Thanks.

> But didn't we change zsh I/O to intentionally stop reading at newlines
> to prevent this sort of thing?

Not quite sure which changes that might refer to. A type-ahead buffer
can contain lots of newlines and in order to get the the terminal query
responses, everything needs to be read. Only solutions I can think of
entail changes to the operating system.

Oliver

diff --git a/Doc/Zsh/params.yo b/Doc/Zsh/params.yo
index dbf48457d..f8a035b13 100644
--- a/Doc/Zsh/params.yo
+++ b/Doc/Zsh/params.yo
@@ -1771,6 +1771,13 @@ termcap and the tt(COLORTERM) environment variable.
 )
 enditem()
 )
+vindex(.term.querywait)
+item(tt(.term.querywait))(
+The time the shell waits, in hundredths of seconds, for the response to
+terminal queries.  A value of tt(`0') disables the timeout and the shell will
+wait indefinitely.  If not set, a default of tt(`50') or half a second is
+used.
+)
 vindex(TIMEFMT)
 item(tt(TIMEFMT))(
 The format of process time reports with the tt(time) keyword.
diff --git a/Src/Zle/termquery.c b/Src/Zle/termquery.c
index 1232a96bf..c696c6147 100644
--- a/Src/Zle/termquery.c
+++ b/Src/Zle/termquery.c
@@ -135,6 +135,7 @@ static char *VERVAR  = ".term.version";
 static char *BGVAR   = ".term.bg";
 static char *FGVAR   = ".term.fg";
 static char *MODEVAR = ".term.mode";
+static char *WAITVAR = ".term.querywait";
 
 /* Query sequences
  * using ESC\\ as ST instead of BEL because the bell was emitted on
@@ -209,6 +210,12 @@ probe_terminal(const char *tquery, seqstate_t *states,
     int finish = 0, number = 0;
     int ch;
     struct ttyinfo ti, torig;
+    struct value vbuf;
+    Value v = getvalue(&vbuf, &WAITVAR, 0);
+    long timeout = v ? -1 - getintvalue(v) : TIMEOUT;
+
+    if (timeout == -1)
+	timeout = -((long)1 << (sizeof(int)*8-11))*100;
 
     seqstate_t *curstate = states;
 
@@ -244,7 +251,7 @@ probe_terminal(const char *tquery, seqstate_t *states,
 		memset(current, 0, blen);
 		blen *= 2;
 	    }
-	    if ((ch = getbyte(TIMEOUT, 0, 1)) == EOF)
+	    if ((ch = getbyte(timeout, 0, 1)) == EOF)
 		break;
 	    *current++ = ch;
 	    illgotten = current;
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index 5f68e6db2..5fe5cd62d 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -427,7 +427,7 @@ enum ztmouttp {
      * there's no general way to fix up if that's wrong.
      */
     ZTM_MAX
-#define	ZMAXTIMEOUT	((time_t)1 << (sizeof(time_t)*8-11))
+#define	ZMAXTIMEOUT	((time_t)1 << (sizeof(int)*8-11))
 };
 
 struct ztmout {




Messages sorted by: Reverse Date, Date, Thread, Author