mirror of
https://github.com/apache/nuttx-apps.git
synced 2026-08-24 23:18:23 +00:00
system/readline: add caller-selectable control handling
Let CPython handle Ctrl-D and signals without changing existing NSH behavior. Signed-off-by: raiden00pl <raiden00@railab.me> Assisted-by: Claude Code
This commit is contained in:
parent
0923948d80
commit
9545e12054
4 changed files with 60 additions and 8 deletions
|
|
@ -42,6 +42,11 @@
|
|||
# undef CONFIG_READLINE_TABCOMPLETION
|
||||
#endif
|
||||
|
||||
/* readline_fd_ex() options */
|
||||
|
||||
#define READLINE_CTRL_D_EOF (1 << 0)
|
||||
#define READLINE_RETURN_ON_EINTR (1 << 1)
|
||||
|
||||
/* Make sure that the are valid values for all tab-completion settings */
|
||||
|
||||
#ifdef CONFIG_READLINE_TABCOMPLETION
|
||||
|
|
@ -176,6 +181,19 @@ FAR const struct extmatch_vtable_s *
|
|||
|
||||
ssize_t readline_fd(FAR char *buf, int buflen, int infd, int outfd);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: readline_fd_ex
|
||||
*
|
||||
* readline_fd_ex() extends readline_fd() with caller-selected options.
|
||||
* READLINE_CTRL_D_EOF makes Ctrl-D return EOF when the line is empty.
|
||||
* READLINE_RETURN_ON_EINTR makes an interrupted input read return -EINTR
|
||||
* instead of being retried.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
ssize_t readline_fd_ex(FAR char *buf, int buflen, int infd, int outfd,
|
||||
unsigned int options);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: readline_stream
|
||||
*
|
||||
|
|
|
|||
|
|
@ -84,6 +84,6 @@ struct rl_common_s
|
|||
****************************************************************************/
|
||||
|
||||
ssize_t readline_common(FAR struct rl_common_s *vtbl,
|
||||
FAR char *buf, int buflen);
|
||||
FAR char *buf, int buflen, unsigned int options);
|
||||
|
||||
#endif /* __APPS_SYSTEM_READLINE_READLINE_H */
|
||||
|
|
|
|||
|
|
@ -49,12 +49,13 @@
|
|||
# define RL_CMDHIST_LINELEN CONFIG_READLINE_CMD_HISTORY_LINELEN
|
||||
#endif
|
||||
|
||||
#define CTRL_D 4 /* ^D - EOF or delete at cursor */
|
||||
|
||||
#ifdef CONFIG_READLINE_EDIT_EMACS
|
||||
/* Emacs-style control key codes */
|
||||
/* Additional Emacs-style control key codes */
|
||||
|
||||
# define CTRL_A 1 /* ^A - Home */
|
||||
# define CTRL_B 2 /* ^B - Left */
|
||||
# define CTRL_D 4 /* ^D - Delete at cursor */
|
||||
# define CTRL_E 5 /* ^E - End */
|
||||
# define CTRL_F 6 /* ^F - Right */
|
||||
# define CTRL_K 11 /* ^K - Kill to end of line */
|
||||
|
|
@ -849,7 +850,7 @@ FAR const struct extmatch_vtable_s *
|
|||
****************************************************************************/
|
||||
|
||||
ssize_t readline_common(FAR struct rl_common_s *vtbl, FAR char *buf,
|
||||
int buflen)
|
||||
int buflen, unsigned int options)
|
||||
{
|
||||
int escape;
|
||||
int nch;
|
||||
|
|
@ -1440,6 +1441,14 @@ ssize_t readline_common(FAR struct rl_common_s *vtbl, FAR char *buf,
|
|||
return submit_line(buf, nch);
|
||||
}
|
||||
|
||||
/* Some callers use the conventional empty-line Ctrl-D as EOF. */
|
||||
|
||||
else if (ch == CTRL_D && (options & READLINE_CTRL_D_EOF) != 0 &&
|
||||
nch == 0)
|
||||
{
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* Emacs-style control keys */
|
||||
|
||||
#ifdef CONFIG_READLINE_EDIT_EMACS
|
||||
|
|
|
|||
|
|
@ -43,9 +43,11 @@
|
|||
struct readline_s
|
||||
{
|
||||
struct rl_common_s vtbl;
|
||||
int infd;
|
||||
unsigned int options;
|
||||
int infd;
|
||||
int errcode;
|
||||
#ifdef CONFIG_READLINE_ECHO
|
||||
int outfd;
|
||||
int outfd;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
@ -93,7 +95,13 @@ static int readline_getc(FAR struct rl_common_s *vtbl)
|
|||
*/
|
||||
|
||||
int errcode = errno;
|
||||
if (errcode != EINTR)
|
||||
if (errcode == EINTR &&
|
||||
(priv->options & READLINE_RETURN_ON_EINTR) != 0)
|
||||
{
|
||||
priv->errcode = errcode;
|
||||
return EOF;
|
||||
}
|
||||
else if (errcode != EINTR)
|
||||
{
|
||||
/* Return EOF on any errors that we cannot handle */
|
||||
|
||||
|
|
@ -219,6 +227,16 @@ static void readline_write(FAR struct rl_common_s *vtbl,
|
|||
****************************************************************************/
|
||||
|
||||
ssize_t readline_fd(FAR char *buf, int buflen, int infd, int outfd)
|
||||
{
|
||||
return readline_fd_ex(buf, buflen, infd, outfd, 0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: readline_fd_ex
|
||||
****************************************************************************/
|
||||
|
||||
ssize_t readline_fd_ex(FAR char *buf, int buflen, int infd, int outfd,
|
||||
unsigned int options)
|
||||
{
|
||||
UNUSED(outfd);
|
||||
|
||||
|
|
@ -244,6 +262,8 @@ ssize_t readline_fd(FAR char *buf, int buflen, int infd, int outfd)
|
|||
|
||||
vtbl.vtbl.rl_getc = readline_getc;
|
||||
vtbl.infd = infd;
|
||||
vtbl.options = options;
|
||||
vtbl.errcode = 0;
|
||||
|
||||
#ifdef CONFIG_READLINE_ECHO
|
||||
vtbl.vtbl.rl_putc = readline_putc;
|
||||
|
|
@ -253,12 +273,17 @@ ssize_t readline_fd(FAR char *buf, int buflen, int infd, int outfd)
|
|||
|
||||
/* The let the common readline logic do the work */
|
||||
|
||||
ret = readline_common(&vtbl.vtbl, buf, buflen);
|
||||
ret = readline_common(&vtbl.vtbl, buf, buflen, options);
|
||||
|
||||
if (restore_termios)
|
||||
{
|
||||
tcsetattr(infd, TCSANOW, &cfg);
|
||||
}
|
||||
|
||||
if (vtbl.errcode != 0)
|
||||
{
|
||||
ret = -vtbl.errcode;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue