summaryrefslogtreecommitdiff
path: root/tools/perf/util/data.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/data.c')
-rw-r--r--tools/perf/util/data.c99
1 files changed, 67 insertions, 32 deletions
diff --git a/tools/perf/util/data.c b/tools/perf/util/data.c
index 14fa83dae71a..94dc534a7386 100644
--- a/tools/perf/util/data.c
+++ b/tools/perf/util/data.c
@@ -20,18 +20,33 @@
#include "rlimit.h"
#include <internal/lib.h>
-static void close_dir(struct perf_data_file *files, int nr)
+static void perf_data_file__close(struct perf_data_file *file)
{
- while (--nr >= 0) {
- close(files[nr].fd);
- zfree(&files[nr].path);
+ if (file->use_stdio) {
+ if (file->fptr) {
+ fclose(file->fptr);
+ file->fptr = NULL;
+ }
+ } else {
+ close(file->fd);
+ file->fd = -1;
}
+ zfree(&file->path);
+}
+
+static void close_dir(struct perf_data_file *files, int nr)
+{
+ while (--nr >= 0)
+ perf_data_file__close(&files[nr]);
+
free(files);
}
void perf_data__close_dir(struct perf_data *data)
{
close_dir(data->dir.files, data->dir.nr);
+ data->dir.files = NULL;
+ data->dir.nr = 0;
}
int perf_data__create_dir(struct perf_data *data, int nr)
@@ -132,16 +147,21 @@ int perf_data__open_dir(struct perf_data *data)
files = file;
file = &files[nr++];
- file->path = strdup(path);
+ *file = (struct perf_data_file){
+ .path = strdup(path),
+ .fd = -1,
+ .size = st.st_size,
+ .use_stdio = false,
+ };
if (!file->path)
goto out_err;
ret = open(file->path, O_RDONLY);
- if (ret < 0)
+ if (ret < 0) {
+ ret = -errno;
goto out_err;
-
+ }
file->fd = ret;
- file->size = st.st_size;
}
closedir(dir);
@@ -174,7 +194,7 @@ static bool check_pipe(struct perf_data *data)
}
if (is_pipe) {
- if (data->use_stdio) {
+ if (data->file.use_stdio) {
const char *mode;
mode = perf_data__is_read(data) ? "r" : "w";
@@ -182,7 +202,7 @@ static bool check_pipe(struct perf_data *data)
if (data->file.fptr == NULL) {
data->file.fd = fd;
- data->use_stdio = false;
+ data->file.use_stdio = false;
}
/*
@@ -344,7 +364,7 @@ int perf_data__open(struct perf_data *data)
return 0;
/* currently it allows stdio for pipe only */
- data->use_stdio = false;
+ data->file.use_stdio = false;
if (!data->path)
data->path = "perf.data";
@@ -364,41 +384,57 @@ void perf_data__close(struct perf_data *data)
if (perf_data__is_dir(data))
perf_data__close_dir(data);
- zfree(&data->file.path);
-
- if (data->use_stdio)
- fclose(data->file.fptr);
- else
- close(data->file.fd);
+ perf_data_file__close(&data->file);
}
-ssize_t perf_data__read(struct perf_data *data, void *buf, size_t size)
+static ssize_t perf_data_file__read(struct perf_data_file *file, void *buf, size_t size)
{
- if (data->use_stdio) {
- if (fread(buf, size, 1, data->file.fptr) == 1)
+ if (file->use_stdio) {
+ if (fread(buf, size, 1, file->fptr) == 1)
return size;
- return feof(data->file.fptr) ? 0 : -1;
+ return feof(file->fptr) ? 0 : -1;
}
- return readn(data->file.fd, buf, size);
+ return readn(file->fd, buf, size);
+}
+
+ssize_t perf_data__read(struct perf_data *data, void *buf, size_t size)
+{
+ return perf_data_file__read(&data->file, buf, size);
}
ssize_t perf_data_file__write(struct perf_data_file *file,
void *buf, size_t size)
{
+ if (file->use_stdio) {
+ if (fwrite(buf, size, /*nmemb=*/1, file->fptr) == 1)
+ return size;
+ return -1;
+ }
return writen(file->fd, buf, size);
}
ssize_t perf_data__write(struct perf_data *data,
void *buf, size_t size)
{
- if (data->use_stdio) {
- if (fwrite(buf, size, 1, data->file.fptr) == 1)
- return size;
- return -1;
- }
return perf_data_file__write(&data->file, buf, size);
}
+off_t perf_data_file__seek(struct perf_data_file *file, off_t offset, int whence)
+{
+ if (file->use_stdio) {
+ off_t res = fseeko(file->fptr, offset, whence);
+
+ return res < 0 ? -1 : ftello(file->fptr);
+ }
+ return lseek(file->fd, offset, whence);
+}
+
+off_t perf_data__seek(struct perf_data *data, off_t offset, int whence)
+{
+ /* Note, a pipe fd will fail with -1 with errno of ESPIPE. */
+ return perf_data_file__seek(&data->file, offset, whence);
+}
+
int perf_data__switch(struct perf_data *data,
const char *postfix,
size_t pos, bool at_exit,
@@ -420,19 +456,18 @@ int perf_data__switch(struct perf_data *data,
pr_warning("Failed to rename %s to %s\n", data->path, *new_filepath);
if (!at_exit) {
- close(data->file.fd);
+ perf_data_file__close(&data->file);
ret = perf_data__open(data);
if (ret < 0)
goto out;
- if (lseek(data->file.fd, pos, SEEK_SET) == (off_t)-1) {
+ if (perf_data__seek(data, pos, SEEK_SET) == (off_t)-1) {
ret = -errno;
- pr_debug("Failed to lseek to %zu: %m\n",
- pos);
+ pr_debug("Failed to seek to %zu: %m", pos);
goto out;
}
}
- ret = data->file.fd;
+ ret = perf_data__fd(data);
out:
return ret;
}