在 c 中文件名的开头和结尾之前和之后使用双下划线 ( __ ) 的目的是什么?



我正在作为初学者学习android内核。我可以通过 adb 使用dmesg命令读取从main()函数内的宏ERROR()system/core/init/init.c抛出的消息。我观察到在main()内部调用函数open_devnull_stdio()后,dmesg不再显示ERROR()抛出的消息。

为了找到原因,我开始挖掘system/core/init/util.c内部的open_devnull_stdio()声明,我发现这句话我看不懂

static const char *name = "/dev/__null__";

实际上,设备中/dev/内部没有名为__null__的文件,但是有一个名为null的文件,我可以使用adb pull抓取它,它是一个0字节(空)文件。

那么为什么文件名用双下划线 (__) 括起来呢?

这是 util.c 的链接

在 C 语言中,在开始之前、结束之后或两者之后使用双下划线没有特殊目的。从C的角度来看,文件名只是一个字符串,操作系统可以自由地以它选择的任何方式进行解释。从Linux的角度来看,这同样适用。文件名中的下划线只是字符。它们的处理方式与字母bt没有区别。

如果我猜对了,并且我正在阅读与您相同的文件(链接到您正在阅读的源代码可能是个好主意),那么代码在您提到的代码之后的行上的作用应该很明显。接下来的行是:

if (mknod(name, S_IFCHR | 0600, (1 << 8) | 3) == 0) {
fd = open(name, O_RDWR);
unlink(name);

这将创建空设备,然后将其打开并立即再次删除。

我怀疑这样做是为了让程序可以在不访问根文件系统的情况下运行,并且仍然能够打开相当于/dev/null.

我不知道答案,但我有一个想法:

以下页面显示了使用/dev/__null__的"strace"输出:

https://gist.github.com/tetsu-koba/1522515

在 Linux 设备文件下有一个 33 位 (?) 数字,用于标识设备。(至少在旧的Linux版本下)您可以在/dev中删除一些文件,当您知道33位数字时,您可以恢复它甚至在另一个目录中创建它(!)!(因此,您可以删除设备/dev/sda2并创建设备(而不是文件!/home/myuser/sda2改为。

上面链接中的跟踪显示以下三行:

mknod("/dev/__null__", S_IFCHR|0600, makedev(1, 3)) = 0
open("/dev/__null__", O_RDWR|O_LARGEFILE) = 3
unlink("/dev/__null__") = 0

这些行将创建设备文件/dev/__null__(使用 33 位数字标识/dev/null)。然后它会打开该文件,然后再次删除该文件。

也许这样做是因为该工具应该能够在存在设备文件"/dev/null"的 Linux 安装上运行(在这种情况下,不应覆盖该文件)和在缺少该文件的安装上运行(在这种情况下,必须使用已知的 33 位数字创建替换文件)。

正如其他人指出的那样,这只是告诉它是"空设备",而不是一个名为"null"的常规文件。null应该像信息接收器一样,而不是像将数据转储到的普通文件。希望这有帮助。

最新更新