summaryrefslogtreecommitdiffstats
path: root/cpukit/libcsupport/src/termios.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2020-01-29 09:32:05 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2020-02-10 09:01:10 +0100
commit90f11edd012fc7032b5c985bad554b8559607832 (patch)
tree846ff20c545417c3462a362e2580ce4f1353b171 /cpukit/libcsupport/src/termios.c
parentconfig: Add CONFIGURE_DIRTY_MEMORY (diff)
downloadrtems-90f11edd012fc7032b5c985bad554b8559607832.tar.bz2
termios: Fix input canonical mode
Canonical input processing was broken by 667501a314ba75f80f1c13c6b43dd35d0a00efd1 as shown by test case termios09. Update #3800.
Diffstat (limited to '')
-rw-r--r--cpukit/libcsupport/src/termios.c83
1 files changed, 33 insertions, 50 deletions
diff --git a/cpukit/libcsupport/src/termios.c b/cpukit/libcsupport/src/termios.c
index fedaa80ba0..b10a4ad774 100644
--- a/cpukit/libcsupport/src/termios.c
+++ b/cpukit/libcsupport/src/termios.c
@@ -1337,23 +1337,16 @@ rtems_status_code rtems_termios_register_isig_handler(
/**
* @brief Type returned by all input processing (iproc) methods
- */
+ */
typedef enum {
/**
- * This indicates that the input character was processed
- * and the results were placed into the buffer.
- */
- RTEMS_TERMIOS_IPROC_IN_BUFFER,
- /**
- * This indicates that the input character was processed
- * and the result did not go into the buffer.
+ * This indicates that the input processing can continue.
*/
- RTEMS_TERMIOS_IPROC_WAS_PROCESSED,
+ RTEMS_TERMIOS_IPROC_CONTINUE,
/**
- * This indicates that the input character was not processed and
- * subsequent processing is required.
+ * This indicates that the input processing is done.
*/
- RTEMS_TERMIOS_IPROC_WAS_NOT_PROCESSED,
+ RTEMS_TERMIOS_IPROC_DONE,
/**
* This indicates that the character was processed and determined
* to be one that requires a signal to be raised (e.g. VINTR or
@@ -1361,7 +1354,7 @@ typedef enum {
* occur. There is no further processing of this character required and
* the pending read() operation should be interrupted.
*/
- RTEMS_TERMIOS_IPROC_INTERRUPT_READ
+ RTEMS_TERMIOS_IPROC_INTERRUPT
} rtems_termios_iproc_status_code;
/*
@@ -1379,12 +1372,10 @@ iproc (unsigned char c, struct rtems_termios_tty *tty)
rtems_termios_isig_status_code rc;
rc = (*termios_isig_handler)(c, tty);
if (rc == RTEMS_TERMIOS_ISIG_INTERRUPT_READ) {
- return RTEMS_TERMIOS_IPROC_INTERRUPT_READ;
- }
- if (rc == RTEMS_TERMIOS_ISIG_WAS_PROCESSED) {
- return RTEMS_TERMIOS_IPROC_IN_BUFFER;
+ return RTEMS_TERMIOS_IPROC_INTERRUPT;
}
- _Assert(rc == RTEMS_TERMIOS_ISIG_WAS_NOT_PROCESSED);
+
+ return RTEMS_TERMIOS_IPROC_CONTINUE;
}
}
@@ -1394,25 +1385,25 @@ iproc (unsigned char c, struct rtems_termios_tty *tty)
if ((c != '\0') && (tty->termios.c_lflag & ICANON)) {
if (c == tty->termios.c_cc[VERASE]) {
erase (tty, 0);
- return RTEMS_TERMIOS_IPROC_WAS_PROCESSED;
+ return RTEMS_TERMIOS_IPROC_CONTINUE;
}
else if (c == tty->termios.c_cc[VKILL]) {
erase (tty, 1);
- return RTEMS_TERMIOS_IPROC_WAS_PROCESSED;
+ return RTEMS_TERMIOS_IPROC_CONTINUE;
}
else if (c == tty->termios.c_cc[VEOF]) {
- return RTEMS_TERMIOS_IPROC_IN_BUFFER;
+ return RTEMS_TERMIOS_IPROC_DONE;
} else if (c == '\n') {
if (tty->termios.c_lflag & (ECHO | ECHONL))
echo (c, tty);
tty->cbuf[tty->ccount++] = c;
- return RTEMS_TERMIOS_IPROC_IN_BUFFER;
+ return RTEMS_TERMIOS_IPROC_DONE;
} else if ((c == tty->termios.c_cc[VEOL]) ||
(c == tty->termios.c_cc[VEOL2])) {
if (tty->termios.c_lflag & ECHO)
echo (c, tty);
tty->cbuf[tty->ccount++] = c;
- return RTEMS_TERMIOS_IPROC_IN_BUFFER;
+ return RTEMS_TERMIOS_IPROC_DONE;
}
}
@@ -1425,9 +1416,8 @@ iproc (unsigned char c, struct rtems_termios_tty *tty)
if (tty->termios.c_lflag & ECHO)
echo (c, tty);
tty->cbuf[tty->ccount++] = c;
- return RTEMS_TERMIOS_IPROC_IN_BUFFER;
}
- return RTEMS_TERMIOS_IPROC_WAS_NOT_PROCESSED;
+ return RTEMS_TERMIOS_IPROC_CONTINUE;
}
/*
@@ -1456,7 +1446,7 @@ static rtems_termios_iproc_status_code
siprocPoll (unsigned char c, rtems_termios_tty *tty)
{
if (c == '\r' && (tty->termios.c_iflag & IGNCR) != 0) {
- return RTEMS_TERMIOS_IPROC_WAS_NOT_PROCESSED;
+ return RTEMS_TERMIOS_IPROC_CONTINUE;
}
/*
@@ -1476,7 +1466,6 @@ fillBufferPoll (struct rtems_termios_tty *tty)
{
int n;
rtems_termios_iproc_status_code rc;
- rtems_termios_iproc_status_code retval = RTEMS_TERMIOS_IPROC_WAS_PROCESSED;
if (tty->termios.c_lflag & ICANON) {
for (;;) {
@@ -1485,12 +1474,8 @@ fillBufferPoll (struct rtems_termios_tty *tty)
rtems_task_wake_after (1);
} else {
rc = siprocPoll (n, tty);
- if (rc == RTEMS_TERMIOS_IPROC_IN_BUFFER) {
- break;
- }
- if (rc == RTEMS_TERMIOS_IPROC_INTERRUPT_READ) {
- retval = RTEMS_TERMIOS_IPROC_INTERRUPT_READ;
- break;
+ if (rc != RTEMS_TERMIOS_IPROC_CONTINUE) {
+ return rc;
}
}
}
@@ -1519,9 +1504,8 @@ fillBufferPoll (struct rtems_termios_tty *tty)
rtems_task_wake_after (1);
} else {
rc = siprocPoll (n, tty);
- if (rc == RTEMS_TERMIOS_IPROC_INTERRUPT_READ) {
- retval = RTEMS_TERMIOS_IPROC_INTERRUPT_READ;
- break;
+ if (rc != RTEMS_TERMIOS_IPROC_CONTINUE) {
+ return rc;
}
if (tty->ccount >= tty->termios.c_cc[VMIN])
break;
@@ -1530,7 +1514,7 @@ fillBufferPoll (struct rtems_termios_tty *tty)
}
}
}
- return retval;
+ return RTEMS_TERMIOS_IPROC_CONTINUE;
}
/*
@@ -1587,20 +1571,17 @@ fillBufferQueue (struct rtems_termios_tty *tty)
/* continue processing new character */
if (tty->termios.c_lflag & ICANON) {
rc = siproc (c, tty);
- /* If the read() should be interrupted, return */
- if (rc == RTEMS_TERMIOS_IPROC_INTERRUPT_READ) {
- return RTEMS_TERMIOS_IPROC_INTERRUPT_READ;
- }
- /* In canonical mode, input is made available line by line */
- if (rc == RTEMS_TERMIOS_IPROC_IN_BUFFER) {
- return RTEMS_TERMIOS_IPROC_IN_BUFFER;
+ if (rc != RTEMS_TERMIOS_IPROC_CONTINUE) {
+ return rc;
}
} else {
rc = siproc (c, tty);
- /* If the read() should be interrupted, return */
- if (rc == RTEMS_TERMIOS_IPROC_INTERRUPT_READ) {
- return RTEMS_TERMIOS_IPROC_INTERRUPT_READ;
+
+ /* in non-canonical mode only stop on interrupt */
+ if (rc == RTEMS_TERMIOS_IPROC_INTERRUPT) {
+ return rc;
}
+
if (tty->ccount >= tty->termios.c_cc[VMIN])
wait = false;
}
@@ -1635,7 +1616,7 @@ fillBufferQueue (struct rtems_termios_tty *tty)
}
}
}
- return RTEMS_TERMIOS_IPROC_WAS_PROCESSED;
+ return RTEMS_TERMIOS_IPROC_CONTINUE;
}
static rtems_status_code
@@ -1647,7 +1628,7 @@ rtems_termios_read_tty (
)
{
uint32_t count;
- rtems_termios_iproc_status_code rc = RTEMS_TERMIOS_IPROC_WAS_PROCESSED;
+ rtems_termios_iproc_status_code rc;
count = initial_count;
@@ -1658,6 +1639,8 @@ rtems_termios_read_tty (
rc = fillBufferPoll (tty);
else
rc = fillBufferQueue (tty);
+ } else {
+ rc = RTEMS_TERMIOS_IPROC_CONTINUE;
}
/*
@@ -1675,7 +1658,7 @@ rtems_termios_read_tty (
* was interrupted. The isig handler can do nothing, have POSIX behavior
* and cause a signal, or a user defined action.
*/
- if (rc == RTEMS_TERMIOS_IPROC_INTERRUPT_READ) {
+ if (rc == RTEMS_TERMIOS_IPROC_INTERRUPT) {
return RTEMS_INTERRUPTED;
}