如果我在虚拟终端中输入 ls -l /dev ,我会得到
lrwxrwxrwx 1 root root 15 apr 10 10:59 stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 apr 10 10:59 stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root 15 apr 10 10:59 stdout -> /proc/self/fd/1
如果我然后输入 ls -l /proc/self/fd 我得到
lrwx------ 1 user user 64 apr 10 19:59 0 -> /dev/pts/1
lrwx------ 1 user user 64 apr 10 19:59 1 -> /dev/pts/1
lrwx------ 1 user user 64 apr 10 19:59 2 -> /dev/pts/1
所有条目都指向同一个设备文件,该文件也恰好是虚拟 shell 的控制终端(由“tty”命令确认)。那么我是否正确地假设 stdin、sdout 和 stderr 文件描述符都在同一个文件(/dev/pts/1)上运行,例如,已经进行了三个单独的 open() 调用(当虚拟 shell 进程从其分叉时)父进程)在同一个文件上?
如果是这样,请在运行以下程序时:
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main() {
int rfd = open("./a_file",O_RDONLY);
int wfd = open("./a_file",O_WRONLY);
char rc='a',wc='b';
if (write(rfd,&wc,1)<0) {
perror("Error");
}
if (read(wfd,&rc,1)<0) {
perror("Error");
}
}
给出:
Error: Bad file descriptor
Error: Bad file descriptor
正如预期的那样,但是当在 read() 参数中将 rfd 更改为 1 (sdtout) 并将 wfd 更改为 0 (stdin) 时,我没有收到错误。这是否意味着 /dev/tty 是使用 O_RDWR 标志打开的?
尝试时:
if (write(1,&wc,1)<0) {
perror("Error");
}
if (read(0,&rc,1)<0) {
perror("Error");
}
我在控制台上看到“b”,但 read() 调用没有返回,就好像没有从文件中读取任何数据一样。这是为什么?
答案1
同意它们都引用相同的设备,实际问题出现在最后。read
无法返回任何内容的原因/dev/tty
不仅仅是来自其的连接输入对其输出,而是您的(shell)进程和真实设备(即 Linux 控制台)之间的连接。您可以在控制台上运行一个程序,该程序从主机读取数据(例如上面的示例)并回复(为调用提供数据read
),但如果没有额外的连接,read
将没有数据。
进一步阅读:
- 读取写入 /dev/tty* 的内容
- /dev/pts 文件中存储了什么内容,我们可以打开它们吗?
- 如何读/写 tty* 设备?,不是重复的,
但在没有解释的情况下对缺乏数据进行了相同的观察。