mirror of
https://github.com/tio/tio.git
synced 2026-05-01 14:57:59 +02:00
Initial import
This commit is contained in:
commit
a14d14d75b
19 changed files with 1604 additions and 0 deletions
2
src/Makefile.am
Normal file
2
src/Makefile.am
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
bin_PROGRAMS = gotty
|
||||
gotty_SOURCES = tty.c options.c device.c main.c
|
||||
38
src/device.c
Normal file
38
src/device.c
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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 <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include "gotty/options.h"
|
||||
|
||||
void wait_for_device(void)
|
||||
{
|
||||
struct stat status;
|
||||
|
||||
/* Loop until device pops up */
|
||||
while (true)
|
||||
{
|
||||
sleep(1);
|
||||
if (stat(option.device, &status) == 0)
|
||||
return;
|
||||
}
|
||||
}
|
||||
27
src/include/gotty/device.h
Normal file
27
src/include/gotty/device.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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
|
||||
41
src/include/gotty/options.h
Normal file
41
src/include/gotty/options.h
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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 OPTIONS_H
|
||||
#define OPTIONS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <limits.h>
|
||||
#include <termios.h>
|
||||
|
||||
/* Options */
|
||||
struct option_t
|
||||
{
|
||||
char device[256];
|
||||
bool no_autoconnect;
|
||||
struct termios tio;
|
||||
};
|
||||
|
||||
extern struct option_t option;
|
||||
|
||||
void parse_options(int argc, char *argv[]);
|
||||
|
||||
#endif
|
||||
49
src/include/gotty/print.h
Normal file
49
src/include/gotty/print.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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 PRINT_H
|
||||
#define PRINT_H
|
||||
|
||||
#define ANSI_COLOR_GRAY "\x1b[1;30m"
|
||||
#define ANSI_COLOR_RED "\x1b[1;31m"
|
||||
#define ANSI_COLOR_GREEN "\x1b[1;32m"
|
||||
#define ANSI_COLOR_YELLOW "\x1b[1;33m"
|
||||
#define ANSI_COLOR_BLUE "\x1b[1;34m"
|
||||
#define ANSI_COLOR_PINK "\x1b[1;35m"
|
||||
#define ANSI_COLOR_CYAN "\x1b[1;36m"
|
||||
#define ANSI_COLOR_WHITE "\x1b[1;37m"
|
||||
#define ANSI_COLOR_RESET "\x1b[0m"
|
||||
|
||||
#define gotty_printf(format, args...) \
|
||||
fprintf (stdout, "\n\033[300D" ANSI_COLOR_YELLOW "[gotty] " format ANSI_COLOR_RESET "\033[300D\n", ## args); \
|
||||
fflush(stdout);
|
||||
|
||||
#ifdef DEBUG
|
||||
#define debug_printf(format, args...) \
|
||||
fprintf (stdout, "[debug] " format, ## args)
|
||||
#define debug_printf_raw(format, args...) \
|
||||
fprintf (stdout, "" format, ## args)
|
||||
#else
|
||||
#define debug_printf(format, args...)
|
||||
#define debug_printf_raw(format, args...)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
28
src/include/gotty/tty.h
Normal file
28
src/include/gotty/tty.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* 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 TTY_H
|
||||
#define TTY_H
|
||||
|
||||
void configure_stdout(void);
|
||||
int connect_tty(void);
|
||||
|
||||
#endif
|
||||
50
src/main.c
Normal file
50
src/main.c
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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 <stdio.h>
|
||||
#include "gotty/options.h"
|
||||
#include "gotty/tty.h"
|
||||
#include "gotty/device.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int status;
|
||||
|
||||
/* Parse options */
|
||||
parse_options(argc, argv);
|
||||
|
||||
/* Configure output terminal */
|
||||
configure_stdout();
|
||||
|
||||
/* Connect to tty device */
|
||||
if (option.no_autoconnect)
|
||||
status = connect_tty();
|
||||
else
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
wait_for_device();
|
||||
status = connect_tty();
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
344
src/options.c
Normal file
344
src/options.c
Normal file
|
|
@ -0,0 +1,344 @@
|
|||
/*
|
||||
* 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 <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <termios.h>
|
||||
#include "config.h"
|
||||
#include "gotty/options.h"
|
||||
#include "gotty/print.h"
|
||||
|
||||
struct option_t option =
|
||||
{
|
||||
"", /* Device name */
|
||||
false, /* No autoconnect */
|
||||
};
|
||||
|
||||
void print_options_help(char *argv[])
|
||||
{
|
||||
printf("Usage: %s [<options>] <device>\n", argv[0]);
|
||||
printf("\n");
|
||||
printf("Options:\n");
|
||||
printf(" -b, --baudrate <baudrate> Baud rate (default: 115200)\n");
|
||||
printf(" -d, --databits 5|6|7|8 Data bits (default: 8)\n");
|
||||
printf(" -f, --flow hard|soft|none Flow control (default: none)\n");
|
||||
printf(" -s, --stopbits 1|2 Stop bits (default: 1)\n");
|
||||
printf(" -p, --parity even|odd|none Parity (default: none)\n");
|
||||
printf(" -n, --no-autoconnect Disable automatic connect\n");
|
||||
printf(" -v, --version Display version\n");
|
||||
printf(" -h, --help Display help\n");
|
||||
printf("\n");
|
||||
printf("In session, press ctrl-g + ctrl-q to quit.\n");
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void parse_options(int argc, char *argv[])
|
||||
{
|
||||
int c;
|
||||
int baudrate;
|
||||
int databits;
|
||||
int stopbits;
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
print_options_help(argv);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Set default termios settings:
|
||||
* (115200 baud, 8 data bits, no flow control, 1 stop bit, no parity) */
|
||||
bzero(&option.tio, sizeof(option.tio));
|
||||
option.tio.c_cflag = B115200 | CS8;
|
||||
|
||||
while (1)
|
||||
{
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"baudrate", required_argument, 0, 'b'},
|
||||
{"databits", required_argument, 0, 'd'},
|
||||
{"flow", required_argument, 0, 'f'},
|
||||
{"stopbits", required_argument, 0, 's'},
|
||||
{"parity", required_argument, 0, 'p'},
|
||||
{"no-autoconnect", no_argument, 0, 'n'},
|
||||
{"version", no_argument, 0, 'v'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
/* getopt_long stores the option index here */
|
||||
int option_index = 0;
|
||||
|
||||
/* Parse argument using getopt_long */
|
||||
c = getopt_long(argc, argv, "b:d:f:s:p:nvh", long_options, &option_index);
|
||||
|
||||
/* Detect the end of the options */
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 0:
|
||||
/* If this option sets a flag, do nothing else now */
|
||||
if (long_options[option_index].flag != 0)
|
||||
break;
|
||||
printf("option %s", long_options[option_index].name);
|
||||
if (optarg)
|
||||
printf(" with arg %s", optarg);
|
||||
printf("\n");
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
baudrate = atoi(optarg);
|
||||
switch (baudrate)
|
||||
{
|
||||
case 0:
|
||||
baudrate = B0;
|
||||
break;
|
||||
case 50:
|
||||
baudrate = B50;
|
||||
break;
|
||||
case 75:
|
||||
baudrate = B75;
|
||||
break;
|
||||
case 110:
|
||||
baudrate = B110;
|
||||
break;
|
||||
case 134:
|
||||
baudrate = B134;
|
||||
break;
|
||||
case 150:
|
||||
baudrate = B150;
|
||||
break;
|
||||
case 300:
|
||||
baudrate = B300;
|
||||
break;
|
||||
case 600:
|
||||
baudrate = B600;
|
||||
break;
|
||||
case 1200:
|
||||
baudrate = B1200;
|
||||
break;
|
||||
case 2400:
|
||||
baudrate = B2400;
|
||||
break;
|
||||
case 4800:
|
||||
baudrate = B4800;
|
||||
break;
|
||||
case 9600:
|
||||
baudrate = B9600;
|
||||
break;
|
||||
case 19200:
|
||||
baudrate = B19200;
|
||||
break;
|
||||
case 38400:
|
||||
baudrate = B38400;
|
||||
break;
|
||||
case 57600:
|
||||
baudrate = B57600;
|
||||
break;
|
||||
case 115200:
|
||||
baudrate = B115200;
|
||||
break;
|
||||
case 230400:
|
||||
baudrate = B230400;
|
||||
break;
|
||||
case 460800:
|
||||
baudrate = B460800;
|
||||
break;
|
||||
case 500000:
|
||||
baudrate = B500000;
|
||||
break;
|
||||
case 576000:
|
||||
baudrate = B576000;
|
||||
break;
|
||||
case 921600:
|
||||
baudrate = B921600;
|
||||
break;
|
||||
case 1000000:
|
||||
baudrate = B1000000;
|
||||
break;
|
||||
case 1152000:
|
||||
baudrate = B1152000;
|
||||
break;
|
||||
case 1500000:
|
||||
baudrate = B1500000;
|
||||
break;
|
||||
case 2000000:
|
||||
baudrate = B2000000;
|
||||
break;
|
||||
case 2500000:
|
||||
baudrate = B2500000;
|
||||
break;
|
||||
case 3000000:
|
||||
baudrate = B3000000;
|
||||
break;
|
||||
case 3500000:
|
||||
baudrate = B3500000;
|
||||
break;
|
||||
case 4000000:
|
||||
baudrate = B4000000;
|
||||
break;
|
||||
default:
|
||||
printf("Error: Invalid baud rate.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
cfsetispeed(&option.tio, baudrate);
|
||||
cfsetospeed(&option.tio, baudrate);
|
||||
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
databits = atoi(optarg);
|
||||
option.tio.c_cflag &= ~CSIZE;
|
||||
switch (databits)
|
||||
{
|
||||
case 5:
|
||||
option.tio.c_cflag |= CS5;
|
||||
break;
|
||||
case 6:
|
||||
option.tio.c_cflag |= CS6;
|
||||
break;
|
||||
case 7:
|
||||
option.tio.c_cflag |= CS7;
|
||||
break;
|
||||
case 8:
|
||||
option.tio.c_cflag |= CS8;
|
||||
break;
|
||||
default:
|
||||
printf("Error: Invalid data bits.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
if (strcmp("hard", optarg) == 0)
|
||||
{
|
||||
option.tio.c_cflag |= CRTSCTS;
|
||||
option.tio.c_iflag &= ~(IXON | IXOFF | IXANY);
|
||||
}
|
||||
else if (strcmp("soft", optarg) == 0)
|
||||
{
|
||||
option.tio.c_cflag &= ~CRTSCTS;
|
||||
option.tio.c_iflag |= IXON | IXOFF;
|
||||
}
|
||||
else if (strcmp("none", optarg) == 0)
|
||||
{
|
||||
option.tio.c_cflag &= ~CRTSCTS;
|
||||
option.tio.c_iflag &= ~(IXON | IXOFF | IXANY);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Error: Invalid flow control.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
|
||||
case 's':
|
||||
stopbits = atoi(optarg);
|
||||
switch (stopbits)
|
||||
{
|
||||
case 1:
|
||||
option.tio.c_cflag &= ~CSTOPB;
|
||||
break;
|
||||
case 2:
|
||||
option.tio.c_cflag |= CSTOPB;
|
||||
break;
|
||||
default:
|
||||
printf("Error: Invalid stop bits.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
if (strcmp("odd", optarg) == 0)
|
||||
{
|
||||
option.tio.c_cflag |= PARENB;
|
||||
option.tio.c_cflag |= PARODD;
|
||||
}
|
||||
else if (strcmp("even", optarg) == 0)
|
||||
{
|
||||
option.tio.c_cflag |= PARENB;
|
||||
option.tio.c_cflag &= ~PARODD;
|
||||
}
|
||||
else if (strcmp("none", optarg) == 0)
|
||||
option.tio.c_cflag &= ~PARENB;
|
||||
else
|
||||
{
|
||||
printf("Error: Invalid parity.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
option.no_autoconnect = true;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
printf("Go TTY v%s\n", VERSION);
|
||||
printf("Copyright (c) 2014 Martin Lund\n");
|
||||
printf("\n");
|
||||
printf("License GPLv2: GNU GPL version 2 or later <http://gnu.org/licenses/gpl-2.0.html>.\n");
|
||||
printf("This is free software: you are free to change and redistribute it.\n");
|
||||
printf("There is NO WARRANTY, to the extent permitted by law.\n");
|
||||
exit(0);
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
print_options_help(argv);
|
||||
exit(0);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
/* getopt_long already printed an error message */
|
||||
exit(1);
|
||||
break;
|
||||
|
||||
default:
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Assume first non-option is the tty device name */
|
||||
if (optind < argc)
|
||||
strcpy(option.device, argv[optind++]);
|
||||
|
||||
if (strlen(option.device) == 0)
|
||||
{
|
||||
printf("Error: Missing device name.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Print any remaining command line arguments (unknown options) */
|
||||
if (optind < argc)
|
||||
{
|
||||
printf("%s: unknown arguments: ", argv[0]);
|
||||
while (optind < argc)
|
||||
printf("%s ", argv[optind++]);
|
||||
printf("\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
181
src/tty.c
Normal file
181
src/tty.c
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
/*
|
||||
* 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 <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <stdbool.h>
|
||||
#include "gotty/tty.h"
|
||||
#include "gotty/print.h"
|
||||
#include "gotty/options.h"
|
||||
|
||||
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
|
||||
|
||||
#define CTRLG 0x07
|
||||
#define CTRLQ 0x11
|
||||
|
||||
static int fd;
|
||||
struct termios stdio, old_stdio, old_tio;
|
||||
|
||||
void configure_stdout(void)
|
||||
{
|
||||
/* Save current stdout settings */
|
||||
if (tcgetattr(STDOUT_FILENO, &old_stdio) < 0)
|
||||
{
|
||||
printf("Error: Saving current stdio settings failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Prepare stdio settings */
|
||||
bzero(&stdio, sizeof(stdio));
|
||||
|
||||
/* Control, input, output, local modes for stdio */
|
||||
stdio.c_cflag = 0;
|
||||
stdio.c_iflag = 0;
|
||||
stdio.c_oflag = 0;
|
||||
stdio.c_lflag = 0;
|
||||
|
||||
/* Control characters */
|
||||
stdio.c_cc[VTIME] = 0; /* Inter-character timer unused */
|
||||
stdio.c_cc[VMIN] = 1; /* Blocking read until 1 character received */
|
||||
|
||||
/* Activate stdio settings */
|
||||
tcsetattr(STDOUT_FILENO, TCSANOW, &stdio);
|
||||
tcsetattr(STDOUT_FILENO, TCSAFLUSH, &stdio);
|
||||
}
|
||||
|
||||
void restore(void)
|
||||
{
|
||||
static int i=0;
|
||||
|
||||
tcflush(STDOUT_FILENO, TCIOFLUSH);
|
||||
tcsetattr(STDOUT_FILENO, TCSANOW, &old_stdio);
|
||||
tcsetattr(STDOUT_FILENO, TCSAFLUSH, &old_stdio);
|
||||
|
||||
tcsetattr(fd, TCSANOW, &old_tio);
|
||||
tcsetattr(fd, TCSAFLUSH, &old_tio);
|
||||
|
||||
gotty_printf("Disconnected\n");
|
||||
}
|
||||
|
||||
int connect_tty(void)
|
||||
{
|
||||
int console = 0;
|
||||
fd_set rdfs; /* Read file descriptor set */
|
||||
int maxfd; /* Maximum file desciptor used */
|
||||
char c, c0 = 0, c1 = 0;
|
||||
static bool first = true;
|
||||
int status;
|
||||
|
||||
/* Open tty device */
|
||||
fd = open(option.device, O_RDWR | O_NOCTTY );
|
||||
if (fd <0)
|
||||
{
|
||||
perror(option.device);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Make sure device is of tty type */
|
||||
if (!isatty(fd))
|
||||
{
|
||||
printf("Error: Not a tty device");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
gotty_printf("Connected");
|
||||
|
||||
/* Save current port settings */
|
||||
if (tcgetattr(fd, &old_tio) < 0)
|
||||
{
|
||||
printf("Error: Saving current port settings failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Make sure we restore settings on exit */
|
||||
if (first)
|
||||
{
|
||||
atexit(&restore);
|
||||
first = false;
|
||||
}
|
||||
|
||||
/* Control, input, output, local modes for tty device */
|
||||
option.tio.c_cflag |= CLOCAL | CREAD;
|
||||
option.tio.c_oflag = 0;
|
||||
option.tio.c_lflag = 0;
|
||||
|
||||
/* Control characters */
|
||||
option.tio.c_cc[VTIME] = 0; /* Inter-character timer unused */
|
||||
option.tio.c_cc[VMIN] = 1; /* Blocking read until 1 character received */
|
||||
|
||||
/* Activate new port settings */
|
||||
tcsetattr(fd, TCSANOW, &option.tio);
|
||||
tcsetattr(fd, TCSAFLUSH, &option.tio);
|
||||
|
||||
maxfd = MAX(fd, console) + 1; /* Maximum bit entry (fd) to test */
|
||||
|
||||
/* Input loop */
|
||||
while (true)
|
||||
{
|
||||
FD_ZERO(&rdfs);
|
||||
FD_SET(fd, &rdfs);
|
||||
FD_SET(console, &rdfs);
|
||||
|
||||
/* Block until input becomes available */
|
||||
select(maxfd, &rdfs, NULL, NULL, NULL);
|
||||
if (FD_ISSET(fd, &rdfs))
|
||||
{
|
||||
/* Input from tty device ready */
|
||||
if (read(fd, &c, 1) > 0)
|
||||
{
|
||||
/* Print received tty character to stdout */
|
||||
putchar(c);
|
||||
fflush(stdout);
|
||||
} else
|
||||
{
|
||||
if (!option.no_autoconnect)
|
||||
gotty_printf("Disconnected");
|
||||
return(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
if (FD_ISSET(console, &rdfs))
|
||||
{
|
||||
/* Input from stdin ready */
|
||||
status = read(console, &c, 1);
|
||||
|
||||
/* Exit upon ctrl-g ctrl-q sequence */
|
||||
c1 = c0;
|
||||
c0 = c;
|
||||
if ((c0 == CTRLQ) && (c1 == CTRLG))
|
||||
exit(EXIT_SUCCESS);
|
||||
|
||||
/* Forward input to tty device */
|
||||
status = write(fd, &c, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return(EXIT_SUCCESS);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue