diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-02-21 15:26:31 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-02-28 10:54:50 +0100 |
commit | 045ff6e11cf21454c6216a1099b44a6fe692586f (patch) | |
tree | c23d93b2e49eb4805a4efdb0c9032a2f06f5916e /testsuite | |
parent | 631fb983aa2e5731973c4b4df677cb59e0bf6606 (diff) |
Add poll() and select() support for Termios
Diffstat (limited to 'testsuite')
-rw-r--r-- | testsuite/netshell01/test_main.c | 121 |
1 files changed, 119 insertions, 2 deletions
diff --git a/testsuite/netshell01/test_main.c b/testsuite/netshell01/test_main.c index 36eeea79..1b68971d 100644 --- a/testsuite/netshell01/test_main.c +++ b/testsuite/netshell01/test_main.c @@ -29,17 +29,132 @@ * that the target is alive after initializing the TCP/IP stack. */ -#include <stdio.h> +#include <assert.h> +#include <errno.h> #include <stdarg.h> +#include <stdbool.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> -#include <errno.h> #include <rtems/shell.h> #define TEST_NAME "LIBBSD NETSHELL 1" static void +change_serial_settings(int fd, const struct termios *current, bool icanon) +{ + struct termios term = *current; + + term.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | + ICRNL | IXON); + term.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL | ECHOPRT | ECHOCTL | + ECHOKE | ICANON | ISIG | IEXTEN); + term.c_cflag &= ~(CSIZE | PARENB); + term.c_cflag |= CS8; + term.c_oflag &= ~(OPOST | ONLRET | ONLCR | OCRNL | ONLRET | TABDLY | + OLCUC); + + term.c_cc[VMIN] = 0; + term.c_cc[VTIME] = 10; + + if (icanon) { + term.c_iflag |= ICRNL; + term.c_lflag |= ICANON; + } + + tcsetattr(fd, TCSANOW, &term); +} + +static void +do_read_select(int fd) +{ + int nfds = fd + 1; + struct fd_set read_set; + struct timeval timeout = { + .tv_sec = 10, + .tv_usec = 0 + }; + int rv; + + FD_ZERO(&read_set); + FD_SET(fd, &read_set); + + rv = select(nfds, &read_set, NULL, NULL, &timeout); + if (rv == 0) { + printf("timeout\n"); + } else if (rv > 0) { + if (FD_ISSET(fd, &read_set)) { + char buf[512]; + ssize_t n = read(fd, buf, sizeof(buf)); + printf("read returned %zi\n", n); + } + } else { + perror("select failed"); + } +} + +static void +do_write_select(int fd) +{ + int nfds = fd + 1; + struct fd_set write_set; + struct timeval to = { + .tv_sec = 0, + .tv_usec = 1 + }; + struct timeval *timeout = &to; + char buf[512]; + int rv; + size_t i; + + memset(buf, 'a', sizeof(buf)); + + for (i = 0; i < sizeof(buf); i += 24) { + buf[i] = '\r'; + buf[i + 1] = '\n'; + } + + for (i = 0; i < 10; ++i) { + write(fd, buf, sizeof(buf)); + + FD_ZERO(&write_set); + FD_SET(fd, &write_set); + rv = select(nfds, NULL, &write_set, NULL, timeout); + if (rv == 0) { + printf("timeout\n"); + } else { + printf("write set: %i\n", FD_ISSET(fd, &write_set)); + } + + timeout = NULL; + } +} + +static int +termiosselect_command(int argc, char *argv[]) +{ + bool icanon = argc > 1 && strcmp(argv[1], "icanon") == 0; + int fd = STDIN_FILENO; + struct termios term; + int rv = tcgetattr(fd, &term); + assert(rv == 0); + + change_serial_settings(fd, &term, icanon); + do_read_select(fd); + do_write_select(STDOUT_FILENO); + tcsetattr(fd, TCSANOW, &term); + return (0); +} + +rtems_shell_cmd_t rtems_shell_ARP_Command = { + .name = "termiosselect", + .usage = "termiosselect [icanon]", + .topic = "net", + .command = termiosselect_command +}; + +static void test_main(void) { rtems_shell_env_t env; @@ -50,4 +165,6 @@ test_main(void) exit(0); } +#define RTEMS_BSD_CONFIG_TERMIOS_KQUEUE_AND_POLL + #include <rtems/bsd/test/default-init.h> |