winegcc: Produce deterministic temporary file names

Add and use xorshift* pseudo random generator.
Replac mkstemps function with it.

Signed-off-by: Marko Semet <marko@marko10-000.de>
feature/deterministic
Marko Semet 2020-06-20 15:48:55 +02:00
parent e80df2d2d5
commit b072c8a345
3 changed files with 102 additions and 2 deletions

View File

@ -384,3 +384,96 @@ int spawn(const strarray* prefix, const strarray* args, int ignore_errors)
strarray_free(arr);
return status;
}
/* xorshift* random generator. Source: https://en.wikipedia.org/wiki/Xorshift#xorshift* */
static uint64_t pseudorandom_state = 1;
extern char **environ;
uint64_t pseudorandom(uint64_t add_to_state)
{
uint64_t tmp = pseudorandom_state + add_to_state;
tmp ^= tmp >> 12;
tmp ^= tmp << 25;
tmp ^= tmp >> 27;
pseudorandom_state = tmp;
return tmp * UINT64_C(0x2545F4914F6CDD1D);
}
char pseudorandom_char(void)
{
char tmp = (char) (pseudorandom(0) % 62);
if (tmp < 10)
{
return '0' + tmp;
}
else if (tmp < 36)
{
return 'A' + (tmp - 10);
}
else
{
return 'a' + (tmp - 36);
}
}
int pseudorandom_tempfile(char* file)
{
/* replaces Xs */
for (char* tmp = file; (*tmp) != 0; tmp++)
{
if ((*tmp) == 'X')
{
(*tmp) = pseudorandom_char();
}
}
/* try to open file */
return open(file, O_CREAT | O_EXCL | O_RDWR, 0600);
}
void init_random_generator(int argc, char **argv)
{
/* process environment */
{
/* copy environment variables and sort them */
char **tmp_envs;
unsigned int counter = 0;
for (const char **env = environ; (*env) != 0; env++, counter++) {}
tmp_envs = (char**) malloc(sizeof(char*) * counter);
for (unsigned int i = 0; i < counter; i++)
{
size_t length = strlen(environ[i]) + 1;
char* tmp = malloc(length);
memcpy(tmp, environ[i], length);
tmp_envs[i] = tmp;
}
qsort(tmp_envs, counter, sizeof(char*), (int(*)(const void*, const void*)) &strcmp);
/* add sorted environment to random generator */
for (unsigned int i = 0; i < counter; i++)
{
size_t j_max = strlen(tmp_envs[i]);
for (size_t j = 0; j < j_max; j++)
{
pseudorandom(tmp_envs[i][j]);
}
}
/* free temp environment */
for (unsigned int i = 0; i < counter; i++)
{
free(tmp_envs[i]);
}
free(tmp_envs);
}
/* process argv */
for (int i = 0; i < argc; i++)
{
size_t j_max = strlen(argv[i]);
for (size_t j = 0; j < j_max; j++)
{
pseudorandom(argv[i][j]);
}
}
}

View File

@ -25,6 +25,8 @@
#define __attribute__(X)
#endif
#include <stdint.h>
#ifndef DECLSPEC_NORETURN
# if defined(_MSC_VER) && (_MSC_VER >= 1200) && !defined(MIDL_PASS)
# define DECLSPEC_NORETURN __declspec(noreturn)
@ -90,3 +92,8 @@ const char *find_binary( const strarray* prefix, const char *name );
int spawn(const strarray* prefix, const strarray* arr, int ignore_errors);
extern int verbose;
uint64_t pseudorandom(uint64_t add_to_state);
char pseudorandom_char(void);
int pseudorandom_tempfile(char* file);
void init_random_generator(int argc, char **argv);

View File

@ -299,7 +299,7 @@ static char* get_temp_file(const char* prefix, const char* suffix)
/* block signals while manipulating the temp files list */
sigprocmask( SIG_BLOCK, &signal_mask, &old_set );
#endif
fd = mkstemps( tmp, strlen(suffix) );
fd = pseudorandom_tempfile(tmp);
if (fd == -1)
{
/* could not create it in current directory, try in TMPDIR */
@ -308,7 +308,7 @@ static char* get_temp_file(const char* prefix, const char* suffix)
free(tmp);
if (!(tmpdir = getenv("TMPDIR"))) tmpdir = "/tmp";
tmp = strmake("%s/%s-XXXXXX%s", tmpdir, prefix, suffix);
fd = mkstemps( tmp, strlen(suffix) );
fd = pseudorandom_tempfile(tmp);
if (fd == -1) error( "could not create temp file\n" );
}
close( fd );