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 unsigned int page_size; 14 15 bool test_attr__enabled; 16 17 bool perf_host = true; 18 bool perf_guest = false; 19 20 void event_attr_init(struct perf_event_attr *attr) 21 { 22 if (!perf_host) 23 attr->exclude_host = 1; 24 if (!perf_guest) 25 attr->exclude_guest = 1; 26 /* to capture ABI version */ 27 attr->size = sizeof(*attr); 28 } 29 30 int mkdir_p(char *path, mode_t mode) 31 { 32 struct stat st; 33 int err; 34 char *d = path; 35 36 if (*d != '/') 37 return -1; 38 39 if (stat(path, &st) == 0) 40 return 0; 41 42 while (*++d == '/'); 43 44 while ((d = strchr(d, '/'))) { 45 *d = '\0'; 46 err = stat(path, &st) && mkdir(path, mode); 47 *d++ = '/'; 48 if (err) 49 return -1; 50 while (*d == '/') 51 ++d; 52 } 53 return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0; 54 } 55 56 static int slow_copyfile(const char *from, const char *to) 57 { 58 int err = 0; 59 char *line = NULL; 60 size_t n; 61 FILE *from_fp = fopen(from, "r"), *to_fp; 62 63 if (from_fp == NULL) 64 goto out; 65 66 to_fp = fopen(to, "w"); 67 if (to_fp == NULL) 68 goto out_fclose_from; 69 70 while (getline(&line, &n, from_fp) > 0) 71 if (fputs(line, to_fp) == EOF) 72 goto out_fclose_to; 73 err = 0; 74 out_fclose_to: 75 fclose(to_fp); 76 free(line); 77 out_fclose_from: 78 fclose(from_fp); 79 out: 80 return err; 81 } 82 83 int copyfile(const char *from, const char *to) 84 { 85 int fromfd, tofd; 86 struct stat st; 87 void *addr; 88 int err = -1; 89 90 if (stat(from, &st)) 91 goto out; 92 93 if (st.st_size == 0) /* /proc? do it slowly... */ 94 return slow_copyfile(from, to); 95 96 fromfd = open(from, O_RDONLY); 97 if (fromfd < 0) 98 goto out; 99 100 tofd = creat(to, 0755); 101 if (tofd < 0) 102 goto out_close_from; 103 104 addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fromfd, 0); 105 if (addr == MAP_FAILED) 106 goto out_close_to; 107 108 if (write(tofd, addr, st.st_size) == st.st_size) 109 err = 0; 110 111 munmap(addr, st.st_size); 112 out_close_to: 113 close(tofd); 114 if (err) 115 unlink(to); 116 out_close_from: 117 close(fromfd); 118 out: 119 return err; 120 } 121 122 unsigned long convert_unit(unsigned long value, char *unit) 123 { 124 *unit = ' '; 125 126 if (value > 1000) { 127 value /= 1000; 128 *unit = 'K'; 129 } 130 131 if (value > 1000) { 132 value /= 1000; 133 *unit = 'M'; 134 } 135 136 if (value > 1000) { 137 value /= 1000; 138 *unit = 'G'; 139 } 140 141 return value; 142 } 143 144 int readn(int fd, void *buf, size_t n) 145 { 146 void *buf_start = buf; 147 148 while (n) { 149 int ret = read(fd, buf, n); 150 151 if (ret <= 0) 152 return ret; 153 154 n -= ret; 155 buf += ret; 156 } 157 158 return buf - buf_start; 159 } 160 161 size_t hex_width(u64 v) 162 { 163 size_t n = 1; 164 165 while ((v >>= 4)) 166 ++n; 167 168 return n; 169 } 170 171 static int hex(char ch) 172 { 173 if ((ch >= '0') && (ch <= '9')) 174 return ch - '0'; 175 if ((ch >= 'a') && (ch <= 'f')) 176 return ch - 'a' + 10; 177 if ((ch >= 'A') && (ch <= 'F')) 178 return ch - 'A' + 10; 179 return -1; 180 } 181 182 /* 183 * While we find nice hex chars, build a long_val. 184 * Return number of chars processed. 185 */ 186 int hex2u64(const char *ptr, u64 *long_val) 187 { 188 const char *p = ptr; 189 *long_val = 0; 190 191 while (*p) { 192 const int hex_val = hex(*p); 193 194 if (hex_val < 0) 195 break; 196 197 *long_val = (*long_val << 4) | hex_val; 198 p++; 199 } 200 201 return p - ptr; 202 } 203 204 /* Obtain a backtrace and print it to stdout. */ 205 #ifdef BACKTRACE_SUPPORT 206 void dump_stack(void) 207 { 208 void *array[16]; 209 size_t size = backtrace(array, ARRAY_SIZE(array)); 210 char **strings = backtrace_symbols(array, size); 211 size_t i; 212 213 printf("Obtained %zd stack frames.\n", size); 214 215 for (i = 0; i < size; i++) 216 printf("%s\n", strings[i]); 217 218 free(strings); 219 } 220 #else 221 void dump_stack(void) {} 222 #endif 223 224 void get_term_dimensions(struct winsize *ws) 225 { 226 char *s = getenv("LINES"); 227 228 if (s != NULL) { 229 ws->ws_row = atoi(s); 230 s = getenv("COLUMNS"); 231 if (s != NULL) { 232 ws->ws_col = atoi(s); 233 if (ws->ws_row && ws->ws_col) 234 return; 235 } 236 } 237 #ifdef TIOCGWINSZ 238 if (ioctl(1, TIOCGWINSZ, ws) == 0 && 239 ws->ws_row && ws->ws_col) 240 return; 241 #endif 242 ws->ws_row = 25; 243 ws->ws_col = 80; 244 } 245