static void defttymode(void) { struct termios def; /* Start with default tty settings. */ if (tcgetattr(STDIN_FILENO, &tmode) < 0) { syslog(LOG_ERR, "tcgetattr %s: %m", ttyn); exit(1); } omode = tmode; /* fill c_cc for dogettytab() */ dogettytab(); /* * Don't rely on the driver too much, and initialize crucial * things according to <sys/ttydefaults.h>. Avoid clobbering * the c_cc[] settings however, the console drivers might wish * to leave their idea of the preferred VERASE key value * there. */ cfmakesane(&def); tmode.c_iflag = def.c_iflag; tmode.c_oflag = def.c_oflag; tmode.c_lflag = def.c_lflag; tmode.c_cflag = def.c_cflag; if (NC) tmode.c_cflag |= CLOCAL; omode = tmode; }
// === PRIVATE === pid_t TTYProcess::LaunchProcess(int& fd, char *prog, char **child_args){ //Returns: -1 for errors, positive value (file descriptor) for the master side of the TTY to watch //First open/setup a new pseudo-terminal file/device on the system (master side) fd = posix_openpt(O_RDWR | O_NOCTTY); //open read/write if(fd<0){ return -1; } //could not create pseudo-terminal int rc = grantpt(fd); //set permissions if(rc!=0){ return -1; } rc = unlockpt(fd); //unlock file (ready for use) if(rc!=0){ return -1; } //Now fork, return the Master device and setup the child pid_t PID = fork(); if(PID==0){ //SLAVE/child int fds = ::open(ptsname(fd), O_RDWR | O_NOCTTY); //open slave side read/write ::close(fd); //close the master side from the slave thread //Adjust the slave side mode to RAW struct termios TSET; rc = tcgetattr(fds, &TSET); //read the current settings cfmakesane(&TSET); //set the RAW mode on the settings ( cfmakeraw(&TSET); ) tcsetattr(fds, TCSANOW, &TSET); //apply the changed settings //Change the controlling terminal in child thread to the slave PTY ::close(0); //close current terminal standard input ::close(1); //close current terminal standard output ::close(2); //close current terminal standard error dup(fds); // Set slave PTY as standard input (0); dup(fds); // Set slave PTY as standard output (1); dup(fds); // Set slave PTY as standard error (2); setsid(); //Make current process new session leader (so we can set controlling terminal) ioctl(0,TIOCSCTTY, 1); //Set the controlling terminal to the slave PTY //Execute the designated program rc = execvp(prog, child_args); ::close(fds); //no need to keep original file descriptor open any more exit(rc); } //MASTER thread (or error) return PID; }
static void test_termios_cfmakesane(void) { struct termios term; memset( &term, '\0', sizeof(term) ); cfmakesane( &term ); puts( "cfmakesane - OK" ); /* Check that all of the flags were set correctly */ rtems_test_assert( term.c_iflag == TTYDEF_IFLAG ); rtems_test_assert( term.c_oflag == TTYDEF_OFLAG ); rtems_test_assert( term.c_lflag == TTYDEF_LFLAG ); rtems_test_assert( term.c_cflag == TTYDEF_CFLAG ); rtems_test_assert( term.c_ispeed == TTYDEF_SPEED ); rtems_test_assert( term.c_ospeed == TTYDEF_SPEED ); rtems_test_assert( memcmp(&term.c_cc, ttydefchars, sizeof(term.c_cc)) == 0 ); }