为什么在 shell 启动之前 /proc/self/fd/0 在串行会话中没有可写位?

为什么在 shell 启动之前 /proc/self/fd/0 在串行会话中没有可写位?

我遇到了一个使用非常旧版本的程序线路噪声图书馆。一切都write()完成了STDIN_FILENO,像这样:

write(STDIN_FILENO,prompt,plen)

write失败并返回 -1 并errno设置为EBADF。我编写了一个 C 程序,该程序在系统启动时在交互启动之前/etc/init.d/rcS依次执行。 C 程序列出目录,其输出为:Busybox initsh/proc/self/fd

l-wx------    1 root     root          64 Jan  1 00:00 2 -> /dev/console
l-wx------    1 root     root          64 Jan  1 00:00 1 -> /dev/console
lr-x------    1 root     root          64 Jan  1 00:00 0 -> /dev/console

正如您所看到的 0 没有w设置位,我认为这就是write失败的原因。但是,正常shshell 启动后:

lrwx------    1 root     root          64 Jan  1 00:00 2 -> /dev/ttyS0
lrwx------    1 root     root          64 Jan  1 00:00 1 -> /dev/ttyS0
lrwx------    1 root     root          64 Jan  1 00:00 0 -> /dev/ttyS0

现在 0 已w设置。为什么会发生这种情况?

答案1

因为你可以拥有多个终端设备。

因此,作为参数专门getty调用。ttyS0所以它使用自己的代码来初始化所有的FD。这恰好与/dev/console打开init.人们可能会猜测getty用 打开 tty 一次O_RDWR,然后dup引用 FD。

我可以看到一个明显的原因代码这样工作。 agetty也可以用-stdin 来调用。所以始终使用dup()是最简单的实现。

我不确定为什么支持该选项。标准 System V 不一定使用或支持它inittab。似乎符合BSD 下使用的旧方法,其中init将终端设备作为打开的 FD 而不是参数传递。旧方法是init初始化所有 FD(关联,仅注意stderr下一个版本中添加的 2 个 FD)。

由于问题被编辑为指定 busybox,并且提到了 cttyhack,因此在 busybox 的情况下明显的解释是“它使代码更小”。这也是历史 Unix 代码的一个驱动特征。

相关内容