]> git.sur5r.net Git - tio/blobdiff - src/tty.c
Imported Upstream version 1.18
[tio] / src / tty.c
index 51c609ce2e68db557b1cfa68c8e565c2d1a15dc8..fccd5ff767f950998e132b0b2072dff2a0964184 100644 (file)
--- a/src/tty.c
+++ b/src/tty.c
@@ -19,6 +19,7 @@
  * 02110-1301, USA.
  */
 
+#include "config.h"
 #include <stdio.h>
 #include <unistd.h>
 #include <string.h>
 #include "tio/log.h"
 #include "tio/error.h"
 
-static struct termios new_stdout, old_stdout, old_tio;
-static long rx_total = 0, tx_total = 0;
+static struct termios tio, new_stdout, old_stdout, old_tio;
+static unsigned long rx_total = 0, tx_total = 0;
 static bool connected = false;
 static bool tainted = false;
+static bool standard_baudrate = true;
 static int fd;
 
+#ifndef BOTHER
+#define BOTHER 0010000
+#endif
+
 #define tio_printf(format, args...) \
 { \
     if (tainted) putchar('\n'); \
@@ -82,7 +88,7 @@ void handle_command_sequence(char input_char, char previous_char, char *output_c
             case KEY_I:
                 tio_printf("Settings information:");
                 tio_printf(" TTY device: %s", option.tty_device);
-                tio_printf(" Baudrate: %d", option.baudrate);
+                tio_printf(" Baudrate: %u", option.baudrate);
                 tio_printf(" Databits: %d", option.databits);
                 tio_printf(" Flow: %s", option.flow);
                 tio_printf(" Stopbits: %d", option.stopbits);
@@ -102,7 +108,7 @@ void handle_command_sequence(char input_char, char previous_char, char *output_c
             case KEY_S:
                 /* Show tx/rx statistics upon ctrl-t s sequence */
                 tio_printf("Statistics:");
-                tio_printf(" Sent %ld bytes, received %ld bytes", tx_total, rx_total);
+                tio_printf(" Sent %lu bytes, received %lu bytes", tx_total, rx_total);
                 *forward = false;
                 break;
             default:
@@ -113,7 +119,167 @@ void handle_command_sequence(char input_char, char previous_char, char *output_c
     }
 }
 
-void wait_for_tty_device(void)
+void stdout_configure(void)
+{
+    /* Save current stdout settings */
+    if (tcgetattr(STDOUT_FILENO, &old_stdout) < 0)
+    {
+        error_printf("Saving current stdio settings failed");
+        exit(EXIT_FAILURE);
+    }
+
+    /* Prepare new stdout settings */
+    memset(&new_stdout, 0, sizeof(new_stdout));
+
+    /* Control, input, output, local modes for stdout */
+    new_stdout.c_cflag = 0;
+    new_stdout.c_iflag = 0;
+    new_stdout.c_oflag = 0;
+    new_stdout.c_lflag = 0;
+
+    /* Control characters */
+    new_stdout.c_cc[VTIME] = 0; /* Inter-character timer unused */
+    new_stdout.c_cc[VMIN]  = 1; /* Blocking read until 1 character received */
+
+    /* Activate new stdout settings */
+    tcsetattr(STDOUT_FILENO, TCSANOW, &new_stdout);
+    tcsetattr(STDOUT_FILENO, TCSAFLUSH, &new_stdout);
+
+    /* Print launch hints */
+    tio_printf("tio v%s", VERSION);
+    tio_printf("Press ctrl-t q to quit");
+
+    /* Make sure we restore old stdout settings on exit */
+    atexit(&stdout_restore);
+}
+
+void stdout_restore(void)
+{
+    tcsetattr(STDOUT_FILENO, TCSANOW, &old_stdout);
+    tcsetattr(STDOUT_FILENO, TCSAFLUSH, &old_stdout);
+}
+
+void tty_configure(void)
+{
+    speed_t baudrate = 0;
+
+    memset(&tio, 0, sizeof(tio));
+
+    /* Set speed */
+    switch (option.baudrate)
+    {
+        /* The macro below expands into switch cases autogenerated by the
+         * configure script. Each switch case verifies and configures the baud
+         * rate and is of the form:
+         *
+         * case $baudrate: baudrate = B$baudrate; break;
+         *
+         * Only switch cases for baud rates detected supported by the host
+         * system are inserted.
+         *
+         * To see which baud rates are being probed see configure.ac
+         */
+        AUTOCONF_BAUDRATE_CASES
+
+        default:
+#if !HAVE_DECL_BOTHER
+            error_printf("Invalid baud rate");
+            exit(EXIT_FAILURE);
+#else
+            standard_baudrate = false;
+            break;
+#endif
+    }
+
+    if (standard_baudrate)
+    {
+        cfsetispeed(&tio, baudrate);
+        cfsetospeed(&tio, baudrate);
+    } else
+    {
+        tio.c_ispeed = tio.c_ospeed = baudrate;
+        tio.c_cflag &= ~CBAUD;
+        tio.c_cflag |= BOTHER;
+    }
+
+    /* Set databits */
+    tio.c_cflag &= ~CSIZE;
+    switch (option.databits)
+    {
+        case 5:
+            tio.c_cflag |= CS5;
+            break;
+        case 6:
+            tio.c_cflag |= CS6;
+            break;
+        case 7:
+            tio.c_cflag |= CS7;
+            break;
+        case 8:
+            tio.c_cflag |= CS8;
+            break;
+        default:
+            error_printf("Invalid data bits");
+            exit(EXIT_FAILURE);
+    }
+
+    /* Set flow control */
+    if (strcmp("hard", option.flow) == 0)
+    {
+        tio.c_cflag |= CRTSCTS;
+        tio.c_iflag &= ~(IXON | IXOFF | IXANY);
+    }
+    else if (strcmp("soft", option.flow) == 0)
+    {
+        tio.c_cflag &= ~CRTSCTS;
+        tio.c_iflag |= IXON | IXOFF;
+    }
+    else if (strcmp("none", option.flow) == 0)
+    {
+        tio.c_cflag &= ~CRTSCTS;
+        tio.c_iflag &= ~(IXON | IXOFF | IXANY);
+    }
+    else
+    {
+        error_printf("Invalid flow control");
+        exit(EXIT_FAILURE);
+    }
+
+    /* Set stopbits */
+    switch (option.stopbits)
+    {
+        case 1:
+            tio.c_cflag &= ~CSTOPB;
+            break;
+        case 2:
+            tio.c_cflag |= CSTOPB;
+            break;
+        default:
+            error_printf("Invalid stop bits");
+            exit(EXIT_FAILURE);
+    }
+
+    /* Set parity */
+    if (strcmp("odd", option.parity) == 0)
+    {
+        tio.c_cflag |= PARENB;
+        tio.c_cflag |= PARODD;
+    }
+    else if (strcmp("even", option.parity) == 0)
+    {
+        tio.c_cflag |= PARENB;
+        tio.c_cflag &= ~PARODD;
+    }
+    else if (strcmp("none", option.parity) == 0)
+        tio.c_cflag &= ~PARENB;
+    else
+    {
+        error_printf("Invalid parity");
+        exit(EXIT_FAILURE);
+    }
+}
+
+void tty_wait_for_device(void)
 {
     fd_set rdfs;
     int    status;
@@ -171,47 +337,7 @@ void wait_for_tty_device(void)
     }
 }
 
-void configure_stdout(void)
-{
-    /* Save current stdout settings */
-    if (tcgetattr(STDOUT_FILENO, &old_stdout) < 0)
-    {
-        error_printf("Saving current stdio settings failed");
-        exit(EXIT_FAILURE);
-    }
-
-    /* Prepare new stdout settings */
-    bzero(&new_stdout, sizeof(new_stdout));
-
-    /* Control, input, output, local modes for stdout */
-    new_stdout.c_cflag = 0;
-    new_stdout.c_iflag = 0;
-    new_stdout.c_oflag = 0;
-    new_stdout.c_lflag = 0;
-
-    /* Control characters */
-    new_stdout.c_cc[VTIME] = 0; /* Inter-character timer unused */
-    new_stdout.c_cc[VMIN]  = 1; /* Blocking read until 1 character received */
-
-    /* Activate new stdout settings */
-    tcsetattr(STDOUT_FILENO, TCSANOW, &new_stdout);
-    tcsetattr(STDOUT_FILENO, TCSAFLUSH, &new_stdout);
-
-    /* Print launch hints */
-    tio_printf("tio v%s", VERSION);
-    tio_printf("Press ctrl-t + q to quit");
-
-    /* Make sure we restore old stdout settings on exit */
-    atexit(&restore_stdout);
-}
-
-void restore_stdout(void)
-{
-    tcsetattr(STDOUT_FILENO, TCSANOW, &old_stdout);
-    tcsetattr(STDOUT_FILENO, TCSAFLUSH, &old_stdout);
-}
-
-void disconnect_tty(void)
+void tty_disconnect(void)
 {
     if (connected)
     {
@@ -222,16 +348,16 @@ void disconnect_tty(void)
     }
 }
 
-void restore_tty(void)
+void tty_restore(void)
 {
     tcsetattr(fd, TCSANOW, &old_tio);
     tcsetattr(fd, TCSAFLUSH, &old_tio);
 
     if (connected)
-        disconnect_tty();
+        tty_disconnect();
 }
 
-int connect_tty(void)
+int tty_connect(void)
 {
     fd_set rdfs;           /* Read file descriptor set */
     int    maxfd;          /* Maximum file descriptor used */
@@ -251,8 +377,8 @@ int connect_tty(void)
     /* Make sure device is of tty type */
     if (!isatty(fd))
     {
-        error_printf_silent("Not a tty device");
-        goto error_isatty;
+        error_printf("Not a tty device");
+        exit(EXIT_FAILURE);;
     }
 
     /* Lock device file */
@@ -266,6 +392,10 @@ int connect_tty(void)
     /* Flush stale I/O data (if any) */
     tcflush(fd, TCIOFLUSH);
 
+    /* Warn if non standard baud rate is used */
+    if (!standard_baudrate)
+        tio_printf("Warning: Using a non standard baud rate");
+
     /* Print connect status */
     tio_printf("Connected");
     connected = true;
@@ -278,22 +408,22 @@ int connect_tty(void)
     /* Make sure we restore tty settings on exit */
     if (first)
     {
-        atexit(&restore_tty);
+        atexit(&tty_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;
+    tio.c_cflag |= CLOCAL | CREAD;
+    tio.c_oflag = 0;
+    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 */
+    tio.c_cc[VTIME] = 0; /* Inter-character timer unused */
+    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);
+    tcsetattr(fd, TCSANOW, &tio);
+    tcsetattr(fd, TCSAFLUSH, &tio);
 
     maxfd = MAX(fd, STDIN_FILENO) + 1;  /* Maximum bit entry (fd) to test */
 
@@ -381,9 +511,8 @@ int connect_tty(void)
     return TIO_SUCCESS;
 
 error_tcgetattr:
-error_isatty:
 error_read:
-    disconnect_tty();
+    tty_disconnect();
 error_open:
     return TIO_ERROR;
 }