forked from Mirrors/wine-wine
winebuild: generate deterministic temp filenames
Using the xorshift* pseudo random generator for the filenames. Signed-off-by: Marko Semet <marko@marko10-000.de>feature/deterministic
parent
1b87584bf5
commit
6c5b40382b
|
@ -27,6 +27,7 @@
|
|||
# error You must include config.h to use this header
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -352,6 +353,11 @@ extern void put_qword( unsigned int val );
|
|||
extern void put_pword( unsigned int val );
|
||||
extern void align_output( unsigned int align );
|
||||
|
||||
extern uint64_t pseudorandom(uint64_t add_to_state);
|
||||
extern char pseudorandom_char(void);
|
||||
extern int pseudorandom_tempfile(char* file);
|
||||
extern void init_random_generator(int argc, char **argv);
|
||||
|
||||
/* global variables */
|
||||
|
||||
extern int current_line;
|
||||
|
|
|
@ -666,6 +666,7 @@ int main(int argc, char **argv)
|
|||
signal( SIGTERM, exit_on_signal );
|
||||
signal( SIGINT, exit_on_signal );
|
||||
|
||||
init_random_generator(argc, argv);
|
||||
argv = parse_options( argc, argv, spec );
|
||||
atexit( cleanup ); /* make sure we remove the output file on exit */
|
||||
|
||||
|
|
|
@ -514,13 +514,13 @@ char *get_temp_file_name( const char *prefix, const char *suffix )
|
|||
strcpy( name + (ext - prefix), ".XXXXXX" );
|
||||
strcat( name, suffix );
|
||||
|
||||
if ((fd = mkstemps( name, strlen(suffix) )) == -1)
|
||||
if ((fd = pseudorandom_tempfile(name)) == -1)
|
||||
{
|
||||
strcpy( name, "/tmp/" );
|
||||
memcpy( name + 5, basename, ext - basename );
|
||||
strcpy( name + 5 + (ext - basename), ".XXXXXX" );
|
||||
strcat( name, suffix );
|
||||
if ((fd = mkstemps( name, strlen(suffix) )) == -1)
|
||||
if ((fd = pseudorandom_tempfile(name)) == -1)
|
||||
fatal_error( "could not generate a temp file\n" );
|
||||
}
|
||||
|
||||
|
@ -1275,3 +1275,96 @@ const char *get_asm_string_section(void)
|
|||
default: return ".section .rodata";
|
||||
}
|
||||
}
|
||||
|
||||
/* 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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue