+static int setup_random_seeds(struct thread_data *td)
+{
+ unsigned long seed;
+ unsigned int i;
+
+ if (!td->o.rand_repeatable && !td->o.rand_seed)
+ return init_random_state(td, td->rand_seeds, sizeof(td->rand_seeds));
+
+ if (!td->o.rand_seed)
+ seed = 0x89;
+ else
+ seed = td->o.rand_seed;
+
+ for (i = 0; i < 4; i++)
+ seed *= 0x9e370001UL;
+
+ for (i = 0; i < FIO_RAND_NR_OFFS; i++) {
+ td->rand_seeds[i] = seed;
+ seed *= 0x9e370001UL;
+ }
+
+ td_fill_rand_seeds(td);
+ return 0;
+}
+
+enum {
+ FPRE_NONE = 0,
+ FPRE_JOBNAME,
+ FPRE_JOBNUM,
+ FPRE_FILENUM
+};
+
+static struct fpre_keyword {
+ const char *keyword;
+ size_t strlen;
+ int key;
+} fpre_keywords[] = {
+ { .keyword = "$jobname", .key = FPRE_JOBNAME, },
+ { .keyword = "$jobnum", .key = FPRE_JOBNUM, },
+ { .keyword = "$filenum", .key = FPRE_FILENUM, },
+ { .keyword = NULL, },
+ };
+
+static char *make_filename(char *buf, struct thread_options *o,
+ const char *jobname, int jobnum, int filenum)
+{
+ struct fpre_keyword *f;
+ char copy[PATH_MAX];
+ size_t dst_left = PATH_MAX - 1;
+
+ if (!o->filename_format || !strlen(o->filename_format)) {
+ sprintf(buf, "%s.%d.%d", jobname, jobnum, filenum);
+ return NULL;
+ }
+
+ for (f = &fpre_keywords[0]; f->keyword; f++)
+ f->strlen = strlen(f->keyword);
+
+ strcpy(buf, o->filename_format);
+ memset(copy, 0, sizeof(copy));
+ for (f = &fpre_keywords[0]; f->keyword; f++) {
+ do {
+ size_t pre_len, post_start = 0;
+ char *str, *dst = copy;
+
+ str = strcasestr(buf, f->keyword);
+ if (!str)
+ break;
+
+ pre_len = str - buf;
+ if (strlen(str) != f->strlen)
+ post_start = pre_len + f->strlen;
+
+ if (pre_len) {
+ strncpy(dst, buf, pre_len);
+ dst += pre_len;
+ dst_left -= pre_len;
+ }
+
+ switch (f->key) {
+ case FPRE_JOBNAME: {
+ int ret;
+
+ ret = snprintf(dst, dst_left, "%s", jobname);
+ if (ret < 0)
+ break;
+ dst += ret;
+ dst_left -= ret;
+ break;
+ }
+ case FPRE_JOBNUM: {
+ int ret;
+
+ ret = snprintf(dst, dst_left, "%d", jobnum);
+ if (ret < 0)
+ break;
+ dst += ret;
+ dst_left -= ret;
+ break;
+ }
+ case FPRE_FILENUM: {
+ int ret;
+
+ ret = snprintf(dst, dst_left, "%d", filenum);
+ if (ret < 0)
+ break;
+ dst += ret;
+ dst_left -= ret;
+ break;
+ }
+ default:
+ assert(0);
+ break;
+ }
+
+ if (post_start)
+ strncpy(dst, buf + post_start, dst_left);
+
+ strcpy(buf, copy);
+ } while (1);
+ }
+
+ return buf;
+}
+
+int parse_dryrun(void)
+{
+ return dump_cmdline || parse_only;
+}
+