perf pmu: Factor out scale conversion code
Move the scale factor parsing code to an own function to reuse it in an upcoming patch. v2: Return error in case strdup returns NULL. Signed-off-by: Andi Kleen <ak@linux.intel.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Link: http://lkml.kernel.org/r/20170103150833.6694-2-andi@firstfloor.org [ Keep returning -ENOMEM when strdup() fails in perf_pmu__parse_scale()/convert_scale() ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
5b485629ba
commit
d02fc6bcd5
@ -94,6 +94,43 @@ static int pmu_format(const char *name, struct list_head *format)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int convert_scale(const char *scale, char **end, double *sval)
|
||||
{
|
||||
char *lc;
|
||||
int ret = 0;
|
||||
|
||||
/*
|
||||
* save current locale
|
||||
*/
|
||||
lc = setlocale(LC_NUMERIC, NULL);
|
||||
|
||||
/*
|
||||
* The lc string may be allocated in static storage,
|
||||
* so get a dynamic copy to make it survive setlocale
|
||||
* call below.
|
||||
*/
|
||||
lc = strdup(lc);
|
||||
if (!lc) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* force to C locale to ensure kernel
|
||||
* scale string is converted correctly.
|
||||
* kernel uses default C locale.
|
||||
*/
|
||||
setlocale(LC_NUMERIC, "C");
|
||||
|
||||
*sval = strtod(scale, end);
|
||||
|
||||
out:
|
||||
/* restore locale */
|
||||
setlocale(LC_NUMERIC, lc);
|
||||
free(lc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *name)
|
||||
{
|
||||
struct stat st;
|
||||
@ -101,7 +138,6 @@ static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *
|
||||
char scale[128];
|
||||
int fd, ret = -1;
|
||||
char path[PATH_MAX];
|
||||
char *lc;
|
||||
|
||||
snprintf(path, PATH_MAX, "%s/%s.scale", dir, name);
|
||||
|
||||
@ -121,37 +157,7 @@ static int perf_pmu__parse_scale(struct perf_pmu_alias *alias, char *dir, char *
|
||||
else
|
||||
scale[sret] = '\0';
|
||||
|
||||
/*
|
||||
* save current locale
|
||||
*/
|
||||
lc = setlocale(LC_NUMERIC, NULL);
|
||||
|
||||
/*
|
||||
* The lc string may be allocated in static storage,
|
||||
* so get a dynamic copy to make it survive setlocale
|
||||
* call below.
|
||||
*/
|
||||
lc = strdup(lc);
|
||||
if (!lc) {
|
||||
ret = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* force to C locale to ensure kernel
|
||||
* scale string is converted correctly.
|
||||
* kernel uses default C locale.
|
||||
*/
|
||||
setlocale(LC_NUMERIC, "C");
|
||||
|
||||
alias->scale = strtod(scale, NULL);
|
||||
|
||||
/* restore locale */
|
||||
setlocale(LC_NUMERIC, lc);
|
||||
|
||||
free(lc);
|
||||
|
||||
ret = 0;
|
||||
ret = convert_scale(scale, NULL, &alias->scale);
|
||||
error:
|
||||
close(fd);
|
||||
return ret;
|
||||
|
Loading…
Reference in New Issue
Block a user