Initial commit of Pollcat library
This commit is contained in:
151
example/tty.c
Normal file
151
example/tty.c
Normal file
@@ -0,0 +1,151 @@
|
||||
/** Minimal terminal using pollcat - TTY side
|
||||
*
|
||||
* This file is part of the Pollcat Library.
|
||||
* Copyright (C) 2022 Expatria Technologies Inc.
|
||||
* Contact: Morgan Hughes <morgan@expatria.ca>
|
||||
*
|
||||
* The Pollcat Library is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the the GNU Lesser General Public License as published by the Free
|
||||
* Software Foundation; either version 3 of the License, or (at your option) any later
|
||||
* version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received copies of the GNU General Public License and the GNU Lesser
|
||||
* General Public License along with the Pollcat Library. If not, see
|
||||
* https://www.gnu.org/licenses/
|
||||
*
|
||||
* vim:ts=4:noexpandtab
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include <pollcat.h>
|
||||
|
||||
#include "terminal.h"
|
||||
|
||||
|
||||
static struct pollcat_timer timer = { 0 };
|
||||
static void callback (void *arg)
|
||||
{
|
||||
command_help();
|
||||
}
|
||||
|
||||
|
||||
static void service (struct pollcat *cat)
|
||||
{
|
||||
char buff[256];
|
||||
char *ptr;
|
||||
int ret;
|
||||
|
||||
if ( !(pollcat_revents(fileno(stdin)) & POLLIN) )
|
||||
return;
|
||||
|
||||
memset(buff, 0, sizeof(buff));
|
||||
if ( (ret = read(fileno(stdin), buff, sizeof(buff) - 1)) < 0 )
|
||||
{
|
||||
fprintf(stderr, "recv(%d): %s", ret, strerror(errno));
|
||||
pollcat_loop_exit();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( command_mode )
|
||||
{
|
||||
pollcat_timer_detach(&timer);
|
||||
command_recv(buff[0]);
|
||||
command_mode = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !(ptr = memchr(buff, command_char, ret)) )
|
||||
{
|
||||
serial_write(buff, ret);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ptr > buff )
|
||||
serial_write(buff, ptr - buff);
|
||||
|
||||
if ( (1 + ptr - buff) < ret )
|
||||
{
|
||||
pollcat_timer_detach(&timer);
|
||||
command_recv(ptr[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
pollcat_timer_attach(&timer, 1000, callback, NULL);
|
||||
command_mode = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct pollcat_ops ops =
|
||||
{
|
||||
.service = service,
|
||||
};
|
||||
|
||||
struct pollcat cat =
|
||||
{
|
||||
.ops = &ops,
|
||||
};
|
||||
|
||||
static int tty_flags;
|
||||
static struct termios tty_tio;
|
||||
|
||||
int tty_init (void)
|
||||
{
|
||||
char tty[256];
|
||||
memset(tty, 0, sizeof(tty));
|
||||
if ( readlink("/proc/self/fd/1", tty, sizeof(tty)) > 0 )
|
||||
{
|
||||
if ( !freopen(tty, "w", stdout) || !freopen(tty, "w", stderr) )
|
||||
perror(tty);
|
||||
setbuf(stderr, NULL);
|
||||
}
|
||||
|
||||
tty_flags = fcntl(fileno(stdin), F_GETFL);
|
||||
if ( tty_flags < 0 )
|
||||
return -1;
|
||||
|
||||
if ( fcntl(fileno(stdin), F_SETFL, tty_flags | O_NONBLOCK) < 0 )
|
||||
return -1;
|
||||
|
||||
if ( tcgetattr(fileno(stdin), &tty_tio) )
|
||||
return -1;
|
||||
|
||||
struct termios tio = tty_tio;
|
||||
cfmakeraw(&tio);
|
||||
if ( tcsetattr(fileno(stdin), TCSANOW, &tio) )
|
||||
return -1;
|
||||
|
||||
pollcat_fd_add(fileno(stdin), POLLIN);
|
||||
pollcat_iter_add(&cat);
|
||||
|
||||
command_char = '\01';
|
||||
command_mode = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tty_done (void)
|
||||
{
|
||||
pollcat_iter_remove(&cat);
|
||||
pollcat_fd_remove(fileno(stdin));
|
||||
|
||||
if ( fcntl(0, F_SETFL, tty_flags) < 0 )
|
||||
perror("fcntl");
|
||||
|
||||
if ( tcsetattr(0, TCSANOW, &tty_tio) )
|
||||
perror("tcsetattr");
|
||||
}
|
||||
|
||||
void tty_write (const void *buff, int len)
|
||||
{
|
||||
write(fileno(stdout), buff, len);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user