Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | #include <linux/compiler.h> #include <linux/kernel.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <string.h> #include "data.h" #include "util.h" #include "debug.h" static bool check_pipe(struct perf_data_file *file) { struct stat st; bool is_pipe = false; int fd = perf_data_file__is_read(file) ? STDIN_FILENO : STDOUT_FILENO; if (!file->path) { if (!fstat(fd, &st) && S_ISFIFO(st.st_mode)) is_pipe = true; } else { if (!strcmp(file->path, "-")) is_pipe = true; } if (is_pipe) file->fd = fd; return file->is_pipe = is_pipe; } static int check_backup(struct perf_data_file *file) { struct stat st; if (!stat(file->path, &st) && st.st_size) { /* TODO check errors properly */ char oldname[PATH_MAX]; snprintf(oldname, sizeof(oldname), "%s.old", file->path); unlink(oldname); rename(file->path, oldname); } return 0; } static int open_file_read(struct perf_data_file *file) { struct stat st; int fd; char sbuf[STRERR_BUFSIZE]; fd = open(file->path, O_RDONLY); if (fd < 0) { int err = errno; pr_err("failed to open %s: %s", file->path, strerror_r(err, sbuf, sizeof(sbuf))); if (err == ENOENT && !strcmp(file->path, "perf.data")) pr_err(" (try 'perf record' first)"); pr_err("\n"); return -err; } if (fstat(fd, &st) < 0) goto out_close; if (!file->force && st.st_uid && (st.st_uid != geteuid())) { pr_err("File %s not owned by current user or root (use -f to override)\n", file->path); goto out_close; } if (!st.st_size) { pr_info("zero-sized file (%s), nothing to do!\n", file->path); goto out_close; } file->size = st.st_size; return fd; out_close: close(fd); return -1; } static int open_file_write(struct perf_data_file *file) { int fd; char sbuf[STRERR_BUFSIZE]; if (check_backup(file)) return -1; fd = open(file->path, O_CREAT|O_RDWR|O_TRUNC, S_IRUSR|S_IWUSR); if (fd < 0) pr_err("failed to open %s : %s\n", file->path, strerror_r(errno, sbuf, sizeof(sbuf))); return fd; } static int open_file(struct perf_data_file *file) { int fd; fd = perf_data_file__is_read(file) ? open_file_read(file) : open_file_write(file); file->fd = fd; return fd < 0 ? -1 : 0; } int perf_data_file__open(struct perf_data_file *file) { if (check_pipe(file)) return 0; if (!file->path) file->path = "perf.data"; return open_file(file); } void perf_data_file__close(struct perf_data_file *file) { close(file->fd); } ssize_t perf_data_file__write(struct perf_data_file *file, void *buf, size_t size) { return writen(file->fd, buf, size); } |