data.c 2.5 KB

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