You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ag...@apache.org on 2020/08/13 23:59:04 UTC

[incubator-nuttx-apps] branch master updated: system/cu: refactor, add option -c to disable \n -> \r\n conversion

This is an automated email from the ASF dual-hosted git repository.

aguettouche pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx-apps.git


The following commit(s) were added to refs/heads/master by this push:
     new fcd3937  system/cu: refactor, add option -c to disable \n -> \r\n conversion
fcd3937 is described below

commit fcd3937d7c5fa57fe996f443c10c3f5cefbb231c
Author: Oleg Evseev <ev...@gmail.com>
AuthorDate: Thu Aug 13 00:10:37 2020 +0300

    system/cu: refactor, add option -c to disable \n -> \r\n conversion
    
    option -c will disable \n -> \r\n conversion both for serial device and console if it is a tty
    
    refactor: use only one function to set termios parameters, use termious related code and options only if CONFIG_SERIAL_TERMIOS is defined
---
 system/cu/cu_main.c | 163 ++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 115 insertions(+), 48 deletions(-)

diff --git a/system/cu/cu_main.c b/system/cu/cu_main.c
index 469063d..b053d28 100644
--- a/system/cu/cu_main.c
+++ b/system/cu/cu_main.c
@@ -81,6 +81,11 @@ enum parity_mode
  ****************************************************************************/
 
 static struct cu_globals_s g_cu;
+#ifdef CONFIG_SERIAL_TERMIOS
+int fd_std_tty;
+static struct termios g_tio_std;
+static struct termios g_tio_dev;
+#endif
 
 /****************************************************************************
  * Public Data
@@ -129,52 +134,17 @@ static void sigint(int sig)
   exit(0);
 }
 
-static int enable_crlf_conversion(int fd)
-{
 #ifdef CONFIG_SERIAL_TERMIOS
-  int rc = 0;
-  int ret;
-  struct termios tio;
-
-  /* enable \n -> \r\n conversion during write */
-
-  ret = tcgetattr(fd, &tio);
-  if (ret)
-    {
-      fprintf(stderr, "en_crlf_conv: ERROR during tcgetattr(): %d\n", errno);
-      rc = -1;
-    }
-
-  tio.c_oflag = OPOST | ONLCR;
-  ret = tcsetattr(fd, TCSANOW, &tio);
-  if (ret)
-    {
-      fprintf(stderr, "en_crlf_conv: ERROR during tcsetattr(): %d\n", errno);
-      rc = -1;
-    }
-
-  return rc;
-#else
-  return -1;
-#endif
-}
-
-static int set_baudrate(int fd, int rate, enum parity_mode parity,
-                        int rtscts)
+static int set_termios(int fd, int rate, enum parity_mode parity,
+                       int rtscts, int nocrlf)
 {
-#ifdef CONFIG_SERIAL_TERMIOS
   int rc = 0;
   int ret;
   struct termios tio;
 
-  /* enable \n -> \r\n conversion during write */
+  tio = g_tio_dev;
 
-  ret = tcgetattr(fd, &tio);
-  if (ret)
-    {
-      fprintf(stderr, "set_baudrate: ERROR during tcgetattr(): %d\n", errno);
-      rc = -1;
-    }
+  /* set baudrate */
 
   if (rate != 0)
     {
@@ -200,36 +170,81 @@ static int set_baudrate(int fd, int rate, enum parity_mode parity,
       tio.c_cflag |= CRTS_IFLOW | CCTS_OFLOW;
     }
 
+  tio.c_oflag = OPOST;
+
+  /* enable or disable \n -> \r\n conversion during write */
+
+  if (nocrlf == 0)
+    {
+      tio.c_oflag |= ONLCR;
+    }
+
   ret = tcsetattr(fd, TCSANOW, &tio);
   if (ret)
     {
-      fprintf(stderr, "set_baudrate: ERROR during tcsetattr(): %d\n", errno);
+      fprintf(stderr, "set_termios: ERROR during tcsetattr(): %d\n", errno);
       rc = -1;
+      goto errout;
     }
 
+  /* for tty stdout force enable or disable \n -> \r\n conversion */
+
+  if (fd_std_tty >= 0)
+  {
+    tio = g_tio_std;
+    if (nocrlf == 0)
+      {
+        tio.c_oflag |= ONLCR;
+      }
+    else
+      {
+        tio.c_oflag &= ~ONLCR;
+      }
+
+    ret = tcsetattr(fd_std_tty, TCSANOW, &tio);
+    if (ret)
+      {
+        fprintf(stderr, "set_termios: ERROR during tcsetattr(): %d\n",
+                errno);
+        rc = -1;
+      }
+  }
+
+errout:
   return rc;
-#else
-  if (rate == 0)
+}
+
+static int retrive_termios(int fd)
+{
+  tcsetattr(fd, TCSANOW, &g_tio_dev);
+  if (fd_std_tty >= 0)
     {
-      return 0;
+      tcsetattr(fd_std_tty, TCSANOW, &g_tio_std);
     }
 
-  return -1;
-#endif
+  return 0;
 }
+#endif
 
 static void print_help(void)
 {
   printf("Usage: cu [options]\n"
          " -l: Use named device (default %s)\n"
+#ifdef CONFIG_SERIAL_TERMIOS
          " -e: Set even parity\n"
          " -o: Set odd parity\n"
          " -s: Use given speed (default %d)\n"
          " -r: Disable RTS/CTS flow control (default: on)\n"
+         " -c: Disable lf -> crlf conversion (default: off)\n"
+#endif
          " -f: Enable endless mode without escape sequence (default: off)\n"
          " -?: This help\n",
+#ifdef CONFIG_SERIAL_TERMIOS
          CONFIG_SYSTEM_CUTERM_DEFAULT_DEVICE,
          CONFIG_SYSTEM_CUTERM_DEFAULT_BAUD);
+#else
+         CONFIG_SYSTEM_CUTERM_DEFAULT_DEVICE);
+#endif
 }
 
 static void print_escape_help(void)
@@ -273,9 +288,12 @@ int main(int argc, FAR char *argv[])
   pthread_attr_t attr;
   struct sigaction sa;
   FAR char *devname = CONFIG_SYSTEM_CUTERM_DEFAULT_DEVICE;
+#ifdef CONFIG_SERIAL_TERMIOS
   int baudrate = CONFIG_SYSTEM_CUTERM_DEFAULT_BAUD;
   enum parity_mode parity = PARITY_NONE;
   int rtscts = 1;
+  int nocrlf = 0;
+#endif
   int nobreak = 0;
   int option;
   int ret;
@@ -294,7 +312,7 @@ int main(int argc, FAR char *argv[])
   sigaction(SIGKILL, &sa, NULL);
 
   optind = 0;   /* global that needs to be reset in FLAT mode */
-  while ((option = getopt(argc, argv, "l:s:efhor?")) != ERROR)
+  while ((option = getopt(argc, argv, "l:s:cefhor?")) != ERROR)
     {
       switch (option)
         {
@@ -302,6 +320,7 @@ int main(int argc, FAR char *argv[])
             devname = optarg;
             break;
 
+#ifdef CONFIG_SERIAL_TERMIOS
           case 's':
             baudrate = atoi(optarg);
             break;
@@ -318,6 +337,11 @@ int main(int argc, FAR char *argv[])
             rtscts = 0;
             break;
 
+          case 'c':
+              nocrlf = 1;
+              break;
+#endif
+
           case 'f':
               nobreak = 1;
               break;
@@ -342,8 +366,47 @@ int main(int argc, FAR char *argv[])
       goto errout_with_devinit;
     }
 
-  enable_crlf_conversion(g_cu.outfd);
-  set_baudrate(g_cu.outfd, baudrate, parity, rtscts);
+#ifdef CONFIG_SERIAL_TERMIOS
+  /* remember serial device termios attributes */
+
+  ret = tcgetattr(g_cu.outfd, &g_tio_dev);
+  if (ret)
+    {
+      fprintf(stderr, "cu_main: ERROR during tcgetattr(): %d\n", errno);
+      goto errout_with_outfd;
+    }
+
+  /* remember std termios attributes if it is a tty. Try to select
+   * right descriptor that is used to refer to tty
+   */
+
+  if (isatty(fileno(stderr)))
+    {
+      fd_std_tty = fileno(stderr);
+    }
+  else if (isatty(fileno(stdout)))
+    {
+      fd_std_tty = fileno(stdout);
+    }
+  else if (isatty(fileno(stdin)))
+    {
+      fd_std_tty = fileno(stdin);
+    }
+  else
+    {
+      fd_std_tty = -1;
+    }
+
+  if (fd_std_tty >= 0)
+    {
+      tcgetattr(fd_std_tty, &g_tio_std);
+    }
+
+  if (set_termios(g_cu.outfd, baudrate, parity, rtscts, nocrlf) != 0)
+    {
+      goto errout_with_outfd_retrieve;
+    }
+#endif
 
   /* Open the serial device for reading.  Since we are already connected,
    * this should not fail.
@@ -443,6 +506,10 @@ int main(int argc, FAR char *argv[])
 
 errout_with_fds:
   close(g_cu.infd);
+#ifdef CONFIG_SERIAL_TERMIOS
+errout_with_outfd_retrieve:
+  retrive_termios(g_cu.outfd);
+#endif
 errout_with_outfd:
   close(g_cu.outfd);
 errout_with_devinit: