我该如何抑制gcc链接器的以下警告:
警告:使用'mktemp'很危险,最好使用'mkstemp'
我知道使用mkstemp()
更好,但由于某些原因,我必须使用mktemp()
函数。
我该如何抑制gcc链接器的以下警告:
警告:使用'mktemp'很危险,最好使用'mkstemp'
我知道使用mkstemp()
更好,但由于某些原因,我必须使用mktemp()
函数。
我猜您需要这个路径,因为您将其传递给一个只接受路径名作为参数而不是文件描述符或FILE
指针的库。如果是这样,您可以使用mkdtemp
创建一个临时目录,并将文件放置在其中,实际名称并不重要,因为由于目录已经独特,所以路径已经是唯一的。
如果您必须使用 mktemp
,那么除了从 libc.so.6 中删除使用 mktemp
的部分之外,您无法做任何事情来抑制该警告。
为什么您必须使用 mktemp
?
有两件事情:
mktemp
不是标准函数。.gnu.warning.mktemp
部分实现的特殊警告。如果确实需要向磁盘写入,请使用本地操作系统 API。或者使用建议的 mkstemp()
函数。
使用mkstemp
:
int fd = mkstemp(template);
调用此函数后,template
将被实际文件名替换。您将获得文件描述符和文件路径。
如果您正在静态链接运行时,则另一个选择是编写自己的mktemp
版本在对象文件中。 链接器应该优先使用您的版本而不是运行时版本。
编辑:感谢Jason Coco指出我对mktemp
及其相关内容的重大误解。现在这个问题比较容易解决。由于链接器将首选对象文件中的版本,因此您只需要根据mkstemp
编写mktemp
即可。
唯一的困难在于清除mkstemp
返回给您的文件描述符并使所有内容都线程安全。 如果您可以限制需要多少临时文件,可以使用描述符的静态数组和atexit
注册函数进行清理。 如果不行,只需改用链接列表。
mktemp
经常被错误使用,当一个人想要创建一个临时名称而不实际创建一个tmp文件时,就像mkstemp
会做的那样。也许你想将这样的名称传递给sem_open
或shm_open
,并且你非常清楚O_EXCL标志。有很多可能的用途,当你想要创建一个具有随机名称的对象,并且该对象不是一个tmp文件。
然而,即使在这种情况下,真的不应该使用mktemp
。这是因为它检查生成的名称是否已存在文件,如果存在这样的文件,它会生成另一个名称,依此类推,在一个循环中。这真的不是你想要的,特别是如果你最终不打算创建这样一个文件。
mktemp
警告。我只是从glibc源代码中提取了mktemp
生成器代码,并添加了%P
修饰符处理,该修饰符将pid添加到模板中:
https://github.com/dosemu2/dosemu2/blob/devel/src/base/misc/utilities.c#L1103
您可以将该代码用作示例,或者编写自己的代码。我相信上述建议足以使您自己的mktemp
类似函数的使用安全可靠。但这只是我的个人意见。
shm_open()
和sem_open()
语义的原因之一 - 这些函数容易受到基于TOCTOU的竞态条件和基于文件名的漏洞利用的影响。 - Andrew Henleshm_open()
和sem_open()
语义的原因之一 - 这些函数容易受到基于TOCTOU的竞争条件和基于文件名的攻击的影响。 - undefined