1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/compiler.h>
3 #include <linux/kernel.h>
15 static bool check_pipe(struct perf_data
*data
)
19 int fd
= perf_data__is_read(data
) ?
20 STDIN_FILENO
: STDOUT_FILENO
;
22 if (!data
->file
.path
) {
23 if (!fstat(fd
, &st
) && S_ISFIFO(st
.st_mode
))
26 if (!strcmp(data
->file
.path
, "-"))
33 return data
->is_pipe
= is_pipe
;
36 static int check_backup(struct perf_data
*data
)
40 if (!stat(data
->file
.path
, &st
) && st
.st_size
) {
41 /* TODO check errors properly */
42 char oldname
[PATH_MAX
];
43 snprintf(oldname
, sizeof(oldname
), "%s.old",
46 rename(data
->file
.path
, oldname
);
52 static int open_file_read(struct perf_data
*data
)
56 char sbuf
[STRERR_BUFSIZE
];
58 fd
= open(data
->file
.path
, O_RDONLY
);
62 pr_err("failed to open %s: %s", data
->file
.path
,
63 str_error_r(err
, sbuf
, sizeof(sbuf
)));
64 if (err
== ENOENT
&& !strcmp(data
->file
.path
, "perf.data"))
65 pr_err(" (try 'perf record' first)");
70 if (fstat(fd
, &st
) < 0)
73 if (!data
->force
&& st
.st_uid
&& (st
.st_uid
!= geteuid())) {
74 pr_err("File %s not owned by current user or root (use -f to override)\n",
80 pr_info("zero-sized data (%s), nothing to do!\n",
85 data
->size
= st
.st_size
;
93 static int open_file_write(struct perf_data
*data
)
96 char sbuf
[STRERR_BUFSIZE
];
98 if (check_backup(data
))
101 fd
= open(data
->file
.path
, O_CREAT
|O_RDWR
|O_TRUNC
|O_CLOEXEC
,
105 pr_err("failed to open %s : %s\n", data
->file
.path
,
106 str_error_r(errno
, sbuf
, sizeof(sbuf
)));
111 static int open_file(struct perf_data
*data
)
115 fd
= perf_data__is_read(data
) ?
116 open_file_read(data
) : open_file_write(data
);
119 return fd
< 0 ? -1 : 0;
122 int perf_data__open(struct perf_data
*data
)
124 if (check_pipe(data
))
127 if (!data
->file
.path
)
128 data
->file
.path
= "perf.data";
130 return open_file(data
);
133 void perf_data__close(struct perf_data
*data
)
135 close(data
->file
.fd
);
138 ssize_t
perf_data_file__write(struct perf_data_file
*file
,
139 void *buf
, size_t size
)
141 return writen(file
->fd
, buf
, size
);
144 ssize_t
perf_data__write(struct perf_data
*data
,
145 void *buf
, size_t size
)
147 return perf_data_file__write(&data
->file
, buf
, size
);
150 int perf_data__switch(struct perf_data
*data
,
152 size_t pos
, bool at_exit
)
157 if (check_pipe(data
))
159 if (perf_data__is_read(data
))
162 if (asprintf(&new_filepath
, "%s.%s", data
->file
.path
, postfix
) < 0)
166 * Only fire a warning, don't return error, continue fill
169 if (rename(data
->file
.path
, new_filepath
))
170 pr_warning("Failed to rename %s to %s\n", data
->file
.path
, new_filepath
);
173 close(data
->file
.fd
);
174 ret
= perf_data__open(data
);
178 if (lseek(data
->file
.fd
, pos
, SEEK_SET
) == (off_t
)-1) {
180 pr_debug("Failed to lseek to %zu: %s",
181 pos
, strerror(errno
));