mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
91 lines
2.7 KiB
C
Vendored
91 lines
2.7 KiB
C
Vendored
#define _CRT_RAND_S
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <io.h>
|
|
#include <errno.h>
|
|
#include <share.h>
|
|
#include <fcntl.h>
|
|
#include <sys/stat.h>
|
|
#include <limits.h>
|
|
|
|
/*
|
|
The mkstemp() function generates a unique temporary filename from template,
|
|
creates and opens the file, and returns an open file descriptor for the
|
|
file.
|
|
|
|
The template may be any file name with at least six trailing Xs, for example
|
|
/tmp/temp.XXXXXXXX. The trailing Xs are replaced with a unique digit and
|
|
letter combination that makes the file name unique. Since it will be
|
|
modified, template must not be a string constant, but should be declared as
|
|
a character array.
|
|
|
|
The file is created with permissions 0600, that is, read plus write for
|
|
owner only. The returned file descriptor provides both read and write access
|
|
to the file.
|
|
*/
|
|
int __cdecl mkstemp (char *template_name)
|
|
{
|
|
int j, fd, len, index;
|
|
unsigned int i, r;
|
|
|
|
/* These are the (62) characters used in temporary filenames. */
|
|
static const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
|
|
|
/* The last six characters of template must be "XXXXXX" */
|
|
if (template_name == NULL || (len = strlen (template_name)) < 6
|
|
|| memcmp (template_name + (len - 6), "XXXXXX", 6)) {
|
|
errno = EINVAL;
|
|
return -1;
|
|
}
|
|
|
|
/* User may supply more than six trailing Xs */
|
|
for (index = len - 6; index > 0 && template_name[index - 1] == 'X'; index--);
|
|
|
|
/* Like OpenBSD, mkstemp() will try 2 ** 31 combinations before giving up. */
|
|
for (i = 0; i <= INT_MAX; i++) {
|
|
for(j = index; j < len; j++) {
|
|
if (rand_s(&r))
|
|
r = rand();
|
|
template_name[j] = letters[r % 62];
|
|
}
|
|
fd = _sopen(template_name,
|
|
_O_RDWR | _O_CREAT | _O_EXCL | _O_BINARY,
|
|
_SH_DENYNO, _S_IREAD | _S_IWRITE);
|
|
if (fd != -1) return fd;
|
|
if (fd == -1 && errno != EEXIST) return -1;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
#if 0
|
|
int main (int argc, char *argv[])
|
|
{
|
|
int i, fd;
|
|
|
|
for (i = 0; i < 10; i++) {
|
|
char template_name[] = { "temp_XXXXXX" };
|
|
fd = mkstemp (template_name);
|
|
if (fd >= 0) {
|
|
fprintf (stderr, "fd=%d, name=%s\n", fd, template_name);
|
|
_close (fd);
|
|
} else {
|
|
fprintf (stderr, "errno=%d\n", errno);
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < 10; i++) {
|
|
char template_name[] = { "temp_XXXXXXXX" };
|
|
fd = mkstemp (template_name);
|
|
if (fd >= 0) {
|
|
fprintf (stderr, "fd=%d, name=%s\n", fd, template_name);
|
|
_close (fd);
|
|
} else {
|
|
fprintf (stderr, "errno=%d\n", errno);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
#endif
|