C语言 如何在以下代码片段中替换 tmpnam() 的使用



我完全理解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()或其变体之一注册的函数可能有用的地方。

最新更新