commit a548d383b230b02d1ca0fc44acc384a32d82abac Author: Steffen Daode Nurpmeso Date: 2012-09-10 15:39:00 +0200 Add a new EL_READRESTART option for editline(3) Which makes it possible to realize read(2) restarts after EINTR errors without actually going the expensive (and sometimes impossible) way through signal handling. Unfortunately editline(3) doesn't offer anything like "el_gets_continue()", which could be used to simply restart the last editing session at the point where it ended, and it seems much harder to add that functionality (also in respect to merging in between *BSD versions) than to add this flag. diff --git a/lib/libedit/editline.3 b/lib/libedit/editline.3 index 1f26b39..7bb783e 100644 --- a/lib/libedit/editline.3 +++ b/lib/libedit/editline.3 @@ -388,6 +388,22 @@ check this (using .Fn el_get ) to determine if editing should be enabled or not. +.It Dv EL_READRESTART , Fa "int flag" +If +.Fa flag +is zero (the default), +then +.Fn el_getc +and +.Fn el_gets +will not treat +.Dv EINTR +errors any special and automatically restart reading characters. +Note this may be restricted to the builtin character read function +.Dv EL_BUILTIN_GETCFN +(see +.Dv EL_GETCFN +below). .It Dv EL_UNBUFFERED , Fa "int flag" If .Fa flag @@ -498,6 +514,9 @@ Retrieve previously registered with the corresponding .Fn el_set call. +.It Dv EL_READRESTART , Fa "int" +Return non-zero if reading of characters is restarted after signal +interruption. .It Dv EL_UNBUFFERED , Fa "int" Return non-zero if unbuffered mode is enabled. .It Dv EL_PREP_TERM , Fa "int" diff --git a/lib/libedit/el.c b/lib/libedit/el.c index d6cfb2d..4be765f 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_READRESTART: + if (va_arg(ap, int)) + el->el_flags |= READRESTART; + else + el->el_flags &= ~READRESTART; + 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_READRESTART: + *va_arg(ap, int *) = (el->el_flags & READRESTART) != 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..d1321cc 100644 --- a/lib/libedit/el.h +++ b/lib/libedit/el.h @@ -54,7 +54,8 @@ #define HANDLE_SIGNALS 0x01 #define NO_TTY 0x02 #define EDIT_DISABLED 0x04 -#define UNBUFFERED 0x08 +#define READRESTART 0x08 +#define UNBUFFERED 0x10 typedef int bool_t; /* True or not */ diff --git a/lib/libedit/histedit.h b/lib/libedit/histedit.h index 8a6caf9..13d0cbf 100644 --- a/lib/libedit/histedit.h +++ b/lib/libedit/histedit.h @@ -130,15 +130,16 @@ unsigned char _el_fn_sh_complete(EditLine *, int); #define EL_RPROMPT 12 /* , el_pfunc_t); */ #define EL_GETCFN 13 /* , el_rfunc_t); */ #define EL_CLIENTDATA 14 /* , void *); */ -#define EL_UNBUFFERED 15 /* , int); */ -#define EL_PREP_TERM 16 /* , int); */ -#define EL_GETTC 17 /* , const char *, ..., NULL); */ -#define EL_GETFP 18 /* , int, FILE **); */ -#define EL_SETFP 19 /* , int, FILE *); */ -#define EL_REFRESH 20 /* , void); set */ -#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_READRESTART 15 /* , int); */ +#define EL_UNBUFFERED 16 /* , int); */ +#define EL_PREP_TERM 17 /* , int); */ +#define EL_GETTC 18 /* , const char *, ..., NULL); */ +#define EL_GETFP 19 /* , int, FILE **); */ +#define EL_SETFP 20 /* , int, FILE *); */ +#define EL_REFRESH 21 /* , void); set */ +#define EL_PROMPT_ESC 22 /* , prompt_func, Char); set/get */ +#define EL_RPROMPT_ESC 23 /* , prompt_func, Char); set/get */ +#define EL_RESIZE 24 /* , el_zfunc_t, void *); set */ #define EL_BUILTIN_GETCFN (NULL) diff --git a/lib/libedit/read.c b/lib/libedit/read.c index ecd1ee2..3634d7e 100644 --- a/lib/libedit/read.c +++ b/lib/libedit/read.c @@ -300,6 +300,8 @@ read_char(EditLine *el, char *cp) el_set(el, EL_REFRESH); goto again; } + if (e == EINTR && (el->el_flags & READRESTART)) + goto again; if (!tried && read__fixio(el->el_infd, e) == 0) tried = 1; else {