mirror of
https://git.rtems.org/rtems-libbsd/
synced 2025-10-15 05:43:33 +08:00
Add poll() and select() support for Termios
This commit is contained in:
@@ -29,16 +29,131 @@
|
||||
* 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)
|
||||
{
|
||||
@@ -50,4 +165,6 @@ test_main(void)
|
||||
exit(0);
|
||||
}
|
||||
|
||||
#define RTEMS_BSD_CONFIG_TERMIOS_KQUEUE_AND_POLL
|
||||
|
||||
#include <rtems/bsd/test/default-init.h>
|
||||
|
Reference in New Issue
Block a user