int main()

in system/cu/cu_main.c [275:515]


int main(int argc, FAR char *argv[])
{
  pthread_attr_t attr;
  struct sigaction sa;
  FAR const char *devname = CONFIG_SYSTEM_CUTERM_DEFAULT_DEVICE;
  FAR struct cu_globals_s *cu = &g_cu;
#ifdef CONFIG_SERIAL_TERMIOS
  int baudrate = CONFIG_SYSTEM_CUTERM_DEFAULT_BAUD;
  enum parity_mode parity = PARITY_NONE;
  int rtscts = 1;
#endif
  int nocrlf = 0;
  int nobreak = 0;
  int option;
  int ret;
  int bcmd;
  int start_of_line = 1;
  int exitval = EXIT_FAILURE;
  bool badarg = false;

  /* Initialize global data */

  memset(cu, 0, sizeof(*cu));

  /* Install signal handlers */

  memset(&sa, 0, sizeof(sa));
  sa.sa_handler = sigint;
  sigaction(SIGINT, &sa, NULL);

  optind = 0;   /* Global that needs to be reset in FLAT mode */
  while ((option = getopt(argc, argv, "l:s:cefhor?")) != ERROR)
    {
      switch (option)
        {
          case 'l':
            devname = optarg;
            break;

#ifdef CONFIG_SERIAL_TERMIOS
          case 's':
            baudrate = atoi(optarg);
            break;

          case 'e':
            parity = PARITY_EVEN;
            break;

          case 'o':
            parity = PARITY_ODD;
            break;

          case 'r':
            rtscts = 0;
            break;
#endif

          case 'c':
            nocrlf = 1;
            break;

          case 'f':
            nobreak = 1;
            break;

          case 'h':
          case '?':
            print_help();
            exitval = EXIT_SUCCESS;

            /* Go through */

          default:
            badarg = true;
            break;
        }
    }

  if (badarg)
    {
      return exitval;
    }

  /* Open the serial device for writing */

  cu->outfd = open(devname, O_WRONLY);
  if (cu->outfd < 0)
    {
      cu_error("cu_main: ERROR: Failed to open %s for writing: %d\n",
              devname, errno);
      goto errout_with_devinit;
    }

  /* Remember serial device termios attributes */

  ret = tcgetattr(cu->outfd, &cu->devtio);
  if (ret)
    {
      cu_error("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)))
    {
      cu->stdfd = fileno(stderr);
    }
  else if (isatty(fileno(stdout)))
    {
      cu->stdfd = fileno(stdout);
    }
  else if (isatty(fileno(stdin)))
    {
      cu->stdfd = fileno(stdin);
    }
  else
    {
      cu->stdfd = -1;
    }

  if (cu->stdfd >= 0)
    {
      tcgetattr(cu->stdfd, &cu->stdtio);
    }

#ifdef CONFIG_SERIAL_TERMIOS
  if (set_termios(cu, baudrate, parity, rtscts, nocrlf) != 0)
#else
  if (set_termios(cu, nocrlf) != 0)
#endif
    {
      goto errout_with_outfd_retrieve;
    }

  /* Open the serial device for reading.  Since we are already connected,
   * this should not fail.
   */

  cu->infd = open(devname, O_RDONLY);
  if (cu->infd < 0)
    {
      cu_error("cu_main: ERROR: Failed to open %s for reading: %d\n",
             devname, errno);
      goto errout_with_outfd;
    }

  /* Start the serial receiver thread */

  ret = pthread_attr_init(&attr);
  if (ret != OK)
    {
      cu_error("cu_main: pthread_attr_init failed: %d\n", ret);
      goto errout_with_fds;
    }

  /* Set priority of listener to configured value */

  attr.priority = CONFIG_SYSTEM_CUTERM_PRIORITY;

  ret = pthread_create(&cu->listener, &attr, cu_listener, cu);
  pthread_attr_destroy(&attr);
  if (ret != 0)
    {
      cu_error("cu_main: Error in thread creation: %d\n", ret);
      goto errout_with_fds;
    }

  /* Send messages and get responses -- forever */

  while (!cu->force_exit)
    {
      int ch = getc(stdin);

      if (ch < 0)
        {
          continue;
        }

      if (nobreak == 1)
        {
          write(cu->outfd, &ch, 1);
          continue;
        }

      if (start_of_line == 1 && ch == '~')
        {
          /* We've seen and escape (~) character, echo it to local
           * terminal and read the next char from serial
           */

          fputc(ch, stdout);
          bcmd = getc(stdin);
          if (bcmd == ch)
            {
              /* Escaping a tilde: handle like normal char */

              write(cu->outfd, &ch, 1);
              continue;
            }
          else
            {
              if (cu_cmd(bcmd) == 1)
                {
                  break;
                }
            }
        }

      /* Normal character */

      write(cu->outfd, &ch, 1);

      /* Determine if we are now at the start of a new line or not */

      if (ch == '\n' || ch == '\r')
        {
          start_of_line = 1;
        }
      else
        {
          start_of_line = 0;
        }
    }

  pthread_cancel(cu->listener);
  exitval = EXIT_SUCCESS;

  /* Error exits */

errout_with_fds:
  close(cu->infd);
errout_with_outfd_retrieve:
  retrieve_termios(cu);
errout_with_outfd:
  close(cu->outfd);
errout_with_devinit:
  return exitval;
}