1. 设备文件
1.1 概览
终端tty文件,dev/pts/2
- 设备文件
设备文件是链接,而不是容器。内核中传输设备数据的子程序被称为设备驱动程序
1
crw--w---- 1 xm tty 136, 0 2月 23 10:50 0
从终端进行数据传输的代码是在设备-进程表中编号为136的子程序,0位参数。
- 设备与权限位
略
- 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);
}
}
- 设备文件 与 i-节点
目录并不能区分,哪些是磁盘文件,哪些是设备文件
i-节点的信息被记录在 结构stat 中的 st_mode 中
磁盘文件的i-节点包含指向数据块的指针
设备文件的i-节点包含指向内核子程序的指针
read是如何工作的? 内核首先找到文件描述符的i-节点,通过i-节点判断是磁盘文件or设备文件。 如果是设备文件,内核通过调用设备驱动的read部分来读取数据
2. 设备与文件的不同
磁盘链接通常有缓冲区, 设备链接一般没有
2.1 磁盘的链接属性
系统调用open
用户在进程和磁盘文件中创建一个链接。若干属性如下. 更改链接属性一般有两种方法:
- fcntl
- open()
- 缓冲机制
关闭缓冲
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");
}
- 开启尾部添加
` s | = O_APPEND;` |
- 也可以通过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
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");
}
- 关闭 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 …);