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;
}