#include <errno.h>
#include <time.h>
#include <dirent.h>
+#include <pthread.h>
#include "config.h"
#include "configfile.h"
#include "tty.h"
#define KEY_B 0x62
#define KEY_C 0x63
#define KEY_E 0x65
+#define KEY_F 0x66
+#define KEY_SHIFT_F 0x46
#define KEY_G 0x67
#define KEY_H 0x68
#define KEY_L 0x6C
static char tty_buffer[BUFSIZ*2];
static size_t tty_buffer_count = 0;
static char *tty_buffer_write_ptr = tty_buffer;
+static pthread_t thread;
+static int pipefd[2];
+static pthread_mutex_t mutex_input_ready = PTHREAD_MUTEX_INITIALIZER;
static void optional_local_echo(char c)
{
return bytes_written;
}
+void *tty_stdin_input_thread(void *arg)
+{
+ UNUSED(arg);
+ char input_buffer[BUFSIZ];
+ ssize_t byte_count;
+ ssize_t bytes_written;
+
+ // Create FIFO pipe
+ if (pipe(pipefd) == -1)
+ {
+ tio_error_printf("Failed to create pipe");
+ exit(EXIT_FAILURE);
+ }
+
+ // Signal that input pipe is ready
+ pthread_mutex_unlock(&mutex_input_ready);
+
+ // Input loop for stdin
+ while (1)
+ {
+ /* Input from stdin ready */
+ byte_count = read(STDIN_FILENO, input_buffer, BUFSIZ);
+ if (byte_count < 0)
+ {
+ tio_warning_printf("Could not read from stdin (%s)", strerror(errno));
+ }
+ else if (byte_count == 0)
+ {
+ // Close write end to signal EOF in read end
+ close(pipefd[1]);
+ pthread_exit(0);
+ }
+
+ if (interactive_mode)
+ {
+ static char previous_char = 0;
+ char input_char;
+
+ // Process quit and flush key command
+ for (int i = 0; i<byte_count; i++)
+ {
+ input_char = input_buffer[i];
+
+ if (previous_char == option.prefix_code)
+ {
+ switch (input_char)
+ {
+ case KEY_Q:
+ exit(EXIT_FAILURE);
+ break;
+ case KEY_SHIFT_F:
+ tio_printf("Flushed data I/O channels")
+ tcflush(fd, TCIOFLUSH);
+ break;
+ default:
+ break;
+ }
+ }
+ previous_char = input_char;
+ }
+ }
+
+ // Write all bytes read to pipe
+ while (byte_count)
+ {
+ bytes_written = write(pipefd[1], input_buffer, byte_count);
+ if (bytes_written < 0)
+ {
+ tio_warning_printf("Could not write to pipe (%s)", strerror(errno));
+ break;
+ }
+ byte_count -= bytes_written;
+ }
+ }
+
+ pthread_exit(0);
+}
+
+void tty_input_thread_create(void)
+{
+ pthread_mutex_lock(&mutex_input_ready);
+
+ if (pthread_create(&thread, NULL, tty_stdin_input_thread, NULL) != 0) {
+ tio_error_printf("pthread_create() error");
+ exit(1);
+ }
+}
+
+void tty_input_thread_wait_ready(void)
+{
+ pthread_mutex_lock(&mutex_input_ready);
+}
+
static void output_hex(char c)
{
hex_chars[hex_char_index++] = c;
}
}
-void handle_command_sequence(char input_char, char previous_char, char *output_char, bool *forward)
+void handle_command_sequence(char input_char, char *output_char, bool *forward)
{
char unused_char;
bool unused_bool;
int state;
static enum line_mode_t line_mode = LINE_OFF;
+ static char previous_char = 0;
/* Ignore unused arguments */
if (output_char == NULL)
/* Do not forward input char to output by default */
*forward = false;
+ /* Handle special double prefix key input case */
+ if (input_char == option.prefix_code)
+ {
+ /* Forward prefix character to tty */
+ *output_char = option.prefix_code;
+ *forward = true;
+ previous_char = 0;
+ return;
+ }
+
switch (input_char)
{
case KEY_QUESTION:
tio_printf(" ctrl-%c b Send break", option.prefix_key);
tio_printf(" ctrl-%c c Show configuration", option.prefix_key);
tio_printf(" ctrl-%c e Toggle local echo mode", option.prefix_key);
+ tio_printf(" ctrl-%c f Toggle log to file", option.prefix_key);
+ tio_printf(" ctrl-%c F Flush data I/O buffers", option.prefix_key);
tio_printf(" ctrl-%c g Toggle serial port line", option.prefix_key);
tio_printf(" ctrl-%c h Toggle hexadecimal mode", option.prefix_key);
tio_printf(" ctrl-%c l Clear screen", option.prefix_key);
tio_printf(" RI : %s", (state & TIOCM_RI) ? "HIGH" : "LOW");
break;
+ case KEY_F:
+ if (option.log)
+ {
+ log_close();
+ option.log = false;
+ }
+ else
+ {
+ if (log_open(option.log_filename) == 0)
+ {
+ option.log = true;
+ }
+ }
+ tio_printf("Switched log to file %s", option.log ? "on" : "off");
+ break;
+
+ case KEY_SHIFT_F:
+ break;
+
case KEY_G:
tio_printf("Please enter which serial line number to toggle:");
tio_printf(" DTR (0)");
break;
default:
- /* Handle double prefix key input case */
- if (input_char == option.prefix_code)
- {
- static int count = 0;
- if (count++ == 1)
- {
- // Do not forward prefix characters excessively
- count = 0;
- break;
- }
-
- /* Forward prefix character to tty */
- *output_char = option.prefix_code;
- *forward = true;
- break;
- }
-
/* Ignore unknown ctrl-t escaped keys */
break;
}
}
+
+ previous_char = input_char;
}
void stdin_restore(void)
int status;
int maxfd;
struct timeval tv;
- static char input_char, previous_char = 0;
+ static char input_char;
static bool first = true;
static int last_errno = 0;
}
FD_ZERO(&rdfs);
- FD_SET(STDIN_FILENO, &rdfs);
- maxfd = MAX(STDIN_FILENO, socket_add_fds(&rdfs, false));
+ FD_SET(pipefd[0], &rdfs);
+ maxfd = MAX(pipefd[0], socket_add_fds(&rdfs, false));
/* Block until input becomes available or timeout */
status = select(maxfd + 1, &rdfs, NULL, NULL, &tv);
if (status > 0)
{
- if (FD_ISSET(STDIN_FILENO, &rdfs))
+ if (FD_ISSET(pipefd[0], &rdfs))
{
/* Input from stdin ready */
/* Read one character */
- status = read(STDIN_FILENO, &input_char, 1);
+ status = read(pipefd[0], &input_char, 1);
if (status <= 0)
{
tio_error_printf("Could not read from stdin");
}
/* Handle commands */
- handle_command_sequence(input_char, previous_char, NULL, NULL);
-
- previous_char = input_char;
+ handle_command_sequence(input_char, NULL, NULL);
}
socket_handle_input(&rdfs, NULL);
}
int maxfd; /* Maximum file descriptor used */
char input_char, output_char;
char input_buffer[BUFSIZ];
- static char previous_char = 0;
static bool first = true;
int status;
bool next_timestamp = false;
FD_SET(fd, &rdfs);
if (!ignore_stdin)
{
- FD_SET(STDIN_FILENO, &rdfs);
+ FD_SET(pipefd[0], &rdfs);
}
- maxfd = MAX(fd, STDIN_FILENO);
+ maxfd = MAX(fd, pipefd[0]);
maxfd = MAX(maxfd, socket_add_fds(&rdfs, true));
/* Manage timeout */
}
}
}
- else if (FD_ISSET(STDIN_FILENO, &rdfs))
+ else if (FD_ISSET(pipefd[0], &rdfs))
{
/* Input from stdin ready */
- ssize_t bytes_read = read(STDIN_FILENO, input_buffer, BUFSIZ);
+ ssize_t bytes_read = read(pipefd[0], input_buffer, BUFSIZ);
if (bytes_read < 0)
{
tio_error_printf_silent("Could not read from stdin (%s)", strerror(errno));
}
/* Handle commands */
- handle_command_sequence(input_char, previous_char, &output_char, &forward);
-
- /* Save previous key */
- previous_char = input_char;
+ handle_command_sequence(input_char, &output_char, &forward);
if ((option.hex_mode) && (forward))
{
}
else
{
+ /* Input from socket ready */
forward = socket_handle_input(&rdfs, &output_char);
if (forward)