#include <string.h>
#include <errno.h>
#include <limits.h>
+#include <stdlib.h>
#include "parse.h"
#include "debug.h"
{
struct fio_option *o1, *o2;
char *s1, *s2, *foo;
- int ret;
+ int prio1, prio2;
s1 = strdup(*((char **) p1));
s2 = strdup(*((char **) p2));
o1 = get_option(s1, fio_options, &foo);
o2 = get_option(s2, fio_options, &foo);
-
- if ((!o1 && o2) || (o1 && !o2))
- ret = 0;
- else
- ret = o2->prio - o1->prio;
+
+ prio1 = prio2 = 0;
+ if (o1)
+ prio1 = o1->prio;
+ if (o2)
+ prio2 = o2->prio;
free(s1);
free(s2);
- return ret;
+ return prio2 - prio1;
}
void sort_options(char **opts, struct fio_option *options, int num_opts)
return 1;
}
+/*
+ * Return a copy of the input string with substrings of the form ${VARNAME}
+ * substituted with the value of the environment variable VARNAME. The
+ * substitution always occurs, even if VARNAME is empty or the corresponding
+ * environment variable undefined.
+ */
+static char *option_dup_subs(const char *opt)
+{
+ char out[OPT_LEN_MAX+1];
+ char in[OPT_LEN_MAX+1];
+ char *outptr = out;
+ char *inptr = in;
+ char *ch1, *ch2, *env;
+ ssize_t nchr = OPT_LEN_MAX;
+ size_t envlen;
+
+ in[OPT_LEN_MAX] = '\0';
+ strncpy(in, opt, OPT_LEN_MAX);
+
+ while (*inptr && nchr > 0) {
+ if (inptr[0] == '$' && inptr[1] == '{') {
+ ch2 = strchr(inptr, '}');
+ if (ch2 && inptr+1 < ch2) {
+ ch1 = inptr+2;
+ inptr = ch2+1;
+ *ch2 = '\0';
+
+ env = getenv(ch1);
+ if (env) {
+ envlen = strlen(env);
+ if (envlen <= nchr) {
+ memcpy(outptr, env, envlen);
+ outptr += envlen;
+ nchr -= envlen;
+ }
+ }
+
+ continue;
+ }
+ }
+
+ *outptr++ = *inptr++;
+ --nchr;
+ }
+
+ *outptr = '\0';
+ return strdup(out);
+}
+
int parse_option(const char *opt, struct fio_option *options, void *data)
{
struct fio_option *o;
char *post, *tmp;
- tmp = strdup(opt);
+ tmp = option_dup_subs(opt);
o = get_option(tmp, options, &post);
if (!o) {