mirror of
https://github.com/apache/nuttx-apps.git
synced 2025-10-19 11:23:07 +08:00
apps/graphics/pdcurs34/nuttx and system/termcurses: This commit fixes two issues:
1. A memory corruption issue that occurs from a paste operation that would overflow the fixed buffer size for keyboard processing. 2. A stall in getch() processing when there are cached keycodes in the termcurses emulation (tcurses_vt100.c).
This commit is contained in:
@@ -167,12 +167,20 @@ bool PDC_check_key(void)
|
|||||||
fd_set rfds;
|
fd_set rfds;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
|
||||||
|
/* Test the registered tcurs interface for cached characters */
|
||||||
|
|
||||||
|
ret = termcurses_checkkey(termstate->tcurs);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Watch stdin (fd 0) to see when it has input. */
|
/* Watch stdin (fd 0) to see when it has input. */
|
||||||
|
|
||||||
FD_ZERO(&rfds);
|
FD_ZERO(&rfds);
|
||||||
FD_SET(termstate->in_fd, &rfds);
|
FD_SET(termstate->in_fd, &rfds);
|
||||||
|
|
||||||
/* Wait up to five seconds. */
|
/* Do not wait. */
|
||||||
|
|
||||||
tv.tv_sec = 0;
|
tv.tv_sec = 0;
|
||||||
tv.tv_usec = 0;
|
tv.tv_usec = 0;
|
||||||
|
@@ -117,6 +117,10 @@ struct termcurses_ops_s
|
|||||||
/* Get a keycode value */
|
/* Get a keycode value */
|
||||||
|
|
||||||
CODE int (*getkeycode)(FAR struct termcurses_s *dev, int *specialkey, int *keymodifers);
|
CODE int (*getkeycode)(FAR struct termcurses_s *dev, int *specialkey, int *keymodifers);
|
||||||
|
|
||||||
|
/* Check for cached keycode value */
|
||||||
|
|
||||||
|
CODE bool (*checkkey)(FAR struct termcurses_s *dev);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct termcurses_dev_s
|
struct termcurses_dev_s
|
||||||
@@ -229,6 +233,16 @@ int termcurses_getwinsize(FAR struct termcurses_s *term, FAR struct winsize *win
|
|||||||
int termcurses_getkeycode(FAR struct termcurses_s *term, FAR int *specialkey,
|
int termcurses_getkeycode(FAR struct termcurses_s *term, FAR int *specialkey,
|
||||||
FAR int *keymodifiers);
|
FAR int *keymodifiers);
|
||||||
|
|
||||||
|
/************************************************************************************
|
||||||
|
* Name: termcurses_checkkey
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Check if there is a key waiting to be processed.
|
||||||
|
*
|
||||||
|
************************************************************************************/
|
||||||
|
|
||||||
|
bool termcurses_checkkey(FAR struct termcurses_s *term);
|
||||||
|
|
||||||
#undef EXTERN
|
#undef EXTERN
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@@ -107,6 +107,7 @@ static int tcurses_vt100_setattributes(FAR struct termcurses_s *dev,
|
|||||||
unsigned long attrib);
|
unsigned long attrib);
|
||||||
static int tcurses_vt100_getkeycode(FAR struct termcurses_s *dev,
|
static int tcurses_vt100_getkeycode(FAR struct termcurses_s *dev,
|
||||||
FAR int *specialkey, FAR int *keymodifers);
|
FAR int *specialkey, FAR int *keymodifers);
|
||||||
|
static bool tcurses_vt100_checkkey(FAR struct termcurses_s *dev);
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Private Data
|
* Private Data
|
||||||
@@ -120,7 +121,8 @@ static const struct termcurses_ops_s g_vt100_ops =
|
|||||||
tcurses_vt100_getwinsize,
|
tcurses_vt100_getwinsize,
|
||||||
tcurses_vt100_setcolors,
|
tcurses_vt100_setcolors,
|
||||||
tcurses_vt100_setattributes,
|
tcurses_vt100_setattributes,
|
||||||
tcurses_vt100_getkeycode
|
tcurses_vt100_getkeycode,
|
||||||
|
tcurses_vt100_checkkey
|
||||||
};
|
};
|
||||||
|
|
||||||
/* VT100 terminal codes */
|
/* VT100 terminal codes */
|
||||||
@@ -831,7 +833,7 @@ static int tcurses_vt100_getkeycode(FAR struct termcurses_s *dev, FAR int *speci
|
|||||||
{
|
{
|
||||||
/* Get next bytes from input stream */
|
/* Get next bytes from input stream */
|
||||||
|
|
||||||
priv->keycount = read(fd, priv->keybuf, sizeof(priv->keybuf));
|
priv->keycount = read(fd, priv->keybuf, sizeof(priv->keybuf)-1);
|
||||||
if (priv->keycount <= 0)
|
if (priv->keycount <= 0)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1047,6 +1049,48 @@ static int tcurses_vt100_getkeycode(FAR struct termcurses_s *dev, FAR int *speci
|
|||||||
return keycode;
|
return keycode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/************************************************************************************
|
||||||
|
* Check if a key is cached for processing.
|
||||||
|
*
|
||||||
|
************************************************************************************/
|
||||||
|
|
||||||
|
static bool tcurses_vt100_checkkey(FAR struct termcurses_s *dev)
|
||||||
|
{
|
||||||
|
FAR struct tcurses_vt100_s *priv;
|
||||||
|
int ret;
|
||||||
|
int fd;
|
||||||
|
fd_set rfds;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
priv = (FAR struct tcurses_vt100_s *) dev;
|
||||||
|
fd = priv->in_fd;
|
||||||
|
|
||||||
|
/* Test for queued characters */
|
||||||
|
|
||||||
|
if (priv->keycount > 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Watch stdin (fd 0) to see when it has input. */
|
||||||
|
|
||||||
|
FD_ZERO(&rfds);
|
||||||
|
FD_SET(fd, &rfds);
|
||||||
|
|
||||||
|
/* Wait up to 1000us for next character after ESC */
|
||||||
|
|
||||||
|
tv.tv_sec = 0;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
|
ret = select(1, &rfds, NULL, NULL, &tv);
|
||||||
|
if (ret > 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Public Functions
|
* Public Functions
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
@@ -272,3 +272,25 @@ int termcurses_getkeycode(FAR struct termcurses_s *term, FAR int *specialkey,
|
|||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/************************************************************************************
|
||||||
|
* Name: termcurses_checkkey
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Check if there is a key waiting to be processed.
|
||||||
|
*
|
||||||
|
************************************************************************************/
|
||||||
|
|
||||||
|
bool termcurses_checkkey(FAR struct termcurses_s *term)
|
||||||
|
{
|
||||||
|
FAR struct termcurses_dev_s *dev = (FAR struct termcurses_dev_s *) term;
|
||||||
|
|
||||||
|
/* Call the dev function */
|
||||||
|
|
||||||
|
if (dev->ops->checkkey)
|
||||||
|
{
|
||||||
|
return dev->ops->checkkey(term);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user