Posts p5重写linux命令--链接控制
Post
Cancel

p5重写linux命令--链接控制

1. 设备文件

1.1 概览

终端tty文件,dev/pts/2

  1. 设备文件

设备文件是链接,而不是容器。内核中传输设备数据的子程序被称为设备驱动程序

1
crw--w----  1 xm   tty  136, 0 2  23 10:50 0

从终端进行数据传输的代码是在设备-进程表中编号为136的子程序,0位参数。

  1. 设备与权限位

  1. write程序

将终端的输入写入一个指定的文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main(int ac,char *av[]){
    int fd;
    char buf[BUFSIZ];
    if (ac != 2){
        perror("write error");
        exit(1);
    }
    fd = open(av[1],O_WRONLY);
    if( fd == -1){
        perror("open error");
    }
    while ( fgets(buf,BUFSIZ,stdin) != NULL){
        if  (write(fd,buf,strlen(buf)) == -1){
            break;
        }
        close(fd);
    }
}
  1. 设备文件 与 i-节点
  • 目录并不能区分,哪些是磁盘文件,哪些是设备文件

  • i-节点的信息被记录在 结构stat 中的 st_mode 中

  • 磁盘文件的i-节点包含指向数据块的指针

  • 设备文件的i-节点包含指向内核子程序的指针

read是如何工作的? 内核首先找到文件描述符的i-节点,通过i-节点判断是磁盘文件or设备文件。 如果是设备文件,内核通过调用设备驱动的read部分来读取数据

2. 设备与文件的不同

磁盘链接通常有缓冲区, 设备链接一般没有

2.1 磁盘的链接属性

系统调用open用户在进程和磁盘文件中创建一个链接。若干属性如下. 更改链接属性一般有两种方法:

  • fcntl
  • open()
  1. 缓冲机制

关闭缓冲

1
2
3
4
5
6
7
8
9
10
11
12
int main(int ac,char *av[]){
    int fd = open("/home/xm/projects/linux/a.txt",O_WRONLY);
    if( fd == -1){
        perror(" open error");
    }
    int s ;
    s = fcntl(fd,F_GETFL);
    s |= O_SYNC;  // 关缓存
    int result = fcntl(fd,F_SETFL,s);
    if  ( result == 1)
        perror("fcntl error");
}
  1. 开启尾部添加
` s= O_APPEND;`
  1. 也可以通过open() 设置第二参数, 不用fcntl这么麻烦

fd = open(FILE_NAME,O_WRONLY|O_APPEND|O_SYNC);

2.2 终端的链接属性

  • tcgetattr(int fd,struct termios *info); // 获取终端状态
  • tcsetattr(int fd,int when,struct termios *info); // 设置终端状态属性
  1. 显示回显状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main(int ac,char *av[]){
    struct termios settings;
    int rv;

    rv = tcgetattr(0,&settings);  // 终端为0号 我也不知道为啥是0  tcgetattr  获取设备属性
    if  (rv == -1){
        perror("tcgetattr error");
        exit(1);
    }
    if( settings.c_cflag & ECHO )       // 这里主要看termios 这个数据结构 里面写的还很清楚
        printf("echo is open\n");
    else
        printf("echo is off\n");
}
  1. 关闭 or 打开回显
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
int main(int ac,char *av[]){
    struct termios settings;
    int rv;
    ac = 2;
    av[1] = "n";
    rv = tcgetattr(0,&settings);  // 终端为0号 我也不知道为啥是0  tcgetattr  获取设备属性
    if  (rv == -1){
        perror("tcgetattr error");
        exit(1);
    }
    if( settings.c_cflag & ECHO )       // 这里主要看termios 这个数据结构 里面写的还很清楚
        printf("echo is open\n");
    else
        printf("echo is off\n");

    printf("ready change ECHO\n");

    if  (ac  == 1)
        return 0;

    if( av[1] == "y"){
        settings.c_cflag |= ECHO;
        printf("CHANGE ECHO is OPen\n ")        ;
    }
    else{
        settings.c_cflag &= ~ECHO;
        printf("CHANGE ECHO is closed   \n");
    }
}

3. 其他设备编程

简述一下,例如CD刻录机等设备。 可以刻录或者删除,可以以不同的速度刻录CD,等。 每个设备都有自己的属性集,程序员如何控制设备呢?

系统调用ioctl: int result = ioctl(int fd,int operation,arg …);

This post is licensed under CC BY 4.0 by the author.

Contents

Trending Tags