• 8设备文件


    设备文件

    Linux把所有设备都映射成了文件

    设备文件一般存储在 /dev 目录下

    我们可以像操作文件一样操作他们

    ls /dev –l

    brw-rw----  1 root disk      8,   0 Dec 21 20:00 sda

    crw--w----  1 root tty         4,   0 Dec 21 20:00 tty0

    b 表示块设备文件

    c  表示字符设备文件

    区别:

    块设备

    1.主要用于随机存取。

    2.将信息存储在定长块内,IO操作通过内核IO缓冲完成,可以对文件任意位置进行任意长度的 IO操作。

    3.比如磁盘。

    字符设备

    1.主要用于顺序存取。

    2.无内核缓冲,只能顺序存取。IO操作的长度为设备要求的块长的整数倍。

    3.比如终端,打印机,网络接口等

    设备文件操作流程

    打开: fd = open(devName, O_RDWR)

    备份: ioctl(fd, TCGETA, &oldAttr);

    设置: ioctl(fd,  TCSETA, &newAttr);

    读:     read(fd, buf, len);

    写:     write(fd, buf, len);

    恢复: ioctl(fd, TCSETA, &oldAttr);

    关闭: close(fd)

    终端设备操作

    include<unistd.h>

    ioctl(int fd, int cmd, struct termio *arg)

    cmd 参数

    TCGETA        获取终端信息

    TCSETA        写入终端信息

    TCSETAW     先将当前输入队列发送完毕,再写入设置

    TCSETAF      先将当前输入队列清空,再写入设置

    include<termio.h>

    struct termio 解析:

    struct termio

    {

    unsigned short c_iflag;   //终端输入方式

    unsigned short c_oflag;  //终端输出方式

    unsigned short c_cflag;  //终端控制方式

    unsigned short c_lflag;   //行规则模式

    char                  c_line;   

    unsigned char  c_cc[NCC];  //控制字符

    }

    例子:只允许输入小写,大写变小写

    void Test_iflag ()

    {

          int fd;

          struct termio  new,old;

          char buf[128];

          //获取当前的设备old

          ioctl(STDIN_FILENO,TCGETA,&old);

          //用new接受old,否则new=NULL;

          new=old;

          //设置小写风格,所有输入均为小写

          new.c_iflag|=IUCLC;

          ioctl(STDIN_FILENO,TCSETA,&new);

         

    scanf("%s",buf);

          printf("change buf:%s ",buf);

          //恢复原来的设备

          ioctl(STDIN_FILENO,TCSETA,&old);

          scanf("%s",buf);

          printf("resume buf:%s ",buf)

    }

    例子:只允许输出大写,小写变大写

    void Test_oflag()

    {

          struct termio  new,old;

          char *buf="hello world";

          printf("oginal buf:%s ",buf);

         

          ioctl(STDOUT_FILENO,TCGETA,&old);

         

          new=old;

          new.c_oflag|=OLCUC;

          ioctl(STDIN_FILENO,TCSETA,&new);

          printf("big buf:%s ",buf);

         

          ioctl(STDIN_FILENO,TCSETA,&old);

         

          printf("resume buf:%s ",buf);

    }

    注意:

    默认ICANON,输入模式为标准模式,有缓冲

    设置为 ~ICANON,则输入模式为原始输入,无缓冲

    例子1:按下字符,立马输出对应的ASCII,不需要按回车,回车键结束

    void Test_lflag()

    {

          struct termio  new,old;

         

          ioctl(STDOUT_FILENO,TCGETA,&old);

         

          new=old;

          new.c_lflag&=~ICANON;

         

          ioctl(STDIN_FILENO,TCSETA,&new);

          char ch=0;

          while(ch!=' ')

          {

               scanf("%c",&ch);

               printf("-->%d ",ch);

          }   

          ioctl(STDIN_FILENO,TCSETA,&old);

    }

    例子2:模拟密码,无显示密码的输入。

          new.c_lflag&=~ECHO;

          ioctl(STDIN_FILENO,TCSETA,&new);

                      

          char pPassWd[16];

          printf("input password :");

          scanf("%s",pPassWd);

          printf("password :%s ",pPassWd);

          ioctl(STDIN_FILENO,TCSETA,&old);

     

    例子:当输入超过5个字符或输入字符且超过5秒无操作,提示超时。

    注意:输入的字符要在缓冲区中为准。即“sdsasddsad”没有按下回车,只在终端显示,该属性不响应。因此new.c_lflag&=~ICANON;设置为原始输入且使用read(STDIN_FILENO,buf,128),而不是scanf();

    void Test_cc()

    {

          struct termio  new,old;

          char buf[128];

          ioctl(STDIN_FILENO,TCGETA,&old);

         

          new=old;

          new.c_lflag&=~ICANON;

          new.c_cc[VMIN]=5;       //5个字符

          new.c_cc[VTIME]=50;    //单位是0.1秒,50即5秒

         

          ioctl(STDIN_FILENO,TCSETA,&new);

          read(STDIN_FILENO,buf,128);

          printf(" over time");    

          ioctl(STDIN_FILENO,TCSETA,&old);

         

    }

    补充:

    printf在终端输出时改变颜色

    终端的字符颜色是用转义序列控制的,是文本模式下的系统显示功能,和具体的语言无关。

    转义序列是以 ESC 开头,可以用 33 完成相同的工作(ESC 的 ASCII 码用十进制表示就是 27, = 用八进制表示的 33)。

    注意:

    [:开始设置的标识;m:结束设置的标志;设置之间使用分号。

    33[显示方式;前景色;背景色m

    显示方式:0(默认值)、1(高亮)、22(非粗体)、4(下划线)、24(非下划线)、5(闪烁)、25(非闪烁)、7(反显)、27(非反显)

    前景色:30(黑色)、31(红色)、32(绿色)、 33(黄色)、34(蓝色)、35(洋红)、36(青色)、37(白色)

    背景色:40(黑色)、41(红色)、42(绿色)、 43(黄色)、44(蓝色)、45(洋红)、46(青色)、47(白色)

    33[0m 默认

    33[1;32;40m 绿色

    033[1;31;40m 红色

    例子:

    printf( "33[1;31;40m 输出红色字符 33[0m" )

  • 相关阅读:
    独家首发Java品优购项目课程,20天课程,430个知识点!视频+资料全部免费领!
    Java8 Stream:2万字20个实例,玩转集合的筛选、归约、分组、聚合
    你还在 if...else?代码这样写才好看!
    关于破解
    菜鸟上路
    4、udtf、udf、udaf
    【模板】快速排序
    最短路问题:迪杰斯特拉算法(Dijsktra)
    最短路径问题:弗洛伊德算法(Floyd)
    栈的基本概念
  • 原文地址:https://www.cnblogs.com/gd-luojialin/p/9215961.html
Copyright © 2020-2023  润新知