mkstemp() implementation for win32
mkstemp() implementation for win32
谁能指出我在Win32上实现mkstemp()(C/C++)的代码,或者非常接近的类似代码?
必须是无种族的。
它应该看起来像
#include <windows.h>
#include <io.h>
// port of mkstemp() to win32. race-free.
// behaviour as described in http://linux.die.net/man/3/mkstemp
//
int mkstemp(char *template) {
...
}
您可以使用从wcecompat
库中提取的以下函数(从文件src/stdlib_extras.cpp
/* mkstemp extracted from libc/sysdeps/posix/tempname.c. Copyright
(C) 1991-1999, 2000, 2001, 2006 Free Software Foundation, Inc.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. */
static const char letters[] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
/* Generate a temporary file name based on TMPL. TMPL must match the
rules for mk[s]temp (i.e. end in "XXXXXX"). The name constructed
does not exist at the time of the call to mkstemp. TMPL is
overwritten with the result. */
int
mkstemp (char *tmpl)
{
int len;
char *XXXXXX;
static unsigned long long value;
unsigned long long random_time_bits;
unsigned int count;
int fd = -1;
int save_errno = errno;
/* A lower bound on the number of temporary files to attempt to
generate. The maximum total number of temporary file names that
can exist for a given template is 62**6. It should never be
necessary to try all these combinations. Instead if a reasonable
number of names is tried (we define reasonable as 62**3) fail to
give the system administrator the chance to remove the problems. */
#define ATTEMPTS_MIN (62 * 62 * 62)
/* The number of times to attempt to generate a temporary file. To
conform to POSIX, this must be no smaller than TMP_MAX. */
#if ATTEMPTS_MIN < TMP_MAX
unsigned int attempts = TMP_MAX;
#else
unsigned int attempts = ATTEMPTS_MIN;
#endif
len = strlen (tmpl);
if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
{
errno = EINVAL;
return -1;
}
/* This is where the Xs start. */
XXXXXX = &tmpl[len - 6];
/* Get some more or less random data. */
{
SYSTEMTIME stNow;
FILETIME ftNow;
// get system time
GetSystemTime(&stNow);
stNow.wMilliseconds = 500;
if (!SystemTimeToFileTime(&stNow, &ftNow))
{
errno = -1;
return -1;
}
random_time_bits = (((unsigned long long)ftNow.dwHighDateTime << 32)
| (unsigned long long)ftNow.dwLowDateTime);
}
value += random_time_bits ^ (unsigned long long)GetCurrentThreadId ();
for (count = 0; count < attempts; value += 7777, ++count)
{
unsigned long long v = value;
/* Fill in the random bits. */
XXXXXX[0] = letters[v % 62];
v /= 62;
XXXXXX[1] = letters[v % 62];
v /= 62;
XXXXXX[2] = letters[v % 62];
v /= 62;
XXXXXX[3] = letters[v % 62];
v /= 62;
XXXXXX[4] = letters[v % 62];
v /= 62;
XXXXXX[5] = letters[v % 62];
fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL, _S_IREAD | _S_IWRITE);
if (fd >= 0)
{
errno = save_errno;
return fd;
}
else if (errno != EEXIST)
return -1;
}
/* We got out of the loop because we ran out of combinations to try. */
errno = EEXIST;
return -1;
}
它将O_EXCL
定义为;
#define _O_EXCL 0x0400
#define O_EXCL _O_EXCL
您可以轻松地从中剔除mkstemp支持。
实际上,使用 _mktemp_s() 是一个非常糟糕的主意——在任何一个上下文中只有 26 个可能的文件名候选者,而且,由于要攻击的范围有限,它暴露了 mkstemp() 旨在克服的竞争条件。 然而,另一个提出的解决方案虽然要好得多,但也存在缺陷,因为它在选择替代文件名字符时具有 62 个自由度,而 Windows 文件系统的大小写不区分占用其中的 26 个,因此只剩下 36 个;这具有将选择任何逻辑上可区分的字母字符的概率加权为数字的两倍的效果。
考虑到这一点,我在这里发布了一个MinGW补丁:https://sourceforge.net/p/mingw/bugs/2003/
如果被采用,这将正式将 mkstemp() 和 mkdtemp() 添加到标准的 MinGW 发行版中。
您可以使用 _mktemp_s() 函数或其任何变体:
errno_t _mktemp_s(
char *template,
size_t sizeInChars
);
哪里:
- 模板:文件名模式。
- sizeInChars:缓冲区的大小(以单字节字符表示
_mktemp_s
);宽字符(以_wmktemp_s
为单位),包括空终止符。
成功时返回 0,失败时返回错误代码。请注意,该函数修改template
参数。
相关文章:
- "error: no matching function for call to"构造函数错误
- 表示"accepting anything for this template argument" C++概念的通配符
- 如何在C++中从两个单独的for循环中添加两个数组
- 在Linux for Windows上编译C++代码时出错
- Win32编译器选项和内存分配
- 调用专用模板时出错"no matching function for call to [...]"
- 为什么我的for循环不能正确获取argv
- 为什么我不能在 FOR LOOP 中使用 i/10,C++?
- Arduino:for/while/if在void setup()或void loop()之前?——错误:之前需要不合格
- 在基于范围的for循环中使用结构化绑定声明
- 通过for循环使用用户输入填充列表
- 使用for循环检查数组中的重复项
- 在for循环中使用auto vs decltype(vec.size())来处理字符串的向量
- 为什么 const std::p air<K,V>& 在 std::map 上基于范围的 for 循环不起作用?
- 正在使用for循环创建QScatterSerie
- HwndHost for Windows Form - Win32 / WinForm Interoperability
- 在QT for Windows中使用Win32 API
- "There's no Qt version assigned to this project for platform Win32" - Qt的Visual Studio插件
- Visual Studio 2012 for windows 8未显示win32控制台应用程序选项
- mkstemp() implementation for win32