1 #include "../perf.h" 2 #include "util.h" 3 #include <sys/mman.h> 4 #ifdef BACKTRACE_SUPPORT 5 #include <execinfo.h> 6 #endif 7 #include <stdio.h> 8 #include <stdlib.h> 9 10 /* 11 * XXX We need to find a better place for these things... 12 */ 13 bool perf_host = true; 14 bool perf_guest = false; 15 16 void event_attr_init(struct perf_event_attr *attr) 17 { 18 if (!perf_host) 19 attr->exclude_host = 1; 20 if (!perf_guest) 21 attr->exclude_guest = 1; 22 /* to capture ABI version */ 23 attr->size = sizeof(*attr); 24 } 25 26 int mkdir_p(char *path, mode_t mode) 27 { 28 struct stat st; 29 int err; 30 char *d = path; 31 32 if (*d != '/') 33 return -1; 34 35 if (stat(path, &st) == 0) 36 return 0; 37 38 while (*++d == '/'); 39 40 while ((d = strchr(d, '/'))) { 41 *d = '\0'; 42 err = stat(path, &st) && mkdir(path, mode); 43 *d++ = '/'; 44 if (err) 45 return -1; 46 while (*d == '/') 47 ++d; 48 } 49 return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0; 50 } 51 52 static int slow_copyfile(const char *from, const char *to) 53 { 54 int err = 0; 55 char *line = NULL; 56 size_t n; 57 FILE *from_fp = fopen(from, "r"), *to_fp; 58 59 if (from_fp == NULL) 60 goto out; 61 62 to_fp = fopen(to, "w"); 63 if (to_fp == NULL) 64 goto out_fclose_from; 65 66 while (getline(&line, &n, from_fp) > 0) 67 if (fputs(line, to_fp) == EOF) 68 goto out_fclose_to; 69 err = 0; 70 out_fclose_to: 71 fclose(to_fp); 72 free(line); 73 out_fclose_from: 74 fclose(from_fp); 75 out: 76 return err; 77 } 78 79 int copyfile(const char *from, const char *to) 80 { 81 int fromfd, tofd; 82 struct stat st; 83 void *addr; 84 int err = -1; 85 86 if (stat(from, &st)) 87 goto out; 88 89 if (st.st_size == 0) /* /proc? do it slowly... */ 90 return slow_copyfile(from, to); 91 92 fromfd = open(from, O_RDONLY); 93 if (fromfd < 0) 94 goto out; 95 96 tofd = creat(to, 0755); 97 if (tofd < 0) 98 goto out_close_from; 99 100 addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fromfd, 0); 101 if (addr == MAP_FAILED) 102 goto out_close_to; 103 104 if (write(tofd, addr, st.st_size) == st.st_size) 105 err = 0; 106 107 munmap(addr, st.st_size); 108 out_close_to: 109 close(tofd); 110 if (err) 111 unlink(to); 112 out_close_from: 113 close(fromfd); 114 out: 115 return err; 116 } 117 118 unsigned long convert_unit(unsigned long value, char *unit) 119 { 120 *unit = ' '; 121 122 if (value > 1000) { 123 value /= 1000; 124 *unit = 'K'; 125 } 126 127 if (value > 1000) { 128 value /= 1000; 129 *unit = 'M'; 130 } 131 132 if (value > 1000) { 133 value /= 1000; 134 *unit = 'G'; 135 } 136 137 return value; 138 } 139 140 int readn(int fd, void *buf, size_t n) 141 { 142 void *buf_start = buf; 143 144 while (n) { 145 int ret = read(fd, buf, n); 146 147 if (ret <= 0) 148 return ret; 149 150 n -= ret; 151 buf += ret; 152 } 153 154 return buf - buf_start; 155 } 156 157 size_t hex_width(u64 v) 158 { 159 size_t n = 1; 160 161 while ((v >>= 4)) 162 ++n; 163 164 return n; 165 } 166 167 /* Obtain a backtrace and print it to stdout. */ 168 #ifdef BACKTRACE_SUPPORT 169 void dump_stack(void) 170 { 171 void *array[16]; 172 size_t size = backtrace(array, ARRAY_SIZE(array)); 173 char **strings = backtrace_symbols(array, size); 174 size_t i; 175 176 printf("Obtained %zd stack frames.\n", size); 177 178 for (i = 0; i < size; i++) 179 printf("%s\n", strings[i]); 180 181 free(strings); 182 } 183 #else 184 void dump_stack(void) {} 185 #endif 186