鉴于一个简单的程序:
/* ttyname.c */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main(int argc, char **argv)
{
char **tty = NULL;
tty = ttyname(fileno(stderr));
if (tty == NULL)
{
fprintf(stderr, "%s\n", strerror(errno));
exit(EXIT_FAILURE);
}
printf("%s\n", tty);
exit(EXIT_SUCCESS);
}
将其编译为initttyname
并调用它,结果如下:
Inappropriate ioctl for device
这意味着错误代码是ENOTTY
。
为什么 fprintf(stderr, ....) 在stderr
不引用终端设备时可以输出到屏幕?
如果您正在调用它,
init
那么您不会将输出输出到屏幕上;输出被发送到内核,内核将其打印到屏幕上。init
是一个特殊的过程您可以将其视为类似于以下 shell 脚本:
这是通过
/dev/console
设备完成的;用于 init 进程的 stdin/stdout/stderr 由内核附加到此。对该设备的写入由内核处理并发送到当前控制台设备,该设备可能是当前的 vty 或串行端口或其他地方。问题是,
ttyname
当 stderr 不是终端时,它总是会失败。因此,如果 stderr 在引导期间可能是一个套接字,ttyname 会失败,但您可以毫无问题地写入 stderr,这就是 fprintf 工作的原因。您可以通过执行 ttyname 的操作来获取套接字名称,即
readlink
在 /proc/self/fd/FD 上,通常 stderr 的“FD”为 2。