diff --git a/src/Makefile.am b/src/Makefile.am index 71da405..55c719c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,4 +1,4 @@ bin_PROGRAMS = gotty -gotty_SOURCES = tty.c options.c device.c main.c +gotty_SOURCES = tty.c options.c main.c bashcompletiondir=$(sysconfdir)/bash_completion.d dist_bashcompletion_DATA=bash-completion/gotty diff --git a/src/device.c b/src/device.c deleted file mode 100644 index 948aa03..0000000 --- a/src/device.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Go TTY - The Really Simple Terminal Application - * - * Copyright (c) 2014 Martin Lund - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * 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 a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include "gotty/options.h" -#include "gotty/print.h" -#include "gotty/tty.h" - -void wait_for_device(void) -{ - int ready, n; - struct stat status; - fd_set rdfs; - struct timeval tv; - char c, c0=0, c1=0; - - /* Loop until device pops up */ - while (true) - { - /* Wait up to 1 seconds */ - tv.tv_sec = 1; - tv.tv_usec = 0; - - FD_ZERO(&rdfs); - FD_SET(STDIN_FILENO, &rdfs); - - /* Block until input becomes available or timeout */ - ready = select(STDIN_FILENO + 1, &rdfs, NULL, NULL, &tv); - if (ready) - { - /* Input from stdin ready */ - - /* Read one character */ - n = read(STDIN_FILENO, &c, 1); - - /* Exit upon ctrl-g ctrl-q sequence */ - c1 = c0; - c0 = c; - if ((c0 == CTRLQ) && (c1 == CTRLG)) - exit(EXIT_SUCCESS); - } else - { - /* Timeout */ - - /* Test for device file */ - if (stat(option.device, &status) == 0) - return; - } - } -} diff --git a/src/include/gotty/device.h b/src/include/gotty/device.h deleted file mode 100644 index 91e8bd5..0000000 --- a/src/include/gotty/device.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Go TTY - The Really Simple Terminal Application - * - * Copyright (c) 2014 Martin Lund - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * 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 a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#ifndef DEVICE_H -#define DEVICE_H - -void wait_for_device(void); - -#endif diff --git a/src/main.c b/src/main.c index 86f7e08..1f72925 100644 --- a/src/main.c +++ b/src/main.c @@ -22,7 +22,6 @@ #include #include "gotty/options.h" #include "gotty/tty.h" -#include "gotty/device.h" int main(int argc, char *argv[]) { @@ -44,7 +43,7 @@ int main(int argc, char *argv[]) { while (true) { - wait_for_device(); + wait_for_tty_device(); status = connect_tty(); } } diff --git a/src/tty.c b/src/tty.c index e1b9643..4b2a2e8 100644 --- a/src/tty.c +++ b/src/tty.c @@ -39,7 +39,50 @@ static int connected = false; struct termios stdio, old_stdio, old_tio; static int fd; -static char c; +static bool tainted = false; + +void wait_for_tty_device(void) +{ + int ready, n; + struct stat status; + fd_set rdfs; + struct timeval tv; + char c_stdin[3]; + + /* Loop until device pops up */ + while (true) + { + /* Wait up to 1 seconds */ + tv.tv_sec = 1; + tv.tv_usec = 0; + + FD_ZERO(&rdfs); + FD_SET(STDIN_FILENO, &rdfs); + + /* Block until input becomes available or timeout */ + ready = select(STDIN_FILENO + 1, &rdfs, NULL, NULL, &tv); + if (ready) + { + /* Input from stdin ready */ + + /* Read one character */ + n = read(STDIN_FILENO, &c_stdin[0], 1); + + /* Exit upon ctrl-g ctrl-q sequence */ + c_stdin[2] = c_stdin[1]; + c_stdin[1] = c_stdin[0]; + if ((c_stdin[1] == CTRLQ) && (c_stdin[2] == CTRLG)) + exit(EXIT_SUCCESS); + } else + { + /* Timeout */ + + /* Test for device file */ + if (stat(option.device, &status) == 0) + return; + } + } +} void configure_stdout(void) { @@ -75,26 +118,32 @@ void restore_stdout(void) tcsetattr(STDOUT_FILENO, TCSAFLUSH, &old_stdio); } +void disconnect_tty(void) +{ + if (tainted) + putchar('\n'); + color_printf("[gotty] Disconnected"); + close(fd); + connected = false; +} + void restore_tty(void) { tcsetattr(fd, TCSANOW, &old_tio); tcsetattr(fd, TCSAFLUSH, &old_tio); if (connected) - { - if (c == 0) - putchar('\n'); - color_printf("[gotty] Disconnected"); - } + disconnect_tty(); } int connect_tty(void) { fd_set rdfs; /* Read file descriptor set */ int maxfd; /* Maximum file desciptor used */ - char c0 = 0, c1 = 0; static bool first = true; int status; + char c_tty; + char c_stdin[3]; /* Open tty device */ fd = open(option.device, O_RDWR | O_NOCTTY ); @@ -113,7 +162,9 @@ int connect_tty(void) color_printf("[gotty] Connected"); connected = true; - c = 0; + tainted = false; + bzero(&c_stdin[0], 3); + c_tty = 0; /* Save current port settings */ if (tcgetattr(fd, &old_tio) < 0) @@ -153,41 +204,35 @@ int connect_tty(void) if (FD_ISSET(fd, &rdfs)) { /* Input from tty device ready */ - if (read(fd, &c, 1) > 0) + if (read(fd, &c_tty, 1) > 0) { /* Print received tty character to stdout */ - putchar(c); + putchar(c_tty); fflush(stdout); + if (c_tty != 0x7) // Small trick to avoid ctrl-g echo + tainted = true; } else { /* Error reading - device is likely unplugged */ - if (!option.no_autoconnect) - { - if (c != 0) - putchar('\n'); - color_printf("[gotty] Disconnected"); - } - close(fd); - connected = false; + disconnect_tty(); return EXIT_FAILURE; } } if (FD_ISSET(STDIN_FILENO, &rdfs)) { /* Input from stdin ready */ - status = read(STDIN_FILENO, &c, 1); + status = read(STDIN_FILENO, &c_stdin[0], 1); + if ((c_stdin[0] != CTRLQ) && (c_stdin[0] != CTRLG)) + tainted = true; /* Exit upon ctrl-g ctrl-q sequence */ - c1 = c0; - c0 = c; - if ((c0 == CTRLQ) && (c1 == CTRLG)) - { - close(fd); + c_stdin[2] = c_stdin[1]; + c_stdin[1] = c_stdin[0]; + if ((c_stdin[1] == CTRLQ) && (c_stdin[2] == CTRLG)) exit(EXIT_SUCCESS); - } /* Forward input to tty device */ - status = write(fd, &c, 1); + status = write(fd, &c_stdin[0], 1); } }