我完全理解tmpnam
已被弃用,并希望将其从现有文件中阻止我构建项目的函数中删除。但是,由于我不熟悉它并且无法尝试它,因此我不确定如何最好地复制此功能。
if ((myfileName = tmpnam(NULL)) == NULL) { return APP_ERROR }
我在这里阅读了有关 tmpnam 的信息,但我能想到的最好的方法是使用以下内容:
if (tmpnam_r == NULL) { return APP_ERROR }
但是,由于我无法使用tmpnam
进行编译并且不熟悉有问题的代码,因此我对正确捕获原始意图没有信心。
据我所知,这似乎是在测试文件是否存在,如果不存在,则仅返回错误,因为下一步包括将内容复制到myfileName
中,在上述检查之后,它应该可能存在。
tmpnam()
的问题在于它生成的名称是唯一的,并且在返回时不存在,但是当您在调用fopen()
(或open()
(时,不能保证该名称是唯一的。
mkstemp()
函数的主要功能是它创建并打开具有新名称的文件,因此不存在TOCTOU(检查时间,使用时间(漏洞。这减少了安全风险的途径。
设计为使用tmpnam()
的代码通常需要文件名,因此通常不能使用tmpfile()
;它不提供查找文件名的方法。 如果您不需要文件名,那么使用tmpfile()
效果很好,并且是标准 C,因此它被广泛使用。
tmpnam()
和tmpnam_s()
的具体情况很有趣。 尽管tmpnam_s()
避免了一些与字符串相关的问题,但它不会以导致mkstemp()
解决的安全问题的方式改变tmpnam()
的行为。 因此,与尝试使用tmpnam_s()
(或 C11 或 C18 标准附录 K 中的任何其他*_s()
功能(引起的可移植性问题无关,它不会解决导致tmpnam()
被弃用的问题。
您可以安排使用mkstemp()
而不是tmpnam()
并在继续执行其他代码之前关闭文件描述符:
tmpnam(name); // Replace this
int fd = mkstemp(name); // With this…
if (fd >= 0)
close(fd);
它不是很好,但它确实可以确保创建文件,从而减少一点安全漏洞,但不如直接使用文件描述符那么多。 你可以(应该(把它包装到一个函数中。
请注意,mkstemp()
返回文件描述符;如果需要文件流,可以使用fdopen()
从文件描述符创建文件流。 如果失败,您可能希望删除该文件(使用remove()
或unlink()
(。
因此,这为您提供了fmkstemp()
的需求:
#include <stdio.h>
#include <stdlib.h> /* mkstemp() */
#include <unistd.h> /* close() */
extern FILE *fmkstemp(char *name); /* Add to a convenient header file */
FILE *fmkstemp(char *name)
{
int fd = mkstemp(name);
FILE *fp = 0;
if (fd >= 0)
{
fp = fdopen(fd, "w+");
if (fp == 0)
{
close(fd);
unlink(name);
}
}
return(fp);
}
请注意,使用fmkstemp()
后,您可以使用fclose()
关闭文件流(并在后台关闭文件描述符(。
不要忘记在退出之前删除临时文件。 这就是向atexit()
或其变体之一注册的函数可能有用的地方。