From eb154cc49285ead7852e4e50358d48bb90cda9df Mon Sep 17 00:00:00 2001 Message-Id: In-Reply-To: References: From: "Steffen \"Daode\" Nurpmeso" Date: Tue, 11 Sep 2012 15:39:47 +0200 Subject: [PATCH 2/3] Add an EL_RESTART_READ option to editline(3) Make it possible to realize read(2) restarts after EINTR errors without actually going the expensive (and sometimes impossible or at least undesirable) way through signal handling. --- lib/libedit/editline.3 | 20 ++++++++++++++++++++ lib/libedit/el.c | 12 ++++++++++++ lib/libedit/el.h | 1 + lib/libedit/histedit.h | 1 + lib/libedit/read.c | 2 ++ 5 files changed, 36 insertions(+), 0 deletions(-) diff --git a/lib/libedit/editline.3 b/lib/libedit/editline.3 index fe58321..6ecbac8 100644 --- a/lib/libedit/editline.3 +++ b/lib/libedit/editline.3 @@ -385,6 +385,22 @@ check this (using .Fn el_get ) to determine if editing should be enabled or not. +.It Dv EL_RESTART_READ , Fa "int flag" +If +.Fa flag +is not zero (as per default), +then +.Fn el_getc +and +.Fn el_gets +will restart character reads that failed with +.Dv EINTR +errors. +Note this may be restricted to the builtin character read function +.Dv EL_BUILTIN_GETCFN +(see +.Dv EL_GETCFN +below). .It Dv EL_GETCFN , Fa "int (*f)(EditLine *, char *c)" Define the character reading function as .Fa f , @@ -486,6 +502,10 @@ Retrieve previously registered with the corresponding .Fn el_set call. +.It Dv EL_RESTART_READ , Fa "int" +Return non-zero if reading of characters is automatically restarted for +.Dv EINTR +errors. .It Dv EL_UNBUFFERED , Fa "int" Sets or clears unbuffered mode. In this mode, diff --git a/lib/libedit/el.c b/lib/libedit/el.c index d6cfb2d..8418f46 100644 --- a/lib/libedit/el.c +++ b/lib/libedit/el.c @@ -274,6 +274,13 @@ el_set(EditLine *el, int op, ...) el->el_data = va_arg(ap, void *); break; + case EL_RESTART_READ: + if (va_arg(ap, int)) + el->el_flags |= RESTART_READ; + else + el->el_flags &= ~RESTART_READ; + break; + case EL_UNBUFFERED: rv = va_arg(ap, int); if (rv && !(el->el_flags & UNBUFFERED)) { @@ -435,6 +442,11 @@ el_get(EditLine *el, int op, ...) rv = 0; break; + case EL_RESTART_READ: + *va_arg(ap, int *) = ((el->el_flags & RESTART_READ) != 0); + rv = 0; + break; + case EL_UNBUFFERED: *va_arg(ap, int *) = (!(el->el_flags & UNBUFFERED)); rv = 0; diff --git a/lib/libedit/el.h b/lib/libedit/el.h index 67d01ff..e296ff6 100644 --- a/lib/libedit/el.h +++ b/lib/libedit/el.h @@ -55,6 +55,7 @@ #define NO_TTY 0x02 #define EDIT_DISABLED 0x04 #define UNBUFFERED 0x08 +#define RESTART_READ 0x100 typedef int bool_t; /* True or not */ diff --git a/lib/libedit/histedit.h b/lib/libedit/histedit.h index 8a6caf9..5f457f8 100644 --- a/lib/libedit/histedit.h +++ b/lib/libedit/histedit.h @@ -139,6 +139,7 @@ unsigned char _el_fn_sh_complete(EditLine *, int); #define EL_PROMPT_ESC 21 /* , prompt_func, Char); set/get */ #define EL_RPROMPT_ESC 22 /* , prompt_func, Char); set/get */ #define EL_RESIZE 23 /* , el_zfunc_t, void *); set */ +#define EL_RESTART_READ 24 /* , int); set/get */ #define EL_BUILTIN_GETCFN (NULL) diff --git a/lib/libedit/read.c b/lib/libedit/read.c index 0880b5c..4c5996c 100644 --- a/lib/libedit/read.c +++ b/lib/libedit/read.c @@ -304,6 +304,8 @@ read_char(EditLine *el, char *cp) el_set(el, EL_REFRESH); goto again; } + if (e == EINTR && (el->el_flags & RESTART_READ)) + goto again; if (!tried && read__fixio(el->el_infd, e) == 0) tried = 1; else { -- 1.7.9.rc2.1.g69204