mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-12-15 02:41:59 +00:00
45 lines
1.0 KiB
C
45 lines
1.0 KiB
C
|
#include <errno.h>
|
||
|
#include <fcntl.h>
|
||
|
#include <stdint.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
#include <time.h>
|
||
|
#include <unistd.h>
|
||
|
|
||
|
/* This assumes that a check for the
|
||
|
template size has already been made */
|
||
|
static char * __randname(char * template)
|
||
|
{
|
||
|
int i;
|
||
|
struct timespec ts;
|
||
|
unsigned long r;
|
||
|
|
||
|
clock_gettime(CLOCK_REALTIME, &ts);
|
||
|
r = (ts.tv_nsec * 65537) ^ ((((intptr_t)(&ts)) / 16) + ((intptr_t)template));
|
||
|
for (i = 0; i < 6; i++, r >>= 5)
|
||
|
template[i] = 'A' + (r & 15) + (r & 16) * 2;
|
||
|
|
||
|
return template;
|
||
|
}
|
||
|
|
||
|
int mkstemps(char * template, int len)
|
||
|
{
|
||
|
size_t l = strlen(template);
|
||
|
if (l < 6 || len > l - 6 || memcmp(template + l - len - 6, "XXXXXX", 6))
|
||
|
{
|
||
|
errno = EINVAL;
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
int fd, retries = 100;
|
||
|
do
|
||
|
{
|
||
|
__randname(template + l - len - 6);
|
||
|
if ((fd = open(template, O_RDWR | O_CREAT | O_EXCL, 0600)) >= 0)
|
||
|
return fd;
|
||
|
} while (--retries && errno == EEXIST);
|
||
|
|
||
|
memcpy(template + l - len - 6, "XXXXXX", 6);
|
||
|
return -1;
|
||
|
}
|