终端设备:终端属性

1. 终端IO 数据结构

  1. 每个终端设备都有相应的输入/输出队列
    输入队列数据可能来自于键盘,串口等输入设备。也可能来自于其它进程
    输出队列数据可能递送给显示器,也可能递送给其它进程

输入队列:
可能工作在两种模式下,规范输入处理和非规范输入处理
在这里插入图片描述

  1. 数据控制
  • 来自键盘/串口的数据输入递送到输入队列后,可能拷贝到输出队列(回显)
  • 来自键盘/串口的数据输入过多,超过MAX_INPUT(大多数系统在输出队列递送响铃字符)。
  • 规范输入处理,最大行字节数为MAX_CANON
  • 向缓冲写,当写队列满时,写进程会睡眠
  • 缓冲队列可以进行刷新操作!属性可配置
          tcflag_t c_iflag;      /* input modes */
          tcflag_t c_oflag;      /* output modes */
          tcflag_t c_cflag;      /* control modes  RS232控制*/ 
          tcflag_t c_lflag;      /* local modes */
          cc_t     c_cc[NCCS];   /* special characters */

***c_iflag:***

   	(? 什么是BREAK?)
      IGNBRK Ignore BREAK condition on input.

      BRKINT If  IGNBRK  is  set,  a  BREAK is ignored.  If it is not set but
             BRKINT is set, then a BREAK causes the input and  output  queues
             to  be  flushed, and if the terminal is the controlling terminal
             of a foreground process group, it will cause a SIGINT to be sent
             to  this  foreground  process  group.   When  neither IGNBRK nor
             BRKINT are set, a BREAK reads as a null byte ('\0'), except when
             PARMRK  is  set,  in which case it reads as the sequence \377 \0
             \0.

   	(忽略校验错误)
      IGNPAR Ignore framing errors and parity errors.

      PARMRK If this bit is set, input bytes with parity  or  framing  errors
             are  marked  when passed to the program.  This bit is meaningful
             only when INPCK is set and IGNPAR is not set.  The way erroneous
             bytes  are  marked  is  with  two  preceding bytes, \377 and \0.
             Thus, the program actually reads three bytes for  one  erroneous
             byte  received from the terminal.  If a valid byte has the value
             \377, and ISTRIP (see below) is not set, the program might  con‐
             fuse it with the prefix that marks a parity error.  Therefore, a
             valid byte \377 is passed to the  program  as  two  bytes,  \377
             \377, in this case.

             If  neither  IGNPAR  nor  PARMRK is set, read a character with a
             parity error or framing error as \0.
             
   	(输入校验检查)
      INPCK  Enable input parity checking.

   	(剥除输入字符的bit7)
      ISTRIP Strip off eighth bit.
    
      INLCR  Translate NL to CR on input.

      IGNCR  Ignore carriage return on input.

      ICRNL  Translate carriage return to newline on input (unless  IGNCR  is
             set).

      IUCLC  (not in POSIX) Map uppercase characters to lowercase on input.

   	(???)
      IXON   Enable XON/XOFF flow control on output.

      IXANY  (XSI)  Typing  any  character will restart stopped output.  (The
             default is to allow just the START character to restart output.)
   	(???)
      IXOFF  Enable XON/XOFF flow control on input.

      IMAXBEL
             (not in POSIX) Ring bell when input queue is full.   Linux  does
             not implement this bit, and acts as if it is always set.

      IUTF8 (since Linux 2.6.4)
             (not  in POSIX) Input is UTF8; this allows character-erase to be
             correctly performed in cooked mode.


***c_oflag:***

      OPOST  Enable implementation-defined output processing.

      OLCUC  (not in POSIX) Map lowercase characters to uppercase on output.

      ONLCR  (XSI) Map NL to CR-NL on output.

      OCRNL  Map CR to NL on output.

      ONOCR  Don't output CR at column 0.

      ONLRET Don't output CR.

      OFILL  Send fill characters for a delay,  rather  than  using  a  timed
             delay.

      OFDEL  Fill character is ASCII DEL (0177).  If unset, fill character is
             ASCII NUL ('\0').  (Not implemented on Linux.)

      NLDLY  Newline  delay  mask.   Values  are  NL0  and  NL1.    [requires
             _BSD_SOURCE or _SVID_SOURCE or _XOPEN_SOURCE]

      CRDLY  Carriage  return  delay mask.  Values are CR0, CR1, CR2, or CR3.
             [requires _BSD_SOURCE or _SVID_SOURCE or _XOPEN_SOURCE]

      TABDLY Horizontal tab delay mask.  Values are TAB0,  TAB1,  TAB2,  TAB3
             (or  XTABS).   A  value of TAB3, that is, XTABS, expands tabs to
             spaces  (with  tab  stops  every  eight   columns).    [requires
             _BSD_SOURCE or _SVID_SOURCE or _XOPEN_SOURCE]

      BSDLY  Backspace  delay  mask.  Values are BS0 or BS1.  (Has never been
             implemented.)   [requires   _BSD_SOURCE   or   _SVID_SOURCE   or
             _XOPEN_SOURCE]

      VTDLY  Vertical tab delay mask.  Values are VT0 or VT1.

      FFDLY  Form  feed  delay  mask.   Values  are  FF0  or  FF1.  [requires
             _BSD_SOURCE or _SVID_SOURCE or _XOPEN_SOURCE]



c_cflag:
   	(字符大小屏蔽)
      CSIZE  Character size mask.  Values are CS5, CS6, CS7, or CS8.
      (停止位个数)
      CSTOPB Set two stop bits, rather than one.

      CREAD  Enable receiver.
      
     (奇偶校验使能)
      PARENB Enable parity generation  on  output  and  parity  checking  for
             input.
     (奇偶校验:奇或者偶配置)
      PARODD If  set, then parity for input and output is odd; otherwise even
             parity is used.

      HUPCL  Lower modem control lines after last process closes  the  device
             (hang up).

      CLOCAL Ignore modem control lines.

      LOBLK  (not  in POSIX) Block output from a noncurrent shell layer.  For
             use by shl (shell layers).  (Not implemented on Linux.)

      CIBAUD (not in POSIX) Mask for input speeds.  The values for the CIBAUD
             bits are the same as the values for the CBAUD bits, shifted left
             IBSHIFT  bits.   [requires  _BSD_SOURCE  or  _SVID_SOURCE]  (Not
             implemented on Linux.)

      CMSPAR (not  in  POSIX)  Use  "stick" (mark/space) parity (supported on
             certain serial devices): if PARODD is set,  the  parity  bit  is
             always 1; if PARODD is not set, then the parity bit is always 0.
             [requires _BSD_SOURCE or _SVID_SOURCE]

      CRTSCTS
             (not  in  POSIX)  Enable  RTS/CTS   (hardware)   flow   control.
             [requires _BSD_SOURCE or _SVID_SOURCE]




c_lflag:
     (启动终端产生信号)
      ISIG   When  any  of  the  characters  INTR,  QUIT,  SUSP, or DSUSP are
             received, generate the corresponding signal.
             
    (启用规范行输入处理)
      ICANON Enable canonical mode (described below).

      XCASE  (not in POSIX; not supported under Linux) If ICANON is also set,
             terminal  is  uppercase  only.  Input is converted to lowercase,
             except for characters preceded by \.  On output, uppercase char‐
             acters  are preceded by \ and lowercase characters are converted
             to  uppercase.   [requires  _BSD_SOURCE   or   _SVID_SOURCE   or
             _XOPEN_SOURCE]

     (输入需要回显)
      ECHO   Echo input characters.
      
     (规范输入行处理 && 擦除字符功能使能)
      ECHOE  If  ICANON is also set, the ERASE character erases the preceding
             input character, and WERASE erases the preceding word.
             
   	(规范输入行处理 && KILL字符擦除当前行)
      ECHOK  If ICANON is also set, the KILL  character  erases  the  current
             line.
   	(规范输入行处理 && 设置回显字符为 NL字符)
      ECHONL If ICANON is also set, echo the NL character even if ECHO is not
             set.

      ECHOCTL
             (not in POSIX) If ECHO is also set, terminal special  characters
             other than TAB, NL, START, and STOP are echoed as ^X, where X is
             the character with ASCII code  0x40  greater  than  the  special
             character.   For  example,  character 0x08 (BS) is echoed as ^H.
             [requires _BSD_SOURCE or _SVID_SOURCE]

      ECHOPRT
             (not in POSIX) If ICANON and ECHO are also set,  characters  are
             printed  as  they  are  being  erased.  [requires _BSD_SOURCE or
             _SVID_SOURCE]

      ECHOKE (not in POSIX) If ICANON is also set, KILL is echoed by  erasing
             each  character  on the line, as specified by ECHOE and ECHOPRT.
             [requires _BSD_SOURCE or _SVID_SOURCE]

      DEFECHO
             (not in POSIX) Echo only when a process is reading.  (Not imple‐
             mented on Linux.)

      FLUSHO (not  in  POSIX;  not  supported  under  Linux)  Output is being
             flushed.  This flag is toggled by typing the DISCARD  character.
             [requires _BSD_SOURCE or _SVID_SOURCE]

   	(中断字符禁止刷新缓冲)
      NOFLSH Disable  flushing  the  input  and output queues when generating
             signals for the INT, QUIT, and SUSP characters.

   	(后台进程尝试写终端设备,发送信号SIGTTOU )
      TOSTOP Send the SIGTTOU signal to the process  group  of  a  background
             process which tries to write to its controlling terminal.

      PENDIN (not  in POSIX; not supported under Linux) All characters in the
             input queue are reprinted  when  the  next  character  is  read.
             (bash(1)  handles typeahead this way.)  [requires _BSD_SOURCE or
             _SVID_SOURCE]

   	(???)
      IEXTEN Enable implementation-defined input processing.  This  flag,  as
             well  as ICANON must be enabled for the special characters EOL2,
             LNEXT, REPRINT, WERASE to be interpreted, and for the IUCLC flag
             to be effective.



 c_cc:
        The  c_cc  array defines the terminal special characters.  The symbolic
      indices (initial values) and meaning are:

      VDISCARD
             (not in POSIX; not supported under Linux; 017, SI, Ctrl-O)  Tog‐
             gle: start/stop discarding pending output.  Recognized when IEX‐
             TEN is set, and then not passed as input.

      VDSUSP (not in POSIX; not  supported  under  Linux;  031,  EM,  Ctrl-Y)
             Delayed  suspend character (DSUSP): send SIGTSTP signal when the
             character is read by the user program.  Recognized  when  IEXTEN
             and  ISIG are set, and the system supports job control, and then
             not passed as input.

      VEOF   (004, EOT, Ctrl-D) End-of-file character (EOF).  More precisely:
             this  character  causes the pending tty buffer to be sent to the
             waiting user program without waiting for end-of-line.  If it  is
             the first character of the line, the read(2) in the user program
             returns 0, which signifies end-of-file.  Recognized when  ICANON
             is set, and then not passed as input.

      VEOL   (0,  NUL)  Additional  end-of-line  character (EOL).  Recognized
             when ICANON is set.

      VEOL2  (not in POSIX; 0, NUL) Yet another end-of-line character (EOL2).
             Recognized when ICANON is set.

      VERASE (0177, DEL, rubout, or 010, BS, Ctrl-H, or also #) Erase charac‐
             ter (ERASE).  This erases the previous not-yet-erased character,
             but  does  not  erase past EOF or beginning-of-line.  Recognized
             when ICANON is set, and then not passed as input.

      VINTR  (003, ETX, Ctrl-C, or also 0177, DEL, rubout) Interrupt  charac‐
             ter (INTR).  Send a SIGINT signal.  Recognized when ISIG is set,
             and then not passed as input.

      VKILL  (025, NAK, Ctrl-U, or Ctrl-X, or also @) Kill character  (KILL).
             This  erases  the input since the last EOF or beginning-of-line.
             Recognized when ICANON is set, and then not passed as input.

      VLNEXT (not in POSIX; 026, SYN, Ctrl-V) Literal next  (LNEXT).   Quotes
             the  next  input  character,  depriving it of a possible special
             meaning.  Recognized when IEXTEN is set, and then not passed  as
             input.

      VMIN   Minimum number of characters for noncanonical read (MIN).

      VQUIT  (034,  FS,  Ctrl-\) Quit character (QUIT).  Send SIGQUIT signal.
             Recognized when ISIG is set, and then not passed as input.

      VREPRINT
             (not in POSIX; 022, DC2, Ctrl-R) Reprint unread characters  (RE‐
             PRINT).  Recognized when ICANON and IEXTEN are set, and then not
             passed as input.

      VSTART (021, DC1, Ctrl-Q) Start  character  (START).   Restarts  output
             stopped by the Stop character.  Recognized when IXON is set, and
             then not passed as input.

      VSTATUS
             (not in POSIX; not supported under Linux; status  request:  024,
             DC4, Ctrl-T).  Status character (STATUS).  Display status infor‐
             mation at terminal, including state of  foreground  process  and
             amount of CPU time it has consumed.  Also sends a SIGINFO signal
             (not supported on Linux) to the foreground process group.

      VSTOP  (023, DC3, Ctrl-S) Stop character  (STOP).   Stop  output  until
             Start  character  typed.   Recognized when IXON is set, and then
             not passed as input.

      VSUSP  (032, SUB, Ctrl-Z) Suspend character (SUSP).  Send SIGTSTP  sig‐
             nal.  Recognized when ISIG is set, and then not passed as input.

      VSWTCH (not in POSIX; not supported under Linux; 0, NUL) Switch charac‐
             ter (SWTCH).  Used in System V to switch shells in shell layers,
             a predecessor to shell job control.

      VTIME  Timeout in deciseconds for noncanonical read (TIME).

      VWERASE
             (not  in  POSIX;  027, ETB, Ctrl-W) Word erase (WERASE).  Recog‐
             nized when ICANON and IEXTEN are set, and  then  not  passed  as
             input.
  1. 终端行规模块
    在这里插入图片描述
  2. 终端设备属性接口
    在这里插入图片描述

2. 终端IO 编程举例

2.1 终端特殊输入字符

在这里插入图片描述
表中可被更改的字符 映射位置在
cc_t c_cc[NCCS]; /* special characters */取相应下标

  • 禁止中断字符
  • 文件结束符 修改为’CTRL + B’
/*

      TCSANOW
             the change occurs immediately.

      TCSADRAIN
             the change occurs after all output written to fd has been trans‐
             mitted.  This option should be  used  when  changing  parameters
             that affect output.

      TCSAFLUSH
             the  change  occurs  after  all  output  written  to  the object
             referred by fd has been transmitted, and all input that has been
             received  but  not  read  will be discarded before the change is
             made.

*/
extern "C"
{
   #include <termios.h>
   #include <unistd.h>
}
#include <iostream>
using namespace std;

int main(void)
{
   long vdisable;
   struct termios term;

   /**/	
   if(isatty(STDIN_FILENO)==0)
   {
   	cout << "Not a ttydevice" << endl;
   	return -1;
   }

   /**/
   if((vdisable = fpathconf(STDIN_FILENO,_PC_VDISABLE)) < 0)
   {
   	cout << "can not get vdisable " << endl;
   	return -1;
   }

   /**/
   if(tcgetattr(STDIN_FILENO,&term) < 0)
   {
   	cout << "failed to get termio" << endl;
   	return -1;
   }

   term.c_cc[VINTR]=vdisable;
   term.c_cc[VEOF]=2;/*ctrl + B*/
   
   if(tcsetattr(STDIN_FILENO, TCSANOW, &term)<0)
   {
   	cout << "failed to set termio" << endl;
   	return -1;
   }
   
   
   return 0;
}

2.2 终端波特率设置

/*speed_t
	        B0
            B50
            B75
            B110
            B134
            B150
            B200
            B300
            B600
            B1200
            B1800
            B2400
            B4800
            B9600
            B19200
            B38400
            B57600
            B115200
            B230400
*/
       speed_t cfgetispeed(const struct termios *termios_p);

       speed_t cfgetospeed(const struct termios *termios_p);

       int cfsetispeed(struct termios *termios_p, speed_t speed);

       int cfsetospeed(struct termios *termios_p, speed_t speed);

2.3 行控制函数

01		/*???*/
       int tcsendbreak(int fd, int duration);
       

02      /*
       tcdrain() waits until all output written to the object referred  to  by
       fd has been transmitted.
       */
       int tcdrain(int fd);


03	  /*
	       tcflush() discards data written to the object referred to by fd but not
       transmitted, or data received but not read, depending on the  value  of
       queue_selector:

       TCIFLUSH
              flushes data received but not read.

       TCOFLUSH
              flushes data written but not transmitted.

       TCIOFLUSH
              flushes  both  data  received but not read, and data written but
              not transmitted.
     */
       int tcflush(int fd, int queue_selector);



04 /*       tcflow() suspends transmission or  reception  of  data  on  the  object
       referred to by fd, depending on the value of action:

       TCOOFF suspends output.

       TCOON  restarts suspended output.

       TCIOFF transmits a STOP character, which stops the terminal device from
              transmitting data to the system.

       TCION  transmits a START character, which starts  the  terminal  device
              transmitting data to the system.

       The  default  on  open of a terminal file is that neither its input nor
       its output is suspended.
*/       
       int tcflow(int fd, int action);

2.4 终端标识

获取终端设备名:

       #include <stdio.h>

       char *ctermid(char *s);

判断fd是否为终端设备

       #include <unistd.h>

       int isatty(int fd);
       

2.5 获取tty描述符对应的设备

NAME
       ttyname, ttyname_r - return name of a terminal

SYNOPSIS
       #include <unistd.h>

       char *ttyname(int fd);

       int ttyname_r(int fd, char *buf, size_t buflen);

DESCRIPTION
       The  function  ttyname() returns a pointer to the null-terminated path‐
       name of the terminal device that is open on the file descriptor fd,  or
       NULL on error (for example, if fd is not connected to a terminal).  The
       return value may point to static data, possibly overwritten by the next
       call.   The function ttyname_r() stores this pathname in the buffer buf
       of length buflen.

RETURN VALUE
       The function ttyname() returns a pointer to a pathname on success.   On
       error,  NULL is returned, and errno is set appropriately.  The function
       ttyname_r() returns 0 on success, and an error number upon error.
#include <iostream>
using namespace std;
extern "C"
{
	#include <unistd.h>
}
int main(void)
{
	cout << ttyname(0) << endl;
	cout << ttyname(1) << endl;
	cout << ttyname(2) << endl;
	return 0;
}

终端模拟器下的测试 输出:
/dev/pts/2
/dev/pts/2
/dev/pts/2

CTRL + ALT + F6 切换终端 输出:
/dev/tty6
/dev/tty6
/dev/tty6

2.6 规范行输入与非规范行输入

2.6.1 规范行输入模式

返回条件:

  • 要求读取的字符个数条件满足,从终端驱动程序返回
  • 读到行定界符返回 [NL EOL EOL2 EOF]
  • 捕捉到信号并且读函数不自动重启,函数返回

2.6.2 非规范行输入模式

通过c_cc[VMIN] 以及 c_cc[VTIME]
用户自定义:MIN 和 TIME的值
在这里插入图片描述

3. 终端IO 控制命令 stty

stty封装了 以下6个接口函数
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值