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

问题描述:

我正在学习android内核作为初学者。我可以通过使用dmesg命令通过adb读取从函数main()中的宏ERROR()引发的消息system/core/init/init.c。我观察到在调用main(),dmesg内部的函数open_devnull_stdio()后,不再显示ERROR()引发的消息。在c中的文件名开始之前和结束之后使用双下划线(__)的目的是什么?

为了找到原因,我开始挖掘到的open_devnull_stdio()system/core/init/util.c声明,我发现这条线我不明白

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

其实有没有名为__null__内的设备/dev/文件,但有一个叫null文件,我可以用adb pull抓住它,它是一个0字节(空)文件。

那么为什么用双下划线(__)包裹文件名?

这里是链接的util.c

+1

我不知道答案,但你可能想查找/ dev/null。这是一个众所周知的“文件”。 https://en.wikipedia.org/wiki/Null_device –

+0

null设备是一件非常特别的事情。你能举出更多的例子吗? – Yunnosch

在开始之前,结束之后或在C之后都没有特别的目的使用双下划线。从C的角度来看,文件名只是一个字符串,操作系统可以以任何方式*解释它选择。从Linux的角度来看,同样适用。文件名中的下划线只是字符。他们没有区别于字母bt

如果我猜对了,我正在阅读the same file as you(链接到您正在阅读的源代码可能是一个好主意),那么它应该是非常明显的代码之后, 。接下来的行是:

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

它创建空设备然后打开并立即再次删除。

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

+0

谢谢@艺术。是的,这两个功能是一样的。我附上了我提到的文件。 – Yasindu

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

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

下面的页面显示了一个“strace的”输出在使用/dev/__null__

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位数字创建替换文件)。