diff options
Diffstat (limited to 'Src')
-rw-r--r-- | Src/Zle/zle_keymap.c | 2 | ||||
-rw-r--r-- | Src/Zle/zle_main.c | 47 | ||||
-rw-r--r-- | Src/Zle/zle_misc.c | 2 | ||||
-rw-r--r-- | Src/Zle/zle_vi.c | 2 | ||||
-rw-r--r-- | Src/builtin.c | 6 | ||||
-rw-r--r-- | Src/init.c | 2 |
6 files changed, 45 insertions, 16 deletions
diff --git a/Src/Zle/zle_keymap.c b/Src/Zle/zle_keymap.c index 6f4e062fc..376805549 100644 --- a/Src/Zle/zle_keymap.c +++ b/Src/Zle/zle_keymap.c @@ -1341,7 +1341,7 @@ getkeymapcmd(Keymap km, Thingy *funcp, char **strp) static int getkeybuf(int w) { - int c = getbyte(w); + int c = getbyte(w, NULL); if(c < 0) return EOF; diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c index 2522f67fd..4f598b889 100644 --- a/Src/Zle/zle_main.c +++ b/Src/Zle/zle_main.c @@ -628,13 +628,16 @@ raw_getbyte(int keytmout, char *cptr) /**/ mod_export int -getbyte(int keytmout) +getbyte(int keytmout, int *timeout) { char cc; unsigned int ret; int die = 0, r, icnt = 0; int old_errno = errno, obreaks = breaks; + if (timeout) + *timeout = 0; + #ifdef ZLE_UNICODE_SUPPORT /* * Reading a single byte always invalidates the status @@ -660,8 +663,12 @@ getbyte(int keytmout) dont_queue_signals(); r = raw_getbyte(keytmout, &cc); restore_queue_signals(q); - if (r == -2) /* timeout */ + if (r == -2) { + /* timeout */ + if (timeout) + *timeout = 1; return lastchar = EOF; + } if (r == 1) break; if (r == 0) { @@ -733,7 +740,7 @@ getbyte(int keytmout) mod_export ZLE_INT_T getfullchar(int keytmout) { - int inchar = getbyte(keytmout); + int inchar = getbyte(keytmout, NULL); #ifdef ZLE_UNICODE_SUPPORT return getrestchar(inchar); @@ -759,7 +766,7 @@ getrestchar(int inchar) /* char cnull = '\0'; */ char c = inchar; wchar_t outchar; - int ret; + int ret, timeout; static mbstate_t ps; /* @@ -769,8 +776,11 @@ getrestchar(int inchar) */ lastchar_wide_valid = 1; - if (inchar == EOF) + if (inchar == EOF) { + /* End of input, so reset the shift state. */ + memset(&ps, 0, sizeof(ps)); return lastchar_wide = WEOF; + } /* * Return may be zero if we have a NULL; handle this like @@ -781,15 +791,34 @@ getrestchar(int inchar) /* * Invalid input. Hmm, what's the right thing to do here? */ + memset(&ps, 0, sizeof(ps)); return lastchar_wide = WEOF; } - /* No timeout here as we really need the character. */ - inchar = getbyte(0); + /* + * Always apply KEYTIMEOUT to the remains of the input + * character. The parts of a multibyte character should + * arrive together. If we don't do this the input can + * get stuck if an invalid byte sequence arrives. + */ + inchar = getbyte(1, &timeout); /* getbyte deliberately resets lastchar_wide_valid */ lastchar_wide_valid = 1; - if (inchar == EOF) - return lastchar_wide = WEOF; + if (inchar == EOF) { + memset(&ps, 0, sizeof(ps)); + if (timeout) + { + /* + * This case means that we got a valid initial byte + * (since we tested for EOF above), but the followup + * timed out. This probably indicates a duff character. + * Return a '?'. + */ + lastchar_wide = L'?'; + } + else + return lastchar_wide = WEOF; + } c = inchar; } return lastchar_wide = (ZLE_INT_T)outchar; diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c index 6b79f431c..05a780b0c 100644 --- a/Src/Zle/zle_misc.c +++ b/Src/Zle/zle_misc.c @@ -595,7 +595,7 @@ universalargument(char **args) * * Hence for now this remains byte-by-byte. */ - while ((gotk = getbyte(0)) != EOF) { + while ((gotk = getbyte(0, NULL)) != EOF) { if (gotk == '-' && !digcnt) { minus = -1; digcnt++; diff --git a/Src/Zle/zle_vi.c b/Src/Zle/zle_vi.c index a83f0197e..cb072cdb6 100644 --- a/Src/Zle/zle_vi.c +++ b/Src/Zle/zle_vi.c @@ -108,7 +108,7 @@ vigetkey(void) char m[3], *str; Thingy cmd; - if(getbyte(0) == EOF) + if (getbyte(0, NULL) == EOF) return ZLEEOF; m[0] = lastchar; diff --git a/Src/builtin.c b/Src/builtin.c index 2df342533..f9ba4af3e 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -4539,7 +4539,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) do { if (izle) { - if ((val = getkeyptr(0)) < 0) + if ((val = getkeyptr(0, NULL)) < 0) break; *bptr++ = (char) val; nchars--; @@ -4595,7 +4595,7 @@ bin_read(char *name, char **args, Options ops, UNUSED(int func)) /* get, and store, reply */ if (izle) { - int key = getkeyptr(0); + int key = getkeyptr(0, NULL); readbuf[0] = (key == 'y' ? 'y' : 'n'); } else { @@ -4818,7 +4818,7 @@ zread(int izle, int *readchar) int ret; if (izle) { - int c = getkeyptr(0); + int c = getkeyptr(0, NULL); return (c < 0 ? EOF : c); } diff --git a/Src/init.c b/Src/init.c index cd20c2237..6d78e5a1a 100644 --- a/Src/init.c +++ b/Src/init.c @@ -82,7 +82,7 @@ mod_export int hasam, hasxn; /* Pointer to read-key function from zle */ /**/ -mod_export int (*getkeyptr) _((int)); +mod_export int (*getkeyptr) _((int, int *)); /* SIGCHLD mask */ |