mkstemp() 是如何工作的?

How mkstemp() actually works?

我对mkstemp()函数的工作过程感到困惑。

mkstemp函数的man页面中,据说该函数生成唯一名称并使用该名称创建文件。

我认为有可能当 mkstemp() 在目录中检查该文件名并在实际创建该文件之前发现它是唯一的时,另一个程序可以创建具有完全相同名称的文件(尽管有可能非常低,但理论上是可能的)。尽管它将无法创建文件,因为它使用 O_EXCL 标志。因此,它必须再次检查新文件名并创建它。 这是 mkstemp() 工作的实际过程吗?

因此,我认为检查文件名和实际创建文件这两个过程都不​​是自动完成的。 (我可能错了)

使用POSIX系统

How mkstemp() actually works?

源代码是算法的文字描述。进行一项实施并检查它。

https://github.com/lattera/glibc/blob/master/misc/mkstemp.c -> https://github.com/lattera/glibc/blob/master/sysdeps/posix/tempname.c

所以没有“检查”,文件从一开始就用 O_CREAT | O_EXCL 打开,所以创建和检查是一起完成的。有关 open 标志的说明,请参阅 https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html

(although chances are very low, but it is possible theoretically)

不,这是不可能的(即使在理论上),因为 mkstemp() 用于创建文件的 open() 系统调用保证没有两个进程可以使用 [=12= 创建相同的文件] 和 O_EXCL 同时。当内核创建文件时,目录 inode 被锁定(因此,不允许同时在该目录中创建任何其他文件),这保证两个 open()s 将被序列化(第一个,或者其他,但不是同时)这意味着当第二个进程有机会创建文件时, open() 调用失败,因为该文件已经被另一个进程创建。为了尽量减少这种情况,该函数通常使用进程的 pid 作为名称的一部分,因此两个进程不能同时生成相同的文件名,因为它们具有不同的进程 ID)mkstemp() 将重试系统调用可能是一个不同的名字,或者只是失败。