]>
git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blob - tools/perf/util/data.c
1 #include <linux/compiler.h>
2 #include <linux/kernel.h>
15 #define O_CLOEXEC 0x400000
16 #elif defined(__alpha__) || defined(__hppa__)
17 #define O_CLOEXEC 010000000
19 #define O_CLOEXEC 02000000
23 static bool check_pipe(struct perf_data_file
*file
)
27 int fd
= perf_data_file__is_read(file
) ?
28 STDIN_FILENO
: STDOUT_FILENO
;
31 if (!fstat(fd
, &st
) && S_ISFIFO(st
.st_mode
))
34 if (!strcmp(file
->path
, "-"))
41 return file
->is_pipe
= is_pipe
;
44 static int check_backup(struct perf_data_file
*file
)
48 if (!stat(file
->path
, &st
) && st
.st_size
) {
49 /* TODO check errors properly */
50 char oldname
[PATH_MAX
];
51 snprintf(oldname
, sizeof(oldname
), "%s.old",
54 rename(file
->path
, oldname
);
60 static int open_file_read(struct perf_data_file
*file
)
64 char sbuf
[STRERR_BUFSIZE
];
66 fd
= open(file
->path
, O_RDONLY
);
70 pr_err("failed to open %s: %s", file
->path
,
71 str_error_r(err
, sbuf
, sizeof(sbuf
)));
72 if (err
== ENOENT
&& !strcmp(file
->path
, "perf.data"))
73 pr_err(" (try 'perf record' first)");
78 if (fstat(fd
, &st
) < 0)
81 if (!file
->force
&& st
.st_uid
&& (st
.st_uid
!= geteuid())) {
82 pr_err("File %s not owned by current user or root (use -f to override)\n",
88 pr_info("zero-sized file (%s), nothing to do!\n",
93 file
->size
= st
.st_size
;
101 static int open_file_write(struct perf_data_file
*file
)
104 char sbuf
[STRERR_BUFSIZE
];
106 if (check_backup(file
))
109 fd
= open(file
->path
, O_CREAT
|O_RDWR
|O_TRUNC
|O_CLOEXEC
,
113 pr_err("failed to open %s : %s\n", file
->path
,
114 str_error_r(errno
, sbuf
, sizeof(sbuf
)));
119 static int open_file(struct perf_data_file
*file
)
123 fd
= perf_data_file__is_read(file
) ?
124 open_file_read(file
) : open_file_write(file
);
127 return fd
< 0 ? -1 : 0;
130 int perf_data_file__open(struct perf_data_file
*file
)
132 if (check_pipe(file
))
136 file
->path
= "perf.data";
138 return open_file(file
);
141 void perf_data_file__close(struct perf_data_file
*file
)
146 ssize_t
perf_data_file__write(struct perf_data_file
*file
,
147 void *buf
, size_t size
)
149 return writen(file
->fd
, buf
, size
);
152 int perf_data_file__switch(struct perf_data_file
*file
,
154 size_t pos
, bool at_exit
)
159 if (check_pipe(file
))
161 if (perf_data_file__is_read(file
))
164 if (asprintf(&new_filepath
, "%s.%s", file
->path
, postfix
) < 0)
168 * Only fire a warning, don't return error, continue fill
171 if (rename(file
->path
, new_filepath
))
172 pr_warning("Failed to rename %s to %s\n", file
->path
, new_filepath
);
176 ret
= perf_data_file__open(file
);
180 if (lseek(file
->fd
, pos
, SEEK_SET
) == (off_t
)-1) {
182 pr_debug("Failed to lseek to %zu: %s",
183 pos
, strerror(errno
));