diff options
Diffstat (limited to 'tools/perf/util/session.c')
-rw-r--r-- | tools/perf/util/session.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c new file mode 100644 index 000000000000..707ce1cb1621 --- /dev/null +++ b/tools/perf/util/session.c | |||
@@ -0,0 +1,80 @@ | |||
1 | #include <linux/kernel.h> | ||
2 | |||
3 | #include <unistd.h> | ||
4 | #include <sys/types.h> | ||
5 | |||
6 | #include "session.h" | ||
7 | #include "util.h" | ||
8 | |||
9 | static int perf_session__open(struct perf_session *self, bool force) | ||
10 | { | ||
11 | struct stat input_stat; | ||
12 | |||
13 | self->fd = open(self->filename, O_RDONLY); | ||
14 | if (self->fd < 0) { | ||
15 | pr_err("failed to open file: %s", self->filename); | ||
16 | if (!strcmp(self->filename, "perf.data")) | ||
17 | pr_err(" (try 'perf record' first)"); | ||
18 | pr_err("\n"); | ||
19 | return -errno; | ||
20 | } | ||
21 | |||
22 | if (fstat(self->fd, &input_stat) < 0) | ||
23 | goto out_close; | ||
24 | |||
25 | if (!force && input_stat.st_uid && (input_stat.st_uid != geteuid())) { | ||
26 | pr_err("file %s not owned by current user or root\n", | ||
27 | self->filename); | ||
28 | goto out_close; | ||
29 | } | ||
30 | |||
31 | if (!input_stat.st_size) { | ||
32 | pr_info("zero-sized file (%s), nothing to do!\n", | ||
33 | self->filename); | ||
34 | goto out_close; | ||
35 | } | ||
36 | |||
37 | if (perf_header__read(&self->header, self->fd) < 0) { | ||
38 | pr_err("incompatible file format"); | ||
39 | goto out_close; | ||
40 | } | ||
41 | |||
42 | self->size = input_stat.st_size; | ||
43 | return 0; | ||
44 | |||
45 | out_close: | ||
46 | close(self->fd); | ||
47 | self->fd = -1; | ||
48 | return -1; | ||
49 | } | ||
50 | |||
51 | struct perf_session *perf_session__new(const char *filename, int mode, bool force) | ||
52 | { | ||
53 | size_t len = strlen(filename) + 1; | ||
54 | struct perf_session *self = zalloc(sizeof(*self) + len); | ||
55 | |||
56 | if (self == NULL) | ||
57 | goto out; | ||
58 | |||
59 | if (perf_header__init(&self->header) < 0) | ||
60 | goto out_delete; | ||
61 | |||
62 | memcpy(self->filename, filename, len); | ||
63 | |||
64 | if (mode == O_RDONLY && perf_session__open(self, force) < 0) { | ||
65 | perf_session__delete(self); | ||
66 | self = NULL; | ||
67 | } | ||
68 | out: | ||
69 | return self; | ||
70 | out_delete: | ||
71 | free(self); | ||
72 | return NULL; | ||
73 | } | ||
74 | |||
75 | void perf_session__delete(struct perf_session *self) | ||
76 | { | ||
77 | perf_header__exit(&self->header); | ||
78 | close(self->fd); | ||
79 | free(self); | ||
80 | } | ||