在创建命名管道时,mkfifo()和mknod()有什么区别?
我尝试搜索,但没有得到满意的答案。
mkfifo()
是标准化和可移植的。通常情况下,使用 mknod()
不是可移植的,这是 POSIX 的一部分(尽管在此答案的早期版本中有相反的说法)。POSIX 规范指出应优先考虑 mkfifo()
。否则,mkfifo()
和 mknod()
创建的 FIFO 没有区别。mknod()
可用于创建除了 FIFO 以外的其他设备类型。它可以创建块设备和字符设备。很久很久以前,mknod()
也用于创建目录——在出现 mkdir()
或 rmdir()
系统调用之前的日子里。创建目录后,您必须使用两次 link()
来创建新目录中的 .
和 ..
条目。(而且您必须具有 root 特权才能使用它,因此 mkdir
和 rmdir
命令是 SUID root 的。)由于这已经不再是游戏的一部分,文件系统现在更加可靠。
参考:Version 7 Unix — 大约在 1979 年。
mknod
手册上写着:“POSIX.1-2001说:‘mknod()
的唯一可移植用途是创建FIFO特殊文件。如果mode
不是S_IFIFO
或dev
不是0,则mknod()
的行为未指定。’”,因此似乎使用S_IFIFO
的mknod
确实是标准的。这在http://pubs.opengroup.org/onlinepubs/9699919799/functions/mknod.html中得到了确认,但有一个警告:“对于制作FIFO特殊文件,应优先使用`mkfifo()`函数。” - Matteo Italiamknod()
确实在POSIX中存在,这让我很惊讶。考虑到已经有了mkfifo()
(以及mkdir()
和rmdir()
),这个函数真的是多余的;我很惊讶它被标准化了。有趣的是,在规范中,该函数用第三个参数的未初始化值进行说明:dev_t dev; int status = mknod("/home/cnd/mod_done", S_IFIFO | S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH, dev);
——dev
没有被显示为初始化。将其设置为0是明智的;第7版手册中也有类似的措辞。 - Jonathan Leffler