📄 tty_posix.c
字号:
/* * System V specific routines for manipulating the TTY */#include <stdio.h>#include <termios.h>#include <fcntl.h>#include "dial_dir.h"#include "modem.h"#include "param.h"static struct termios hold;extern int fd;/* * Change the communication line settings to the new values. */voidline_set(){static int first = 1;struct termios tbuf;unsigned int baud; /* nothing to do! */ if (fd == -1) return; if (first) { tcgetattr(fd, &hold); first = 0; } /* get the current settings */ tcgetattr(fd, &tbuf); /* set some beginning values */ tbuf.c_cc[VMIN] = 1; tbuf.c_cc[VTIME] = 1; tbuf.c_oflag = 0; tbuf.c_iflag = 0; tbuf.c_cflag = (CREAD|HUPCL|CLOCAL); tbuf.c_lflag = 0; if (*param->flow_ctrl == 'X') tbuf.c_iflag |= (IXON|IXOFF); /* strip high bit? */ if (*param->strip == 'Y') tbuf.c_iflag |= ISTRIP; /* * If the DTE speed is locked, then ignore all request to * change the speed. */ baud = modem->lock_sp[modem->t_cur]; if (baud == 0) baud = dir->baud[0]; /* the baud rate */ switch (baud) { case 300: tbuf.c_cflag |= B300; break; case 1200: tbuf.c_cflag |= B1200; break; case 2400: tbuf.c_cflag |= B2400; break; case 4800: tbuf.c_cflag |= B4800; break; case 9600: tbuf.c_cflag |= B9600; break; case 19200:#ifdef B19200 tbuf.c_cflag |= B19200;#else /* B19200 */#ifdef EXTA tbuf.c_cflag |= EXTA;#endif /* EXTA */#endif /* B19200 */ break; case 38400:#ifdef B38400 tbuf.c_cflag |= B38400;#else /* B38400 */#ifdef EXTB tbuf.c_cflag |= EXTB;#endif /* EXTB */#endif /* B38400 */ break; } /* the parity */ switch (dir->parity[0]) { case 'N': break; case 'O': tbuf.c_cflag |= (PARENB|PARODD); break; case 'E': tbuf.c_cflag |= PARENB; break; } /* the data bits */ if (dir->data_bits[0] == 8) tbuf.c_cflag |= CS8; else tbuf.c_cflag |= CS7; /* the stop bits */ if (dir->stop_bits[0] == 2) tbuf.c_cflag |= CSTOPB; /* now set 'em! */ tcsetattr(fd, TCSANOW, &tbuf); return;}/* * Put things back the way they were. */voidreset_line(){ tcsetattr(fd, TCSANOW, &hold); return;}/* * Put the stdin/stdout in terminal mode. We've divided up the * responsibility for the line settings options between the serial port * and the stdin and stdout. */voidterm_mode(){struct termios tbuf; tcgetattr(0, &tbuf); tbuf.c_cc[VMIN] = 1; tbuf.c_cc[VTIME] = 0; tbuf.c_iflag = 0; tbuf.c_oflag = 0; tbuf.c_lflag = 0; /* duplex */ if (dir->duplex[0] == 'H') tbuf.c_lflag = ECHO; tcsetattr(0, TCSANOW, &tbuf); return;}/* * Put the TTY driver in the mode suitable for xmodem transfers. */voidxmodem_mode(fds)int fds;{struct termios tbuf; tcgetattr(fds, &tbuf); /* * Turn off the XON/XOFF flow control, turn off echoing, and * switch to 8 bit no parity. */ tbuf.c_cc[VMIN] = 1; tbuf.c_cc[VTIME] = 0; tbuf.c_iflag = 0; /* no flow control or mapping */ tbuf.c_oflag = 0; /* no char mapping or delays */ tbuf.c_lflag = 0; /* no echo or signals */ tbuf.c_cflag &= ~(PARENB|CSIZE);/* no parity */ tbuf.c_cflag |= CS8; /* 8 bit */ tcsetattr(fds, TCSANOW, &tbuf); return;}/* * Put the TTY line in a mode suitable for the ASCII transfer. Puts the * terminal in the raw, non-blocking mode. */voidascii_mode(up)int up;{struct termios tbuf; tcgetattr(fd, &tbuf); tbuf.c_oflag = 0; /* flow control & 8th bit stripping */ if (up) { tbuf.c_iflag = (ISTRIP|IXON); /* if no CR's, use NL delays */ if (!strcmp(param->cr_up, "STRIP")) tbuf.c_oflag = (OPOST|ONLRET); /* CR delay times */ switch (param->cr_delay) { case 0: break; case 100: tbuf.c_oflag |= (OPOST|CR2); break; case 150: tbuf.c_oflag |= (OPOST|CR3); break; } } /* if down loading */ else tbuf.c_iflag = (ISTRIP|IXOFF); tcsetattr(fd, TCSANOW, &tbuf); return;}/* * Flush the file descriptor */inttty_flush(fds, mode)int fds, mode;{ switch(mode) { case 0: return(tcflush(fds, TCIFLUSH)); case 1: return(tcflush(fds, TCOFLUSH)); case 2: return(tcflush(fds, TCIOFLUSH)); }}/* * Wait for the output to drain */inttty_drain(fds)int fds;{#ifndef linux if (tcdrain(fds) < 1) perror("tcdrain");#endif return 0;}/* * Send a modem break */inttty_break(fds)int fds;{ return(tcsendbreak(fds, 0));}/* * Fix the file descriptor so that a read is satisfied immediately. When * read() is called it returns the character in the queue, or an error if * no key was pressed. */inttty_noblock(fds, on)int fds, on;{int current; current = fcntl(fds, F_GETFL, 0); if (on) return(fcntl(fds, F_SETFL, current | O_NDELAY)); else return(fcntl(fds, F_SETFL, current & ~O_NDELAY));}/* * Get the current baud rate of the terminal */intmy_speed(){static unsigned int speed[16] = {0, 50, 75, 110, 134, 150, 200, 300,600, 1200, 1800, 2400, 4800, 9600, 19200, 38400};struct termios tbuf; tcgetattr(0, &tbuf); return(speed[tbuf.c_cflag & CBAUD]);}/* * Restart any XON/XOFF flow control that may have stopped the tty */voidtty_restart(){ if (fd != -1 && *param->flow_ctrl == 'X') tcflow(fd, TCOON); return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -