我询问的原因是我想知道为什么mkstemp()会返回一个文件描述符。如果可以安全地立即关闭描述符,为什么它还要返回一个描述符呢?mkstemp()可以自行关闭它并只给我一个文件名。
在使用mkstemp()
创建文件和重新打开它之间的时间内,对手可能会删除您创建的文件并放置一个符号链接指向完全不同的位置。这是TOCTOU(Time of Check, Time of Use)漏洞,使用mkstemp()
可以大大避免,前提是保持文件描述符处于打开状态。
一旦关闭文件描述符,在足够敌对的环境中所有赌注都没有了。
请注意,即使保持文件描述符打开,对手也可能会删除文件或重命名文件,然后创建自己的文件(符号链接、目录)代替它。文件描述符仍然有效。您可以使用stat()
获取名称信息和fstat()
获取文件描述符信息,如果两者匹配(st_dev
和st_ino
字段),那么您可能仍然没问题。如果它们不同,有人已经在使用该文件——如果您重命名它,您可能正在重命名他们的文件而不是您创建的文件。
虽然mkstemp()
创建的原始文件仍然存在,但名称不会重新生成。通常,连续调用mkstemp()
将创建不同的名称,但是在创建时名称保证是唯一的(请参见open()
的O_EXCL
标志)。
以防万一,您可能会想知道,没有一种方法可以将名称与文件描述符关联起来(没有假设的int flink(int fd, const char *name)
系统调用)。之前在Stack Exchange网站上有一个问题,答案绝对是否定的,并提供了Linux Kernel邮件列表等参考资料。其中一个问题是Is it possible to recreate a file from an opened file descriptor?,但我认为还有一个更详尽的版本的问题。
mkstemp()
可能会两次返回相同的名称;如果它仍然存在,则不会再次返回相同的名称。 - Jonathan Leffler