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, 52 bool force) 53 { 54 size_t len = strlen(filename) + 1; 55 struct perf_session *self = zalloc(sizeof(*self) + len); 56 57 if (self == NULL) 58 goto out; 59 60 if (perf_header__init(&self->header) < 0) 61 goto out_delete; 62 63 memcpy(self->filename, filename, len); 64 65 if (mode == O_RDONLY && perf_session__open(self, force) < 0) { 66 perf_session__delete(self); 67 self = NULL; 68 } 69 out: 70 return self; 71 out_delete: 72 free(self); 73 return NULL; 74 } 75 76 void perf_session__delete(struct perf_session *self) 77 { 78 perf_header__exit(&self->header); 79 close(self->fd); 80 free(self); 81 } 82