From 8e827d35068326950a6781d93aeef33b66d3438b Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 4 Aug 2009 09:51:48 +0200 Subject: [PATCH] Allow ':' in filenames You can now use '\' to escape a colon in a filename. Signed-off-by: Jens Axboe --- HOWTO | 7 +++++-- options.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 3 deletions(-) diff --git a/HOWTO b/HOWTO index dc70ab66..aec00e84 100644 --- a/HOWTO +++ b/HOWTO @@ -243,8 +243,11 @@ filename=str Fio normally makes up a filename based on the job name, can specify a number of files by separating the names with a ':' colon. So if you wanted a job to open /dev/sda and /dev/sdb as the two working files, you would use - filename=/dev/sda:/dev/sdb. '-' is a reserved name, meaning - stdin or stdout. Which of the two depends on the read/write + filename=/dev/sda:/dev/sdb. If the wanted filename does need to + include a colon, then escape that with a '\' character. For + instance, if the filename is "/dev/dsk/foo@3,0:c", then you would + use filename="/dev/dsk/foo@3,0\:c". '-' is a reserved name, + meaning stdin or stdout. Which of the two depends on the read/write direction set. opendir=str Tell fio to recursively add any file it can find in this diff --git a/options.c b/options.c index 6941af0e..b7262a7f 100644 --- a/options.c +++ b/options.c @@ -449,6 +449,52 @@ static int check_dir(struct thread_data *td, char *fname) return 0; } +/* + * Return next file in the string. Files are separated with ':'. If the ':' + * is escaped with a '\', then that ':' is part of the filename and does not + * indicate a new file. + */ +static char *get_next_file_name(char **ptr) +{ + char *str = *ptr; + char *p, *start; + + if (!str || !strlen(str)) + return NULL; + + start = str; + do { + /* + * No colon, we are done + */ + p = strchr(str, ':'); + if (!p) { + *ptr = NULL; + break; + } + + /* + * We got a colon, but it's the first character. Skip and + * continue + */ + if (p == start) { + str = ++start; + continue; + } + + if (*(p - 1) != '\\') { + *p = '\0'; + *ptr = p + 1; + break; + } + + memmove(p - 1, p, strlen(p) + 1); + str = p; + } while (1); + + return start; +} + static int str_filename_cb(void *data, const char *input) { struct thread_data *td = data; @@ -462,7 +508,7 @@ static int str_filename_cb(void *data, const char *input) if (!td->files_index) td->o.nr_files = 0; - while ((fname = strsep(&str, ":")) != NULL) { + while ((fname = get_next_file_name(&str)) != NULL) { if (!strlen(fname)) break; if (check_dir(td, fname)) { -- 2.25.1