mirror of
https://github.com/tio/tio.git
synced 2026-05-01 14:57:59 +02:00
Improved error handling
Fixes a memory leak and avoids aggressive busy looping when problems accessing tty device.
This commit is contained in:
parent
4c59995db8
commit
ece9e7f918
5 changed files with 132 additions and 26 deletions
|
|
@ -4,11 +4,13 @@ tio_SOURCES = tty.c \
|
|||
time.c \
|
||||
main.c \
|
||||
log.c \
|
||||
error.c \
|
||||
include/tio/tty.h \
|
||||
include/tio/options.h \
|
||||
include/tio/time.h \
|
||||
include/tio/print.h \
|
||||
include/tio/log.h
|
||||
include/tio/log.h \
|
||||
include/tio/error.h
|
||||
|
||||
if ENABLE_BASH_COMPLETION
|
||||
bashcompletiondir=@BASH_COMPLETION_DIR@
|
||||
|
|
|
|||
35
src/error.c
Normal file
35
src/error.c
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* tio - the simple TTY terminal I/O application
|
||||
*
|
||||
* Copyright (c) 2014-2016 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "tio/options.h"
|
||||
#include "tio/print.h"
|
||||
|
||||
char *error = "";
|
||||
|
||||
void error_exit(void)
|
||||
{
|
||||
if ((error[0] != 0) && (option.no_autoconnect))
|
||||
printf("Error: %s\n", error);
|
||||
}
|
||||
32
src/include/tio/error.h
Normal file
32
src/include/tio/error.h
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* tio - the simple TTY terminal I/O application
|
||||
*
|
||||
* Copyright (c) 2014-2016 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 ERROR_H
|
||||
#define ERROR_H
|
||||
|
||||
#define TIO_SUCCESS 0
|
||||
#define TIO_ERROR 1
|
||||
|
||||
extern char *error;
|
||||
|
||||
void error_exit(void);
|
||||
|
||||
#endif
|
||||
|
|
@ -21,9 +21,12 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include "tio/options.h"
|
||||
#include "tio/tty.h"
|
||||
#include "tio/log.h"
|
||||
#include "tio/error.h"
|
||||
#include "tio/print.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
|
@ -35,6 +38,9 @@ int main(int argc, char *argv[])
|
|||
/* Configure output terminal */
|
||||
configure_stdout();
|
||||
|
||||
/* Install error exit handler */
|
||||
atexit(&error_exit);
|
||||
|
||||
/* Install log exit handler */
|
||||
atexit(&log_exit);
|
||||
|
||||
|
|
|
|||
59
src/tty.c
59
src/tty.c
|
|
@ -36,6 +36,7 @@
|
|||
#include "tio/options.h"
|
||||
#include "tio/time.h"
|
||||
#include "tio/log.h"
|
||||
#include "tio/error.h"
|
||||
|
||||
static int connected = false;
|
||||
struct termios new_stdout, old_stdout, old_tio;
|
||||
|
|
@ -44,22 +45,27 @@ static bool tainted = false;
|
|||
|
||||
void wait_for_tty_device(void)
|
||||
{
|
||||
int ready, n;
|
||||
struct stat status;
|
||||
fd_set rdfs;
|
||||
int ready, status;
|
||||
struct timeval tv;
|
||||
char c_stdin[3];
|
||||
static char c_stdin[3];
|
||||
static bool first = true;
|
||||
|
||||
/* Loop until device pops up */
|
||||
while (true)
|
||||
{
|
||||
/* Test for accessible device file */
|
||||
if (access(option.tty_device, R_OK) == 0)
|
||||
return;
|
||||
|
||||
if (first)
|
||||
{
|
||||
/* Don't wait first time */
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 1;
|
||||
first = false;
|
||||
} else
|
||||
{
|
||||
/* Wait up to 1 second */
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
}
|
||||
|
||||
FD_ZERO(&rdfs);
|
||||
FD_SET(STDIN_FILENO, &rdfs);
|
||||
|
|
@ -71,7 +77,9 @@ void wait_for_tty_device(void)
|
|||
/* Input from stdin ready */
|
||||
|
||||
/* Read one character */
|
||||
n = read(STDIN_FILENO, &c_stdin[0], 1);
|
||||
status = read(STDIN_FILENO, &c_stdin[0], 1);
|
||||
if (status < 0)
|
||||
printf("Warning: Could not read from stdin\n");
|
||||
|
||||
/* Exit upon ctrl-t + q sequence */
|
||||
c_stdin[2] = c_stdin[1];
|
||||
|
|
@ -79,6 +87,10 @@ void wait_for_tty_device(void)
|
|||
if ((c_stdin[1] == KEY_Q) && (c_stdin[2] == KEY_CTRL_T))
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
/* Test for accessible device file */
|
||||
if (access(option.tty_device, R_OK) == 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -139,18 +151,24 @@ int connect_tty(void)
|
|||
fd_set rdfs; /* Read file descriptor set */
|
||||
int maxfd; /* Maximum file descriptor used */
|
||||
static bool first = true;
|
||||
int status;
|
||||
char c_tty;
|
||||
char c_stdin[3];
|
||||
int status;
|
||||
|
||||
/* Open tty device */
|
||||
fd = open(option.tty_device, O_RDWR | O_NOCTTY );
|
||||
if (fd < 0)
|
||||
return EXIT_FAILURE;
|
||||
{
|
||||
error = strerror(errno);
|
||||
goto error_open;
|
||||
}
|
||||
|
||||
/* Make sure device is of tty type */
|
||||
if (!isatty(fd))
|
||||
return EXIT_FAILURE;
|
||||
{
|
||||
error = "Not a tty device";
|
||||
goto error_isatty;
|
||||
}
|
||||
|
||||
/* Flush stale I/O data (if any) */
|
||||
tcflush(fd, TCIOFLUSH);
|
||||
|
|
@ -164,7 +182,7 @@ int connect_tty(void)
|
|||
|
||||
/* Save current port settings */
|
||||
if (tcgetattr(fd, &old_tio) < 0)
|
||||
return EXIT_FAILURE;
|
||||
goto error_tcgetattr;
|
||||
|
||||
/* Make sure we restore tty settings on exit */
|
||||
if (first)
|
||||
|
|
@ -216,13 +234,16 @@ int connect_tty(void)
|
|||
{
|
||||
/* Error reading - device is likely unplugged */
|
||||
disconnect_tty();
|
||||
return EXIT_FAILURE;
|
||||
goto error_reading;
|
||||
}
|
||||
}
|
||||
if (FD_ISSET(STDIN_FILENO, &rdfs))
|
||||
{
|
||||
/* Input from stdin ready */
|
||||
status = read(STDIN_FILENO, &c_stdin[0], 1);
|
||||
if (status < 0)
|
||||
printf("Warning: Could not read from stdin");
|
||||
|
||||
if ((c_stdin[0] != KEY_Q) && (c_stdin[0] != KEY_CTRL_T))
|
||||
tainted = true;
|
||||
|
||||
|
|
@ -234,6 +255,8 @@ int connect_tty(void)
|
|||
|
||||
/* Forward input to tty device */
|
||||
status = write(fd, &c_stdin[0], 1);
|
||||
if (status < 0)
|
||||
printf("Warning: Could not write to tty device");
|
||||
|
||||
/* Write to log */
|
||||
if (option.log)
|
||||
|
|
@ -245,5 +268,13 @@ int connect_tty(void)
|
|||
}
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
return TIO_SUCCESS;
|
||||
|
||||
error_tcgetattr:
|
||||
error_isatty:
|
||||
close(fd);
|
||||
connected = false;
|
||||
error_reading:
|
||||
error_open:
|
||||
return TIO_ERROR;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue