在 c 文件名的开头和结尾之后使用双下划线 ( __ ) 的目的是什么?
What is the purpose of using double underscore ( __ ) before the start and after the end of an file name in c?
我正在研究 android 内核作为初学者。我可以通过 adb 使用 dmesg
命令读取 system/core/init/init.c
函数 main()
内的宏 ERROR()
抛出的消息。我观察到在 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
的 link
正如其他人指出的那样,这只是告诉它是 "null device",而不是一个名为 "null" 的常规文件。 <strong>null</strong>
应该像信息接收器一样工作,而不是像将数据转储到的普通文件。希望这有帮助。
我不知道答案,但我有一个想法:
下一页显示了 "strace" 输出,其中使用了 /dev/__null__
:
https://gist.github.com/tetsu-koba/1522515
在 Linux 下,设备文件有一个 33 位 (?) 数字来标识设备。 (至少在旧的 Linux 版本下)你可以删除 /dev
中的一些文件,当你知道 33 位数字时,你可以恢复它甚至在另一个目录 (!) 中创建它! (因此您可以删除设备 /dev/sda2
并创建设备(不是文件!)/home/myuser/sda2
。)
上面link中的跟踪显示以下三行:
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 位数字创建替换文件)。
在C语言中,开始前、结束后或两者都使用双下划线没有特殊目的。从C的角度来看,文件名只是一个字符串,操作系统可以随意解释它选择的方式。从Linux的角度来看,同样适用。文件名中的下划线只是字符。它们与字母 b
和 t
.
没有区别对待
如果我猜对了并且我正在阅读 the same file as you(link 到您正在阅读的源代码可能是个好主意)那么应该很明显代码是什么在你提到的那个之后的线上做。接下来的几行是:
if (mknod(name, S_IFCHR | 0600, (1 << 8) | 3) == 0) {
fd = open(name, O_RDWR);
unlink(name);
创建空设备,然后打开并立即再次删除。
我怀疑这样做是为了让程序可以 运行 在不访问根文件系统的情况下仍然能够打开 /dev/null
.
的等效项
我正在研究 android 内核作为初学者。我可以通过 adb 使用 dmesg
命令读取 system/core/init/init.c
函数 main()
内的宏 ERROR()
抛出的消息。我观察到在 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
的 link正如其他人指出的那样,这只是告诉它是 "null device",而不是一个名为 "null" 的常规文件。 <strong>null</strong>
应该像信息接收器一样工作,而不是像将数据转储到的普通文件。希望这有帮助。
我不知道答案,但我有一个想法:
下一页显示了 "strace" 输出,其中使用了 /dev/__null__
:
https://gist.github.com/tetsu-koba/1522515
在 Linux 下,设备文件有一个 33 位 (?) 数字来标识设备。 (至少在旧的 Linux 版本下)你可以删除 /dev
中的一些文件,当你知道 33 位数字时,你可以恢复它甚至在另一个目录 (!) 中创建它! (因此您可以删除设备 /dev/sda2
并创建设备(不是文件!)/home/myuser/sda2
。)
上面link中的跟踪显示以下三行:
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 位数字创建替换文件)。
在C语言中,开始前、结束后或两者都使用双下划线没有特殊目的。从C的角度来看,文件名只是一个字符串,操作系统可以随意解释它选择的方式。从Linux的角度来看,同样适用。文件名中的下划线只是字符。它们与字母 b
和 t
.
如果我猜对了并且我正在阅读 the same file as you(link 到您正在阅读的源代码可能是个好主意)那么应该很明显代码是什么在你提到的那个之后的线上做。接下来的几行是:
if (mknod(name, S_IFCHR | 0600, (1 << 8) | 3) == 0) {
fd = open(name, O_RDWR);
unlink(name);
创建空设备,然后打开并立即再次删除。
我怀疑这样做是为了让程序可以 运行 在不访问根文件系统的情况下仍然能够打开 /dev/null
.