Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf tools: Remove some unused functions

Without the bloated cplus_demangle from binutils, i.e building with:

$ make NO_DEMANGLE=1 O=~acme/git/build/perf -j3 -C tools/perf/ install

Before:

text data bss dec hex filename
471851 29280 4025056 4526187 45106b /home/acme/bin/perf

After:

[acme@doppio linux-2.6-tip]$ size ~/bin/perf
text data bss dec hex filename
446886 29232 4008576 4484694 446e56 /home/acme/bin/perf

So its a 5.3% size reduction in code, but the interesting part is in the git
diff --stat output:

19 files changed, 20 insertions(+), 1909 deletions(-)

If we ever need some of the things we got from git but weren't using, we just
have to go to the git repo and get fresh, uptodate source code bits.

Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

+20 -1909
+1
tools/perf/builtin-record.c
··· 25 25 26 26 #include <unistd.h> 27 27 #include <sched.h> 28 + #include <sys/mman.h> 28 29 29 30 enum write_mode_t { 30 31 WRITE_FORCE,
-81
tools/perf/util/abspath.c
··· 1 1 #include "cache.h" 2 2 3 - /* 4 - * Do not use this for inspecting *tracked* content. When path is a 5 - * symlink to a directory, we do not want to say it is a directory when 6 - * dealing with tracked content in the working tree. 7 - */ 8 - static int is_directory(const char *path) 9 - { 10 - struct stat st; 11 - return (!stat(path, &st) && S_ISDIR(st.st_mode)); 12 - } 13 - 14 - /* We allow "recursive" symbolic links. Only within reason, though. */ 15 - #define MAXDEPTH 5 16 - 17 - const char *make_absolute_path(const char *path) 18 - { 19 - static char bufs[2][PATH_MAX + 1], *buf = bufs[0], *next_buf = bufs[1]; 20 - char cwd[1024] = ""; 21 - int buf_index = 1, len; 22 - 23 - int depth = MAXDEPTH; 24 - char *last_elem = NULL; 25 - struct stat st; 26 - 27 - if (strlcpy(buf, path, PATH_MAX) >= PATH_MAX) 28 - die ("Too long path: %.*s", 60, path); 29 - 30 - while (depth--) { 31 - if (!is_directory(buf)) { 32 - char *last_slash = strrchr(buf, '/'); 33 - if (last_slash) { 34 - *last_slash = '\0'; 35 - last_elem = xstrdup(last_slash + 1); 36 - } else { 37 - last_elem = xstrdup(buf); 38 - *buf = '\0'; 39 - } 40 - } 41 - 42 - if (*buf) { 43 - if (!*cwd && !getcwd(cwd, sizeof(cwd))) 44 - die ("Could not get current working directory"); 45 - 46 - if (chdir(buf)) 47 - die ("Could not switch to '%s'", buf); 48 - } 49 - if (!getcwd(buf, PATH_MAX)) 50 - die ("Could not get current working directory"); 51 - 52 - if (last_elem) { 53 - len = strlen(buf); 54 - 55 - if (len + strlen(last_elem) + 2 > PATH_MAX) 56 - die ("Too long path name: '%s/%s'", 57 - buf, last_elem); 58 - buf[len] = '/'; 59 - strcpy(buf + len + 1, last_elem); 60 - free(last_elem); 61 - last_elem = NULL; 62 - } 63 - 64 - if (!lstat(buf, &st) && S_ISLNK(st.st_mode)) { 65 - len = readlink(buf, next_buf, PATH_MAX); 66 - if (len < 0) 67 - die ("Invalid symlink: %s", buf); 68 - if (PATH_MAX <= len) 69 - die("symbolic link too long: %s", buf); 70 - next_buf[len] = '\0'; 71 - buf = next_buf; 72 - buf_index = 1 - buf_index; 73 - next_buf = bufs[buf_index]; 74 - } else 75 - break; 76 - } 77 - 78 - if (*cwd && chdir(cwd)) 79 - die ("Could not change back to '%s'", cwd); 80 - 81 - return buf; 82 - } 83 - 84 3 static const char *get_pwd_cwd(void) 85 4 { 86 5 static char cwd[PATH_MAX + 1];
+1 -54
tools/perf/util/cache.h
··· 13 13 14 14 #define PERF_DIR_ENVIRONMENT "PERF_DIR" 15 15 #define PERF_WORK_TREE_ENVIRONMENT "PERF_WORK_TREE" 16 - #define DEFAULT_PERF_DIR_ENVIRONMENT ".perf" 17 - #define DB_ENVIRONMENT "PERF_OBJECT_DIRECTORY" 18 - #define INDEX_ENVIRONMENT "PERF_INDEX_FILE" 19 - #define GRAFT_ENVIRONMENT "PERF_GRAFT_FILE" 20 - #define TEMPLATE_DIR_ENVIRONMENT "PERF_TEMPLATE_DIR" 21 - #define CONFIG_ENVIRONMENT "PERF_CONFIG" 22 16 #define EXEC_PATH_ENVIRONMENT "PERF_EXEC_PATH" 23 - #define CEILING_DIRECTORIES_ENVIRONMENT "PERF_CEILING_DIRECTORIES" 24 - #define PERFATTRIBUTES_FILE ".perfattributes" 25 - #define INFOATTRIBUTES_FILE "info/attributes" 26 - #define ATTRIBUTE_MACRO_PREFIX "[attr]" 17 + #define DEFAULT_PERF_DIR_ENVIRONMENT ".perf" 27 18 #define PERF_DEBUGFS_ENVIRONMENT "PERF_DEBUGFS_DIR" 28 19 29 20 typedef int (*config_fn_t)(const char *, const char *, void *); 30 21 extern int perf_default_config(const char *, const char *, void *); 31 - extern int perf_config_from_file(config_fn_t fn, const char *, void *); 32 22 extern int perf_config(config_fn_t fn, void *); 33 - extern int perf_parse_ulong(const char *, unsigned long *); 34 23 extern int perf_config_int(const char *, const char *); 35 - extern unsigned long perf_config_ulong(const char *, const char *); 36 - extern int perf_config_bool_or_int(const char *, const char *, int *); 37 24 extern int perf_config_bool(const char *, const char *); 38 - extern int perf_config_string(const char **, const char *, const char *); 39 - extern int perf_config_set(const char *, const char *); 40 - extern int perf_config_set_multivar(const char *, const char *, const char *, int); 41 - extern int perf_config_rename_section(const char *, const char *); 42 - extern const char *perf_etc_perfconfig(void); 43 - extern int check_repository_format_version(const char *var, const char *value, void *cb); 44 - extern int perf_config_system(void); 45 - extern int perf_config_global(void); 46 25 extern int config_error_nonbool(const char *); 47 - extern const char *config_exclusive_filename; 48 - 49 - #define MAX_PERFNAME (1000) 50 - extern char perf_default_email[MAX_PERFNAME]; 51 - extern char perf_default_name[MAX_PERFNAME]; 52 - extern int user_ident_explicitly_given; 53 - 54 - extern const char *perf_log_output_encoding; 55 - extern const char *perf_mailmap_file; 56 - 57 - /* IO helper functions */ 58 - extern void maybe_flush_or_die(FILE *, const char *); 59 - extern int copy_fd(int ifd, int ofd); 60 - extern int copy_file(const char *dst, const char *src, int mode); 61 - extern ssize_t write_in_full(int fd, const void *buf, size_t count); 62 - extern void write_or_die(int fd, const void *buf, size_t count); 63 - extern int write_or_whine(int fd, const void *buf, size_t count, const char *msg); 64 - extern int write_or_whine_pipe(int fd, const void *buf, size_t count, const char *msg); 65 - extern void fsync_or_die(int fd, const char *); 66 26 67 27 /* pager.c */ 68 28 extern void setup_pager(void); ··· 42 82 void setup_browser(void); 43 83 void exit_browser(bool wait_for_ok); 44 84 #endif 45 - 46 - extern const char *editor_program; 47 - extern const char *excludes_file; 48 85 49 86 char *alias_lookup(const char *alias); 50 87 int split_cmdline(char *cmdline, const char ***argv); ··· 72 115 return path[0] == '/'; 73 116 } 74 117 75 - const char *make_absolute_path(const char *path); 76 118 const char *make_nonrelative_path(const char *path); 77 - const char *make_relative_path(const char *abs, const char *base); 78 - int normalize_path_copy(char *dst, const char *src); 79 - int longest_ancestor_length(const char *path, const char *prefix_list); 80 119 char *strip_path_suffix(const char *path, const char *suffix); 81 120 82 121 extern char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2))); 83 122 extern char *perf_path(const char *fmt, ...) __attribute__((format (printf, 1, 2))); 84 - /* perf_mkstemp() - create tmp file honoring TMPDIR variable */ 85 - extern int perf_mkstemp(char *path, size_t len, const char *template); 86 123 87 - extern char *mksnpath(char *buf, size_t n, const char *fmt, ...) 88 - __attribute__((format (printf, 3, 4))); 89 - extern char *perf_snpath(char *buf, size_t n, const char *fmt, ...) 90 - __attribute__((format (printf, 3, 4))); 91 124 extern char *perf_pathdup(const char *fmt, ...) 92 125 __attribute__((format (printf, 1, 2))); 93 126
+6 -455
tools/perf/util/config.c
··· 16 16 static int config_linenr; 17 17 static int config_file_eof; 18 18 19 - const char *config_exclusive_filename = NULL; 19 + static const char *config_exclusive_filename; 20 20 21 21 static int get_next_char(void) 22 22 { ··· 291 291 return 0; 292 292 } 293 293 294 - int perf_parse_ulong(const char *value, unsigned long *ret) 295 - { 296 - if (value && *value) { 297 - char *end; 298 - unsigned long val = strtoul(value, &end, 0); 299 - if (!parse_unit_factor(end, &val)) 300 - return 0; 301 - *ret = val; 302 - return 1; 303 - } 304 - return 0; 305 - } 306 - 307 294 static void die_bad_config(const char *name) 308 295 { 309 296 if (config_file_name) ··· 306 319 return ret; 307 320 } 308 321 309 - unsigned long perf_config_ulong(const char *name, const char *value) 310 - { 311 - unsigned long ret; 312 - if (!perf_parse_ulong(value, &ret)) 313 - die_bad_config(name); 314 - return ret; 315 - } 316 - 317 - int perf_config_bool_or_int(const char *name, const char *value, int *is_bool) 322 + static int perf_config_bool_or_int(const char *name, const char *value, int *is_bool) 318 323 { 319 324 *is_bool = 1; 320 325 if (!value) ··· 327 348 return !!perf_config_bool_or_int(name, value, &discard); 328 349 } 329 350 330 - int perf_config_string(const char **dest, const char *var, const char *value) 331 - { 332 - if (!value) 333 - return config_error_nonbool(var); 334 - *dest = strdup(value); 335 - return 0; 336 - } 337 - 338 351 static int perf_default_core_config(const char *var __used, const char *value __used) 339 352 { 340 353 /* Add other config variables here and to Documentation/config.txt. */ ··· 342 371 return 0; 343 372 } 344 373 345 - int perf_config_from_file(config_fn_t fn, const char *filename, void *data) 374 + static int perf_config_from_file(config_fn_t fn, const char *filename, void *data) 346 375 { 347 376 int ret; 348 377 FILE *f = fopen(filename, "r"); ··· 360 389 return ret; 361 390 } 362 391 363 - const char *perf_etc_perfconfig(void) 392 + static const char *perf_etc_perfconfig(void) 364 393 { 365 394 static const char *system_wide; 366 395 if (!system_wide) ··· 374 403 return v ? perf_config_bool(k, v) : def; 375 404 } 376 405 377 - int perf_config_system(void) 406 + static int perf_config_system(void) 378 407 { 379 408 return !perf_env_bool("PERF_CONFIG_NOSYSTEM", 0); 380 409 } 381 410 382 - int perf_config_global(void) 411 + static int perf_config_global(void) 383 412 { 384 413 return !perf_env_bool("PERF_CONFIG_NOGLOBAL", 0); 385 414 } ··· 418 447 if (found == 0) 419 448 return -1; 420 449 return ret; 421 - } 422 - 423 - /* 424 - * Find all the stuff for perf_config_set() below. 425 - */ 426 - 427 - #define MAX_MATCHES 512 428 - 429 - static struct { 430 - int baselen; 431 - char* key; 432 - int do_not_match; 433 - regex_t* value_regex; 434 - int multi_replace; 435 - size_t offset[MAX_MATCHES]; 436 - enum { START, SECTION_SEEN, SECTION_END_SEEN, KEY_SEEN } state; 437 - int seen; 438 - } store; 439 - 440 - static int matches(const char* key, const char* value) 441 - { 442 - return !strcmp(key, store.key) && 443 - (store.value_regex == NULL || 444 - (store.do_not_match ^ 445 - !regexec(store.value_regex, value, 0, NULL, 0))); 446 - } 447 - 448 - static int store_aux(const char* key, const char* value, void *cb __used) 449 - { 450 - int section_len; 451 - const char *ep; 452 - 453 - switch (store.state) { 454 - case KEY_SEEN: 455 - if (matches(key, value)) { 456 - if (store.seen == 1 && store.multi_replace == 0) { 457 - warning("%s has multiple values", key); 458 - } else if (store.seen >= MAX_MATCHES) { 459 - error("too many matches for %s", key); 460 - return 1; 461 - } 462 - 463 - store.offset[store.seen] = ftell(config_file); 464 - store.seen++; 465 - } 466 - break; 467 - case SECTION_SEEN: 468 - /* 469 - * What we are looking for is in store.key (both 470 - * section and var), and its section part is baselen 471 - * long. We found key (again, both section and var). 472 - * We would want to know if this key is in the same 473 - * section as what we are looking for. We already 474 - * know we are in the same section as what should 475 - * hold store.key. 476 - */ 477 - ep = strrchr(key, '.'); 478 - section_len = ep - key; 479 - 480 - if ((section_len != store.baselen) || 481 - memcmp(key, store.key, section_len+1)) { 482 - store.state = SECTION_END_SEEN; 483 - break; 484 - } 485 - 486 - /* 487 - * Do not increment matches: this is no match, but we 488 - * just made sure we are in the desired section. 489 - */ 490 - store.offset[store.seen] = ftell(config_file); 491 - /* fallthru */ 492 - case SECTION_END_SEEN: 493 - case START: 494 - if (matches(key, value)) { 495 - store.offset[store.seen] = ftell(config_file); 496 - store.state = KEY_SEEN; 497 - store.seen++; 498 - } else { 499 - if (strrchr(key, '.') - key == store.baselen && 500 - !strncmp(key, store.key, store.baselen)) { 501 - store.state = SECTION_SEEN; 502 - store.offset[store.seen] = ftell(config_file); 503 - } 504 - } 505 - default: 506 - break; 507 - } 508 - return 0; 509 - } 510 - 511 - static int store_write_section(int fd, const char* key) 512 - { 513 - const char *dot; 514 - int i, success; 515 - struct strbuf sb = STRBUF_INIT; 516 - 517 - dot = memchr(key, '.', store.baselen); 518 - if (dot) { 519 - strbuf_addf(&sb, "[%.*s \"", (int)(dot - key), key); 520 - for (i = dot - key + 1; i < store.baselen; i++) { 521 - if (key[i] == '"' || key[i] == '\\') 522 - strbuf_addch(&sb, '\\'); 523 - strbuf_addch(&sb, key[i]); 524 - } 525 - strbuf_addstr(&sb, "\"]\n"); 526 - } else { 527 - strbuf_addf(&sb, "[%.*s]\n", store.baselen, key); 528 - } 529 - 530 - success = (write_in_full(fd, sb.buf, sb.len) == (ssize_t)sb.len); 531 - strbuf_release(&sb); 532 - 533 - return success; 534 - } 535 - 536 - static int store_write_pair(int fd, const char* key, const char* value) 537 - { 538 - int i, success; 539 - int length = strlen(key + store.baselen + 1); 540 - const char *quote = ""; 541 - struct strbuf sb = STRBUF_INIT; 542 - 543 - /* 544 - * Check to see if the value needs to be surrounded with a dq pair. 545 - * Note that problematic characters are always backslash-quoted; this 546 - * check is about not losing leading or trailing SP and strings that 547 - * follow beginning-of-comment characters (i.e. ';' and '#') by the 548 - * configuration parser. 549 - */ 550 - if (value[0] == ' ') 551 - quote = "\""; 552 - for (i = 0; value[i]; i++) 553 - if (value[i] == ';' || value[i] == '#') 554 - quote = "\""; 555 - if (i && value[i - 1] == ' ') 556 - quote = "\""; 557 - 558 - strbuf_addf(&sb, "\t%.*s = %s", 559 - length, key + store.baselen + 1, quote); 560 - 561 - for (i = 0; value[i]; i++) 562 - switch (value[i]) { 563 - case '\n': 564 - strbuf_addstr(&sb, "\\n"); 565 - break; 566 - case '\t': 567 - strbuf_addstr(&sb, "\\t"); 568 - break; 569 - case '"': 570 - case '\\': 571 - strbuf_addch(&sb, '\\'); 572 - default: 573 - strbuf_addch(&sb, value[i]); 574 - break; 575 - } 576 - strbuf_addf(&sb, "%s\n", quote); 577 - 578 - success = (write_in_full(fd, sb.buf, sb.len) == (ssize_t)sb.len); 579 - strbuf_release(&sb); 580 - 581 - return success; 582 - } 583 - 584 - static ssize_t find_beginning_of_line(const char* contents, size_t size, 585 - size_t offset_, int* found_bracket) 586 - { 587 - size_t equal_offset = size, bracket_offset = size; 588 - ssize_t offset; 589 - 590 - contline: 591 - for (offset = offset_-2; offset > 0 592 - && contents[offset] != '\n'; offset--) 593 - switch (contents[offset]) { 594 - case '=': equal_offset = offset; break; 595 - case ']': bracket_offset = offset; break; 596 - default: break; 597 - } 598 - if (offset > 0 && contents[offset-1] == '\\') { 599 - offset_ = offset; 600 - goto contline; 601 - } 602 - if (bracket_offset < equal_offset) { 603 - *found_bracket = 1; 604 - offset = bracket_offset+1; 605 - } else 606 - offset++; 607 - 608 - return offset; 609 - } 610 - 611 - int perf_config_set(const char* key, const char* value) 612 - { 613 - return perf_config_set_multivar(key, value, NULL, 0); 614 - } 615 - 616 - /* 617 - * If value==NULL, unset in (remove from) config, 618 - * if value_regex!=NULL, disregard key/value pairs where value does not match. 619 - * if multi_replace==0, nothing, or only one matching key/value is replaced, 620 - * else all matching key/values (regardless how many) are removed, 621 - * before the new pair is written. 622 - * 623 - * Returns 0 on success. 624 - * 625 - * This function does this: 626 - * 627 - * - it locks the config file by creating ".perf/config.lock" 628 - * 629 - * - it then parses the config using store_aux() as validator to find 630 - * the position on the key/value pair to replace. If it is to be unset, 631 - * it must be found exactly once. 632 - * 633 - * - the config file is mmap()ed and the part before the match (if any) is 634 - * written to the lock file, then the changed part and the rest. 635 - * 636 - * - the config file is removed and the lock file rename()d to it. 637 - * 638 - */ 639 - int perf_config_set_multivar(const char* key, const char* value, 640 - const char* value_regex, int multi_replace) 641 - { 642 - int i, dot; 643 - int fd = -1, in_fd; 644 - int ret = 0; 645 - char* config_filename; 646 - const char* last_dot = strrchr(key, '.'); 647 - 648 - if (config_exclusive_filename) 649 - config_filename = strdup(config_exclusive_filename); 650 - else 651 - config_filename = perf_pathdup("config"); 652 - 653 - /* 654 - * Since "key" actually contains the section name and the real 655 - * key name separated by a dot, we have to know where the dot is. 656 - */ 657 - 658 - if (last_dot == NULL) { 659 - error("key does not contain a section: %s", key); 660 - ret = 2; 661 - goto out_free; 662 - } 663 - store.baselen = last_dot - key; 664 - 665 - store.multi_replace = multi_replace; 666 - 667 - /* 668 - * Validate the key and while at it, lower case it for matching. 669 - */ 670 - store.key = malloc(strlen(key) + 1); 671 - dot = 0; 672 - for (i = 0; key[i]; i++) { 673 - unsigned char c = key[i]; 674 - if (c == '.') 675 - dot = 1; 676 - /* Leave the extended basename untouched.. */ 677 - if (!dot || i > store.baselen) { 678 - if (!iskeychar(c) || (i == store.baselen+1 && !isalpha(c))) { 679 - error("invalid key: %s", key); 680 - free(store.key); 681 - ret = 1; 682 - goto out_free; 683 - } 684 - c = tolower(c); 685 - } else if (c == '\n') { 686 - error("invalid key (newline): %s", key); 687 - free(store.key); 688 - ret = 1; 689 - goto out_free; 690 - } 691 - store.key[i] = c; 692 - } 693 - store.key[i] = 0; 694 - 695 - /* 696 - * If .perf/config does not exist yet, write a minimal version. 697 - */ 698 - in_fd = open(config_filename, O_RDONLY); 699 - if ( in_fd < 0 ) { 700 - free(store.key); 701 - 702 - if ( ENOENT != errno ) { 703 - error("opening %s: %s", config_filename, 704 - strerror(errno)); 705 - ret = 3; /* same as "invalid config file" */ 706 - goto out_free; 707 - } 708 - /* if nothing to unset, error out */ 709 - if (value == NULL) { 710 - ret = 5; 711 - goto out_free; 712 - } 713 - 714 - store.key = (char*)key; 715 - if (!store_write_section(fd, key) || 716 - !store_write_pair(fd, key, value)) 717 - goto write_err_out; 718 - } else { 719 - struct stat st; 720 - char *contents; 721 - ssize_t contents_sz, copy_begin, copy_end; 722 - int new_line = 0; 723 - 724 - if (value_regex == NULL) 725 - store.value_regex = NULL; 726 - else { 727 - if (value_regex[0] == '!') { 728 - store.do_not_match = 1; 729 - value_regex++; 730 - } else 731 - store.do_not_match = 0; 732 - 733 - store.value_regex = (regex_t*)malloc(sizeof(regex_t)); 734 - if (regcomp(store.value_regex, value_regex, 735 - REG_EXTENDED)) { 736 - error("invalid pattern: %s", value_regex); 737 - free(store.value_regex); 738 - ret = 6; 739 - goto out_free; 740 - } 741 - } 742 - 743 - store.offset[0] = 0; 744 - store.state = START; 745 - store.seen = 0; 746 - 747 - /* 748 - * After this, store.offset will contain the *end* offset 749 - * of the last match, or remain at 0 if no match was found. 750 - * As a side effect, we make sure to transform only a valid 751 - * existing config file. 752 - */ 753 - if (perf_config_from_file(store_aux, config_filename, NULL)) { 754 - error("invalid config file %s", config_filename); 755 - free(store.key); 756 - if (store.value_regex != NULL) { 757 - regfree(store.value_regex); 758 - free(store.value_regex); 759 - } 760 - ret = 3; 761 - goto out_free; 762 - } 763 - 764 - free(store.key); 765 - if (store.value_regex != NULL) { 766 - regfree(store.value_regex); 767 - free(store.value_regex); 768 - } 769 - 770 - /* if nothing to unset, or too many matches, error out */ 771 - if ((store.seen == 0 && value == NULL) || 772 - (store.seen > 1 && multi_replace == 0)) { 773 - ret = 5; 774 - goto out_free; 775 - } 776 - 777 - fstat(in_fd, &st); 778 - contents_sz = xsize_t(st.st_size); 779 - contents = mmap(NULL, contents_sz, PROT_READ, 780 - MAP_PRIVATE, in_fd, 0); 781 - close(in_fd); 782 - 783 - if (store.seen == 0) 784 - store.seen = 1; 785 - 786 - for (i = 0, copy_begin = 0; i < store.seen; i++) { 787 - if (store.offset[i] == 0) { 788 - store.offset[i] = copy_end = contents_sz; 789 - } else if (store.state != KEY_SEEN) { 790 - copy_end = store.offset[i]; 791 - } else 792 - copy_end = find_beginning_of_line( 793 - contents, contents_sz, 794 - store.offset[i]-2, &new_line); 795 - 796 - if (copy_end > 0 && contents[copy_end-1] != '\n') 797 - new_line = 1; 798 - 799 - /* write the first part of the config */ 800 - if (copy_end > copy_begin) { 801 - if (write_in_full(fd, contents + copy_begin, 802 - copy_end - copy_begin) < 803 - copy_end - copy_begin) 804 - goto write_err_out; 805 - if (new_line && 806 - write_in_full(fd, "\n", 1) != 1) 807 - goto write_err_out; 808 - } 809 - copy_begin = store.offset[i]; 810 - } 811 - 812 - /* write the pair (value == NULL means unset) */ 813 - if (value != NULL) { 814 - if (store.state == START) { 815 - if (!store_write_section(fd, key)) 816 - goto write_err_out; 817 - } 818 - if (!store_write_pair(fd, key, value)) 819 - goto write_err_out; 820 - } 821 - 822 - /* write the rest of the config */ 823 - if (copy_begin < contents_sz) 824 - if (write_in_full(fd, contents + copy_begin, 825 - contents_sz - copy_begin) < 826 - contents_sz - copy_begin) 827 - goto write_err_out; 828 - 829 - munmap(contents, contents_sz); 830 - } 831 - 832 - ret = 0; 833 - 834 - out_free: 835 - free(config_filename); 836 - return ret; 837 - 838 - write_err_out: 839 - goto out_free; 840 - 841 450 } 842 451 843 452 /*
+1 -1
tools/perf/util/exec_cmd.c
··· 116 116 strbuf_release(&new_path); 117 117 } 118 118 119 - const char **prepare_perf_cmd(const char **argv) 119 + static const char **prepare_perf_cmd(const char **argv) 120 120 { 121 121 int argc; 122 122 const char **nargv;
-1
tools/perf/util/exec_cmd.h
··· 5 5 extern const char *perf_extract_argv0_path(const char *path); 6 6 extern const char *perf_exec_path(void); 7 7 extern void setup_path(void); 8 - extern const char **prepare_perf_cmd(const char **argv); 9 8 extern int execv_perf_cmd(const char **argv); /* NULL terminated */ 10 9 extern int execl_perf_cmd(const char *cmd, ...); 11 10 extern const char *system_path(const char *path);
+6 -24
tools/perf/util/help.c
··· 4 4 #include "levenshtein.h" 5 5 #include "help.h" 6 6 7 - /* most GUI terminals set COLUMNS (although some don't export it) */ 8 - static int term_columns(void) 9 - { 10 - char *col_string = getenv("COLUMNS"); 11 - int n_cols; 12 - 13 - if (col_string && (n_cols = atoi(col_string)) > 0) 14 - return n_cols; 15 - 16 - #ifdef TIOCGWINSZ 17 - { 18 - struct winsize ws; 19 - if (!ioctl(1, TIOCGWINSZ, &ws)) { 20 - if (ws.ws_col) 21 - return ws.ws_col; 22 - } 23 - } 24 - #endif 25 - 26 - return 80; 27 - } 28 - 29 7 void add_cmdname(struct cmdnames *cmds, const char *name, size_t len) 30 8 { 31 9 struct cmdname *ent = malloc(sizeof(*ent) + len + 1); ··· 74 96 { 75 97 int cols = 1, rows; 76 98 int space = longest + 1; /* min 1 SP between words */ 77 - int max_cols = term_columns() - 1; /* don't print *on* the edge */ 99 + struct winsize win; 100 + int max_cols; 78 101 int i, j; 102 + 103 + get_term_dimensions(&win); 104 + max_cols = win.ws_col - 1; /* don't print *on* the edge */ 79 105 80 106 if (space < max_cols) 81 107 cols = max_cols / space; ··· 306 324 307 325 main_cmds.names[0] = NULL; 308 326 clean_cmdnames(&main_cmds); 309 - fprintf(stderr, "WARNING: You called a Git program named '%s', " 327 + fprintf(stderr, "WARNING: You called a perf program named '%s', " 310 328 "which does not exist.\n" 311 329 "Continuing under the assumption that you meant '%s'\n", 312 330 cmd, assumed);
-202
tools/perf/util/path.c
··· 54 54 return path; 55 55 } 56 56 57 - char *mksnpath(char *buf, size_t n, const char *fmt, ...) 58 - { 59 - va_list args; 60 - unsigned len; 61 - 62 - va_start(args, fmt); 63 - len = vsnprintf(buf, n, fmt, args); 64 - va_end(args); 65 - if (len >= n) { 66 - strlcpy(buf, bad_path, n); 67 - return buf; 68 - } 69 - return cleanup_path(buf); 70 - } 71 - 72 57 static char *perf_vsnpath(char *buf, size_t n, const char *fmt, va_list args) 73 58 { 74 59 const char *perf_dir = get_perf_dir(); ··· 71 86 return cleanup_path(buf); 72 87 bad: 73 88 strlcpy(buf, bad_path, n); 74 - return buf; 75 - } 76 - 77 - char *perf_snpath(char *buf, size_t n, const char *fmt, ...) 78 - { 79 - va_list args; 80 - va_start(args, fmt); 81 - (void)perf_vsnpath(buf, n, fmt, args); 82 - va_end(args); 83 89 return buf; 84 90 } 85 91 ··· 117 141 if (len >= PATH_MAX) 118 142 return bad_path; 119 143 return cleanup_path(pathname); 120 - } 121 - 122 - 123 - /* perf_mkstemp() - create tmp file honoring TMPDIR variable */ 124 - int perf_mkstemp(char *path, size_t len, const char *template) 125 - { 126 - const char *tmp; 127 - size_t n; 128 - 129 - tmp = getenv("TMPDIR"); 130 - if (!tmp) 131 - tmp = "/tmp"; 132 - n = snprintf(path, len, "%s/%s", tmp, template); 133 - if (len <= n) { 134 - errno = ENAMETOOLONG; 135 - return -1; 136 - } 137 - return mkstemp(path); 138 - } 139 - 140 - 141 - const char *make_relative_path(const char *abs_path, const char *base) 142 - { 143 - static char buf[PATH_MAX + 1]; 144 - int baselen; 145 - 146 - if (!base) 147 - return abs_path; 148 - 149 - baselen = strlen(base); 150 - if (prefixcmp(abs_path, base)) 151 - return abs_path; 152 - if (abs_path[baselen] == '/') 153 - baselen++; 154 - else if (base[baselen - 1] != '/') 155 - return abs_path; 156 - 157 - strcpy(buf, abs_path + baselen); 158 - 159 - return buf; 160 - } 161 - 162 - /* 163 - * It is okay if dst == src, but they should not overlap otherwise. 164 - * 165 - * Performs the following normalizations on src, storing the result in dst: 166 - * - Ensures that components are separated by '/' (Windows only) 167 - * - Squashes sequences of '/'. 168 - * - Removes "." components. 169 - * - Removes ".." components, and the components the precede them. 170 - * Returns failure (non-zero) if a ".." component appears as first path 171 - * component anytime during the normalization. Otherwise, returns success (0). 172 - * 173 - * Note that this function is purely textual. It does not follow symlinks, 174 - * verify the existence of the path, or make any system calls. 175 - */ 176 - int normalize_path_copy(char *dst, const char *src) 177 - { 178 - char *dst0; 179 - 180 - if (has_dos_drive_prefix(src)) { 181 - *dst++ = *src++; 182 - *dst++ = *src++; 183 - } 184 - dst0 = dst; 185 - 186 - if (is_dir_sep(*src)) { 187 - *dst++ = '/'; 188 - while (is_dir_sep(*src)) 189 - src++; 190 - } 191 - 192 - for (;;) { 193 - char c = *src; 194 - 195 - /* 196 - * A path component that begins with . could be 197 - * special: 198 - * (1) "." and ends -- ignore and terminate. 199 - * (2) "./" -- ignore them, eat slash and continue. 200 - * (3) ".." and ends -- strip one and terminate. 201 - * (4) "../" -- strip one, eat slash and continue. 202 - */ 203 - if (c == '.') { 204 - if (!src[1]) { 205 - /* (1) */ 206 - src++; 207 - } else if (is_dir_sep(src[1])) { 208 - /* (2) */ 209 - src += 2; 210 - while (is_dir_sep(*src)) 211 - src++; 212 - continue; 213 - } else if (src[1] == '.') { 214 - if (!src[2]) { 215 - /* (3) */ 216 - src += 2; 217 - goto up_one; 218 - } else if (is_dir_sep(src[2])) { 219 - /* (4) */ 220 - src += 3; 221 - while (is_dir_sep(*src)) 222 - src++; 223 - goto up_one; 224 - } 225 - } 226 - } 227 - 228 - /* copy up to the next '/', and eat all '/' */ 229 - while ((c = *src++) != '\0' && !is_dir_sep(c)) 230 - *dst++ = c; 231 - if (is_dir_sep(c)) { 232 - *dst++ = '/'; 233 - while (is_dir_sep(c)) 234 - c = *src++; 235 - src--; 236 - } else if (!c) 237 - break; 238 - continue; 239 - 240 - up_one: 241 - /* 242 - * dst0..dst is prefix portion, and dst[-1] is '/'; 243 - * go up one level. 244 - */ 245 - dst--; /* go to trailing '/' */ 246 - if (dst <= dst0) 247 - return -1; 248 - /* Windows: dst[-1] cannot be backslash anymore */ 249 - while (dst0 < dst && dst[-1] != '/') 250 - dst--; 251 - } 252 - *dst = '\0'; 253 - return 0; 254 - } 255 - 256 - /* 257 - * path = Canonical absolute path 258 - * prefix_list = Colon-separated list of absolute paths 259 - * 260 - * Determines, for each path in prefix_list, whether the "prefix" really 261 - * is an ancestor directory of path. Returns the length of the longest 262 - * ancestor directory, excluding any trailing slashes, or -1 if no prefix 263 - * is an ancestor. (Note that this means 0 is returned if prefix_list is 264 - * "/".) "/foo" is not considered an ancestor of "/foobar". Directories 265 - * are not considered to be their own ancestors. path must be in a 266 - * canonical form: empty components, or "." or ".." components are not 267 - * allowed. prefix_list may be null, which is like "". 268 - */ 269 - int longest_ancestor_length(const char *path, const char *prefix_list) 270 - { 271 - char buf[PATH_MAX+1]; 272 - const char *ceil, *colon; 273 - int len, max_len = -1; 274 - 275 - if (prefix_list == NULL || !strcmp(path, "/")) 276 - return -1; 277 - 278 - for (colon = ceil = prefix_list; *colon; ceil = colon+1) { 279 - for (colon = ceil; *colon && *colon != PATH_SEP; colon++); 280 - len = colon - ceil; 281 - if (len == 0 || len > PATH_MAX || !is_absolute_path(ceil)) 282 - continue; 283 - strlcpy(buf, ceil, len+1); 284 - if (normalize_path_copy(buf, buf) < 0) 285 - continue; 286 - len = strlen(buf); 287 - if (len > 0 && buf[len-1] == '/') 288 - buf[--len] = '\0'; 289 - 290 - if (!strncmp(path, buf, len) && 291 - path[len] == '/' && 292 - len > max_len) { 293 - max_len = len; 294 - } 295 - } 296 - 297 - return max_len; 298 144 } 299 145 300 146 /* strip arbitrary amount of directory separators at end of path */
+1 -432
tools/perf/util/quote.c
··· 1 1 #include "cache.h" 2 2 #include "quote.h" 3 3 4 - int quote_path_fully = 1; 5 - 6 4 /* Help to copy the thing properly quoted for the shell safety. 7 5 * any single quote is replaced with '\'', any exclamation point 8 6 * is replaced with '\!', and the whole thing is enclosed in a ··· 17 19 return (c == '\'' || c == '!'); 18 20 } 19 21 20 - void sq_quote_buf(struct strbuf *dst, const char *src) 22 + static void sq_quote_buf(struct strbuf *dst, const char *src) 21 23 { 22 24 char *to_free = NULL; 23 25 ··· 39 41 free(to_free); 40 42 } 41 43 42 - void sq_quote_print(FILE *stream, const char *src) 43 - { 44 - char c; 45 - 46 - fputc('\'', stream); 47 - while ((c = *src++)) { 48 - if (need_bs_quote(c)) { 49 - fputs("'\\", stream); 50 - fputc(c, stream); 51 - fputc('\'', stream); 52 - } else { 53 - fputc(c, stream); 54 - } 55 - } 56 - fputc('\'', stream); 57 - } 58 - 59 44 void sq_quote_argv(struct strbuf *dst, const char** argv, size_t maxlen) 60 45 { 61 46 int i; ··· 51 70 if (maxlen && dst->len > maxlen) 52 71 die("Too many or long arguments"); 53 72 } 54 - } 55 - 56 - char *sq_dequote_step(char *arg, char **next) 57 - { 58 - char *dst = arg; 59 - char *src = arg; 60 - char c; 61 - 62 - if (*src != '\'') 63 - return NULL; 64 - for (;;) { 65 - c = *++src; 66 - if (!c) 67 - return NULL; 68 - if (c != '\'') { 69 - *dst++ = c; 70 - continue; 71 - } 72 - /* We stepped out of sq */ 73 - switch (*++src) { 74 - case '\0': 75 - *dst = 0; 76 - if (next) 77 - *next = NULL; 78 - return arg; 79 - case '\\': 80 - c = *++src; 81 - if (need_bs_quote(c) && *++src == '\'') { 82 - *dst++ = c; 83 - continue; 84 - } 85 - /* Fallthrough */ 86 - default: 87 - if (!next || !isspace(*src)) 88 - return NULL; 89 - do { 90 - c = *++src; 91 - } while (isspace(c)); 92 - *dst = 0; 93 - *next = src; 94 - return arg; 95 - } 96 - } 97 - } 98 - 99 - char *sq_dequote(char *arg) 100 - { 101 - return sq_dequote_step(arg, NULL); 102 - } 103 - 104 - int sq_dequote_to_argv(char *arg, const char ***argv, int *nr, int *alloc) 105 - { 106 - char *next = arg; 107 - 108 - if (!*arg) 109 - return 0; 110 - do { 111 - char *dequoted = sq_dequote_step(next, &next); 112 - if (!dequoted) 113 - return -1; 114 - ALLOC_GROW(*argv, *nr + 1, *alloc); 115 - (*argv)[(*nr)++] = dequoted; 116 - } while (next); 117 - 118 - return 0; 119 - } 120 - 121 - /* 1 means: quote as octal 122 - * 0 means: quote as octal if (quote_path_fully) 123 - * -1 means: never quote 124 - * c: quote as "\\c" 125 - */ 126 - #define X8(x) x, x, x, x, x, x, x, x 127 - #define X16(x) X8(x), X8(x) 128 - static signed char const sq_lookup[256] = { 129 - /* 0 1 2 3 4 5 6 7 */ 130 - /* 0x00 */ 1, 1, 1, 1, 1, 1, 1, 'a', 131 - /* 0x08 */ 'b', 't', 'n', 'v', 'f', 'r', 1, 1, 132 - /* 0x10 */ X16(1), 133 - /* 0x20 */ -1, -1, '"', -1, -1, -1, -1, -1, 134 - /* 0x28 */ X16(-1), X16(-1), X16(-1), 135 - /* 0x58 */ -1, -1, -1, -1,'\\', -1, -1, -1, 136 - /* 0x60 */ X16(-1), X8(-1), 137 - /* 0x78 */ -1, -1, -1, -1, -1, -1, -1, 1, 138 - /* 0x80 */ /* set to 0 */ 139 - }; 140 - 141 - static inline int sq_must_quote(char c) 142 - { 143 - return sq_lookup[(unsigned char)c] + quote_path_fully > 0; 144 - } 145 - 146 - /* 147 - * Returns the longest prefix not needing a quote up to maxlen if 148 - * positive. 149 - * This stops at the first \0 because it's marked as a character 150 - * needing an escape. 151 - */ 152 - static ssize_t next_quote_pos(const char *s, ssize_t maxlen) 153 - { 154 - ssize_t len; 155 - 156 - if (maxlen < 0) { 157 - for (len = 0; !sq_must_quote(s[len]); len++); 158 - } else { 159 - for (len = 0; len < maxlen && !sq_must_quote(s[len]); len++); 160 - } 161 - return len; 162 - } 163 - 164 - /* 165 - * C-style name quoting. 166 - * 167 - * (1) if sb and fp are both NULL, inspect the input name and counts the 168 - * number of bytes that are needed to hold c_style quoted version of name, 169 - * counting the double quotes around it but not terminating NUL, and 170 - * returns it. 171 - * However, if name does not need c_style quoting, it returns 0. 172 - * 173 - * (2) if sb or fp are not NULL, it emits the c_style quoted version 174 - * of name, enclosed with double quotes if asked and needed only. 175 - * Return value is the same as in (1). 176 - */ 177 - static size_t quote_c_style_counted(const char *name, ssize_t maxlen, 178 - struct strbuf *sb, FILE *fp, int no_dq) 179 - { 180 - #define EMIT(c) \ 181 - do { \ 182 - if (sb) strbuf_addch(sb, (c)); \ 183 - if (fp) fputc((c), fp); \ 184 - count++; \ 185 - } while (0) 186 - 187 - #define EMITBUF(s, l) \ 188 - do { \ 189 - int __ret; \ 190 - if (sb) strbuf_add(sb, (s), (l)); \ 191 - if (fp) __ret = fwrite((s), (l), 1, fp); \ 192 - count += (l); \ 193 - } while (0) 194 - 195 - ssize_t len, count = 0; 196 - const char *p = name; 197 - 198 - for (;;) { 199 - int ch; 200 - 201 - len = next_quote_pos(p, maxlen); 202 - if (len == maxlen || !p[len]) 203 - break; 204 - 205 - if (!no_dq && p == name) 206 - EMIT('"'); 207 - 208 - EMITBUF(p, len); 209 - EMIT('\\'); 210 - p += len; 211 - ch = (unsigned char)*p++; 212 - if (sq_lookup[ch] >= ' ') { 213 - EMIT(sq_lookup[ch]); 214 - } else { 215 - EMIT(((ch >> 6) & 03) + '0'); 216 - EMIT(((ch >> 3) & 07) + '0'); 217 - EMIT(((ch >> 0) & 07) + '0'); 218 - } 219 - } 220 - 221 - EMITBUF(p, len); 222 - if (p == name) /* no ending quote needed */ 223 - return 0; 224 - 225 - if (!no_dq) 226 - EMIT('"'); 227 - return count; 228 - } 229 - 230 - size_t quote_c_style(const char *name, struct strbuf *sb, FILE *fp, int nodq) 231 - { 232 - return quote_c_style_counted(name, -1, sb, fp, nodq); 233 - } 234 - 235 - void quote_two_c_style(struct strbuf *sb, const char *prefix, const char *path, int nodq) 236 - { 237 - if (quote_c_style(prefix, NULL, NULL, 0) || 238 - quote_c_style(path, NULL, NULL, 0)) { 239 - if (!nodq) 240 - strbuf_addch(sb, '"'); 241 - quote_c_style(prefix, sb, NULL, 1); 242 - quote_c_style(path, sb, NULL, 1); 243 - if (!nodq) 244 - strbuf_addch(sb, '"'); 245 - } else { 246 - strbuf_addstr(sb, prefix); 247 - strbuf_addstr(sb, path); 248 - } 249 - } 250 - 251 - void write_name_quoted(const char *name, FILE *fp, int terminator) 252 - { 253 - if (terminator) { 254 - quote_c_style(name, NULL, fp, 0); 255 - } else { 256 - fputs(name, fp); 257 - } 258 - fputc(terminator, fp); 259 - } 260 - 261 - void write_name_quotedpfx(const char *pfx, ssize_t pfxlen, 262 - const char *name, FILE *fp, int terminator) 263 - { 264 - int needquote = 0; 265 - 266 - if (terminator) { 267 - needquote = next_quote_pos(pfx, pfxlen) < pfxlen 268 - || name[next_quote_pos(name, -1)]; 269 - } 270 - if (needquote) { 271 - fputc('"', fp); 272 - quote_c_style_counted(pfx, pfxlen, NULL, fp, 1); 273 - quote_c_style(name, NULL, fp, 1); 274 - fputc('"', fp); 275 - } else { 276 - int ret; 277 - 278 - ret = fwrite(pfx, pfxlen, 1, fp); 279 - fputs(name, fp); 280 - } 281 - fputc(terminator, fp); 282 - } 283 - 284 - /* quote path as relative to the given prefix */ 285 - char *quote_path_relative(const char *in, int len, 286 - struct strbuf *out, const char *prefix) 287 - { 288 - int needquote; 289 - 290 - if (len < 0) 291 - len = strlen(in); 292 - 293 - /* "../" prefix itself does not need quoting, but "in" might. */ 294 - needquote = (next_quote_pos(in, len) < len); 295 - strbuf_setlen(out, 0); 296 - strbuf_grow(out, len); 297 - 298 - if (needquote) 299 - strbuf_addch(out, '"'); 300 - if (prefix) { 301 - int off = 0; 302 - while (off < len && prefix[off] && prefix[off] == in[off]) 303 - if (prefix[off] == '/') { 304 - prefix += off + 1; 305 - in += off + 1; 306 - len -= off + 1; 307 - off = 0; 308 - } else 309 - off++; 310 - 311 - for (; *prefix; prefix++) 312 - if (*prefix == '/') 313 - strbuf_addstr(out, "../"); 314 - } 315 - 316 - quote_c_style_counted (in, len, out, NULL, 1); 317 - 318 - if (needquote) 319 - strbuf_addch(out, '"'); 320 - if (!out->len) 321 - strbuf_addstr(out, "./"); 322 - 323 - return out->buf; 324 - } 325 - 326 - /* 327 - * C-style name unquoting. 328 - * 329 - * Quoted should point at the opening double quote. 330 - * + Returns 0 if it was able to unquote the string properly, and appends the 331 - * result in the strbuf `sb'. 332 - * + Returns -1 in case of error, and doesn't touch the strbuf. Though note 333 - * that this function will allocate memory in the strbuf, so calling 334 - * strbuf_release is mandatory whichever result unquote_c_style returns. 335 - * 336 - * Updates endp pointer to point at one past the ending double quote if given. 337 - */ 338 - int unquote_c_style(struct strbuf *sb, const char *quoted, const char **endp) 339 - { 340 - size_t oldlen = sb->len, len; 341 - int ch, ac; 342 - 343 - if (*quoted++ != '"') 344 - return -1; 345 - 346 - for (;;) { 347 - len = strcspn(quoted, "\"\\"); 348 - strbuf_add(sb, quoted, len); 349 - quoted += len; 350 - 351 - switch (*quoted++) { 352 - case '"': 353 - if (endp) 354 - *endp = quoted; 355 - return 0; 356 - case '\\': 357 - break; 358 - default: 359 - goto error; 360 - } 361 - 362 - switch ((ch = *quoted++)) { 363 - case 'a': ch = '\a'; break; 364 - case 'b': ch = '\b'; break; 365 - case 'f': ch = '\f'; break; 366 - case 'n': ch = '\n'; break; 367 - case 'r': ch = '\r'; break; 368 - case 't': ch = '\t'; break; 369 - case 'v': ch = '\v'; break; 370 - 371 - case '\\': case '"': 372 - break; /* verbatim */ 373 - 374 - /* octal values with first digit over 4 overflow */ 375 - case '0': case '1': case '2': case '3': 376 - ac = ((ch - '0') << 6); 377 - if ((ch = *quoted++) < '0' || '7' < ch) 378 - goto error; 379 - ac |= ((ch - '0') << 3); 380 - if ((ch = *quoted++) < '0' || '7' < ch) 381 - goto error; 382 - ac |= (ch - '0'); 383 - ch = ac; 384 - break; 385 - default: 386 - goto error; 387 - } 388 - strbuf_addch(sb, ch); 389 - } 390 - 391 - error: 392 - strbuf_setlen(sb, oldlen); 393 - return -1; 394 - } 395 - 396 - /* quoting as a string literal for other languages */ 397 - 398 - void perl_quote_print(FILE *stream, const char *src) 399 - { 400 - const char sq = '\''; 401 - const char bq = '\\'; 402 - char c; 403 - 404 - fputc(sq, stream); 405 - while ((c = *src++)) { 406 - if (c == sq || c == bq) 407 - fputc(bq, stream); 408 - fputc(c, stream); 409 - } 410 - fputc(sq, stream); 411 - } 412 - 413 - void python_quote_print(FILE *stream, const char *src) 414 - { 415 - const char sq = '\''; 416 - const char bq = '\\'; 417 - const char nl = '\n'; 418 - char c; 419 - 420 - fputc(sq, stream); 421 - while ((c = *src++)) { 422 - if (c == nl) { 423 - fputc(bq, stream); 424 - fputc('n', stream); 425 - continue; 426 - } 427 - if (c == sq || c == bq) 428 - fputc(bq, stream); 429 - fputc(c, stream); 430 - } 431 - fputc(sq, stream); 432 - } 433 - 434 - void tcl_quote_print(FILE *stream, const char *src) 435 - { 436 - char c; 437 - 438 - fputc('"', stream); 439 - while ((c = *src++)) { 440 - switch (c) { 441 - case '[': case ']': 442 - case '{': case '}': 443 - case '$': case '\\': case '"': 444 - fputc('\\', stream); 445 - default: 446 - fputc(c, stream); 447 - break; 448 - case '\f': 449 - fputs("\\f", stream); 450 - break; 451 - case '\r': 452 - fputs("\\r", stream); 453 - break; 454 - case '\n': 455 - fputs("\\n", stream); 456 - break; 457 - case '\t': 458 - fputs("\\t", stream); 459 - break; 460 - case '\v': 461 - fputs("\\v", stream); 462 - break; 463 - } 464 - } 465 - fputc('"', stream); 466 73 }
-39
tools/perf/util/quote.h
··· 22 22 * 23 23 * Note that the above examples leak memory! Remember to free result from 24 24 * sq_quote() in a real application. 25 - * 26 - * sq_quote_buf() writes to an existing buffer of specified size; it 27 - * will return the number of characters that would have been written 28 - * excluding the final null regardless of the buffer size. 29 25 */ 30 26 31 - extern void sq_quote_print(FILE *stream, const char *src); 32 - 33 - extern void sq_quote_buf(struct strbuf *, const char *src); 34 27 extern void sq_quote_argv(struct strbuf *, const char **argv, size_t maxlen); 35 - 36 - /* This unwraps what sq_quote() produces in place, but returns 37 - * NULL if the input does not look like what sq_quote would have 38 - * produced. 39 - */ 40 - extern char *sq_dequote(char *); 41 - 42 - /* 43 - * Same as the above, but can be used to unwrap many arguments in the 44 - * same string separated by space. "next" is changed to point to the 45 - * next argument that should be passed as first parameter. When there 46 - * is no more argument to be dequoted, "next" is updated to point to NULL. 47 - */ 48 - extern char *sq_dequote_step(char *arg, char **next); 49 - extern int sq_dequote_to_argv(char *arg, const char ***argv, int *nr, int *alloc); 50 - 51 - extern int unquote_c_style(struct strbuf *, const char *quoted, const char **endp); 52 - extern size_t quote_c_style(const char *name, struct strbuf *, FILE *, int no_dq); 53 - extern void quote_two_c_style(struct strbuf *, const char *, const char *, int); 54 - 55 - extern void write_name_quoted(const char *name, FILE *, int terminator); 56 - extern void write_name_quotedpfx(const char *pfx, ssize_t pfxlen, 57 - const char *name, FILE *, int terminator); 58 - 59 - /* quote path as relative to the given prefix */ 60 - char *quote_path_relative(const char *in, int len, 61 - struct strbuf *out, const char *prefix); 62 - 63 - /* quoting as a string literal for other languages */ 64 - extern void perl_quote_print(FILE *stream, const char *src); 65 - extern void python_quote_print(FILE *stream, const char *src); 66 - extern void tcl_quote_print(FILE *stream, const char *src); 67 28 68 29 #endif /* __PERF_QUOTE_H */
-90
tools/perf/util/run-command.c
··· 212 212 prepare_run_command_v_opt(&cmd, argv, opt); 213 213 return run_command(&cmd); 214 214 } 215 - 216 - int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const char *const *env) 217 - { 218 - struct child_process cmd; 219 - prepare_run_command_v_opt(&cmd, argv, opt); 220 - cmd.dir = dir; 221 - cmd.env = env; 222 - return run_command(&cmd); 223 - } 224 - 225 - int start_async(struct async *async) 226 - { 227 - int pipe_out[2]; 228 - 229 - if (pipe(pipe_out) < 0) 230 - return error("cannot create pipe: %s", strerror(errno)); 231 - async->out = pipe_out[0]; 232 - 233 - /* Flush stdio before fork() to avoid cloning buffers */ 234 - fflush(NULL); 235 - 236 - async->pid = fork(); 237 - if (async->pid < 0) { 238 - error("fork (async) failed: %s", strerror(errno)); 239 - close_pair(pipe_out); 240 - return -1; 241 - } 242 - if (!async->pid) { 243 - close(pipe_out[0]); 244 - exit(!!async->proc(pipe_out[1], async->data)); 245 - } 246 - close(pipe_out[1]); 247 - 248 - return 0; 249 - } 250 - 251 - int finish_async(struct async *async) 252 - { 253 - int ret = 0; 254 - 255 - if (wait_or_whine(async->pid)) 256 - ret = error("waitpid (async) failed"); 257 - 258 - return ret; 259 - } 260 - 261 - int run_hook(const char *index_file, const char *name, ...) 262 - { 263 - struct child_process hook; 264 - const char **argv = NULL, *env[2]; 265 - char idx[PATH_MAX]; 266 - va_list args; 267 - int ret; 268 - size_t i = 0, alloc = 0; 269 - 270 - if (access(perf_path("hooks/%s", name), X_OK) < 0) 271 - return 0; 272 - 273 - va_start(args, name); 274 - ALLOC_GROW(argv, i + 1, alloc); 275 - argv[i++] = perf_path("hooks/%s", name); 276 - while (argv[i-1]) { 277 - ALLOC_GROW(argv, i + 1, alloc); 278 - argv[i++] = va_arg(args, const char *); 279 - } 280 - va_end(args); 281 - 282 - memset(&hook, 0, sizeof(hook)); 283 - hook.argv = argv; 284 - hook.no_stdin = 1; 285 - hook.stdout_to_stderr = 1; 286 - if (index_file) { 287 - snprintf(idx, sizeof(idx), "PERF_INDEX_FILE=%s", index_file); 288 - env[0] = idx; 289 - env[1] = NULL; 290 - hook.env = env; 291 - } 292 - 293 - ret = start_command(&hook); 294 - free(argv); 295 - if (ret) { 296 - warning("Could not spawn %s", argv[0]); 297 - return ret; 298 - } 299 - ret = finish_command(&hook); 300 - if (ret == -ERR_RUN_COMMAND_WAITPID_SIGNAL) 301 - warning("%s exited due to uncaught signal", argv[0]); 302 - 303 - return ret; 304 - }
-30
tools/perf/util/run-command.h
··· 50 50 int finish_command(struct child_process *); 51 51 int run_command(struct child_process *); 52 52 53 - extern int run_hook(const char *index_file, const char *name, ...); 54 - 55 53 #define RUN_COMMAND_NO_STDIN 1 56 54 #define RUN_PERF_CMD 2 /*If this is to be perf sub-command */ 57 55 #define RUN_COMMAND_STDOUT_TO_STDERR 4 58 56 int run_command_v_opt(const char **argv, int opt); 59 - 60 - /* 61 - * env (the environment) is to be formatted like environ: "VAR=VALUE". 62 - * To unset an environment variable use just "VAR". 63 - */ 64 - int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const char *const *env); 65 - 66 - /* 67 - * The purpose of the following functions is to feed a pipe by running 68 - * a function asynchronously and providing output that the caller reads. 69 - * 70 - * It is expected that no synchronization and mutual exclusion between 71 - * the caller and the feed function is necessary so that the function 72 - * can run in a thread without interfering with the caller. 73 - */ 74 - struct async { 75 - /* 76 - * proc writes to fd and closes it; 77 - * returns 0 on success, non-zero on failure 78 - */ 79 - int (*proc)(int fd, void *data); 80 - void *data; 81 - int out; /* caller reads from here and closes it */ 82 - pid_t pid; 83 - }; 84 - 85 - int start_async(struct async *async); 86 - int finish_async(struct async *async); 87 57 88 58 #endif /* __PERF_RUN_COMMAND_H */
+1
tools/perf/util/session.c
··· 5 5 #include <byteswap.h> 6 6 #include <unistd.h> 7 7 #include <sys/types.h> 8 + #include <sys/mman.h> 8 9 9 10 #include "session.h" 10 11 #include "sort.h"
+1 -1
tools/perf/util/sigchain.c
··· 16 16 die("BUG: signal out of range: %d", sig); 17 17 } 18 18 19 - int sigchain_push(int sig, sigchain_fun f) 19 + static int sigchain_push(int sig, sigchain_fun f) 20 20 { 21 21 struct sigchain_signal *s = signals + sig; 22 22 check_signum(sig);
-1
tools/perf/util/sigchain.h
··· 3 3 4 4 typedef void (*sigchain_fun)(int); 5 5 6 - int sigchain_push(int sig, sigchain_fun f); 7 6 int sigchain_pop(int sig); 8 7 9 8 void sigchain_push_common(sigchain_fun f);
+1 -228
tools/perf/util/strbuf.c
··· 41 41 return res; 42 42 } 43 43 44 - void strbuf_attach(struct strbuf *sb, void *buf, size_t len, size_t alloc) 45 - { 46 - strbuf_release(sb); 47 - sb->buf = buf; 48 - sb->len = len; 49 - sb->alloc = alloc; 50 - strbuf_grow(sb, 0); 51 - sb->buf[sb->len] = '\0'; 52 - } 53 - 54 44 void strbuf_grow(struct strbuf *sb, size_t extra) 55 45 { 56 46 if (sb->len + extra + 1 <= sb->len) ··· 50 60 ALLOC_GROW(sb->buf, sb->len + extra + 1, sb->alloc); 51 61 } 52 62 53 - void strbuf_trim(struct strbuf *sb) 54 - { 55 - char *b = sb->buf; 56 - while (sb->len > 0 && isspace((unsigned char)sb->buf[sb->len - 1])) 57 - sb->len--; 58 - while (sb->len > 0 && isspace(*b)) { 59 - b++; 60 - sb->len--; 61 - } 62 - memmove(sb->buf, b, sb->len); 63 - sb->buf[sb->len] = '\0'; 64 - } 65 - void strbuf_rtrim(struct strbuf *sb) 66 - { 67 - while (sb->len > 0 && isspace((unsigned char)sb->buf[sb->len - 1])) 68 - sb->len--; 69 - sb->buf[sb->len] = '\0'; 70 - } 71 - 72 - void strbuf_ltrim(struct strbuf *sb) 73 - { 74 - char *b = sb->buf; 75 - while (sb->len > 0 && isspace(*b)) { 76 - b++; 77 - sb->len--; 78 - } 79 - memmove(sb->buf, b, sb->len); 80 - sb->buf[sb->len] = '\0'; 81 - } 82 - 83 - void strbuf_tolower(struct strbuf *sb) 84 - { 85 - unsigned int i; 86 - 87 - for (i = 0; i < sb->len; i++) 88 - sb->buf[i] = tolower(sb->buf[i]); 89 - } 90 - 91 - struct strbuf **strbuf_split(const struct strbuf *sb, int delim) 92 - { 93 - int alloc = 2, pos = 0; 94 - char *n, *p; 95 - struct strbuf **ret; 96 - struct strbuf *t; 97 - 98 - ret = calloc(alloc, sizeof(struct strbuf *)); 99 - p = n = sb->buf; 100 - while (n < sb->buf + sb->len) { 101 - int len; 102 - n = memchr(n, delim, sb->len - (n - sb->buf)); 103 - if (pos + 1 >= alloc) { 104 - alloc = alloc * 2; 105 - ret = realloc(ret, sizeof(struct strbuf *) * alloc); 106 - } 107 - if (!n) 108 - n = sb->buf + sb->len - 1; 109 - len = n - p + 1; 110 - t = malloc(sizeof(struct strbuf)); 111 - strbuf_init(t, len); 112 - strbuf_add(t, p, len); 113 - ret[pos] = t; 114 - ret[++pos] = NULL; 115 - p = ++n; 116 - } 117 - return ret; 118 - } 119 - 120 - void strbuf_list_free(struct strbuf **sbs) 121 - { 122 - struct strbuf **s = sbs; 123 - 124 - while (*s) { 125 - strbuf_release(*s); 126 - free(*s++); 127 - } 128 - free(sbs); 129 - } 130 - 131 - int strbuf_cmp(const struct strbuf *a, const struct strbuf *b) 132 - { 133 - int len = a->len < b->len ? a->len: b->len; 134 - int cmp = memcmp(a->buf, b->buf, len); 135 - if (cmp) 136 - return cmp; 137 - return a->len < b->len ? -1: a->len != b->len; 138 - } 139 - 140 - void strbuf_splice(struct strbuf *sb, size_t pos, size_t len, 63 + static void strbuf_splice(struct strbuf *sb, size_t pos, size_t len, 141 64 const void *data, size_t dlen) 142 65 { 143 66 if (pos + len < pos) ··· 69 166 strbuf_setlen(sb, sb->len + dlen - len); 70 167 } 71 168 72 - void strbuf_insert(struct strbuf *sb, size_t pos, const void *data, size_t len) 73 - { 74 - strbuf_splice(sb, pos, 0, data, len); 75 - } 76 - 77 169 void strbuf_remove(struct strbuf *sb, size_t pos, size_t len) 78 170 { 79 171 strbuf_splice(sb, pos, len, NULL, 0); ··· 78 180 { 79 181 strbuf_grow(sb, len); 80 182 memcpy(sb->buf + sb->len, data, len); 81 - strbuf_setlen(sb, sb->len + len); 82 - } 83 - 84 - void strbuf_adddup(struct strbuf *sb, size_t pos, size_t len) 85 - { 86 - strbuf_grow(sb, len); 87 - memcpy(sb->buf + sb->len, sb->buf + pos, len); 88 183 strbuf_setlen(sb, sb->len + len); 89 184 } 90 185 ··· 105 214 strbuf_setlen(sb, sb->len + len); 106 215 } 107 216 108 - void strbuf_expand(struct strbuf *sb, const char *format, expand_fn_t fn, 109 - void *context) 110 - { 111 - for (;;) { 112 - const char *percent; 113 - size_t consumed; 114 - 115 - percent = strchrnul(format, '%'); 116 - strbuf_add(sb, format, percent - format); 117 - if (!*percent) 118 - break; 119 - format = percent + 1; 120 - 121 - consumed = fn(sb, format, context); 122 - if (consumed) 123 - format += consumed; 124 - else 125 - strbuf_addch(sb, '%'); 126 - } 127 - } 128 - 129 - size_t strbuf_expand_dict_cb(struct strbuf *sb, const char *placeholder, 130 - void *context) 131 - { 132 - struct strbuf_expand_dict_entry *e = context; 133 - size_t len; 134 - 135 - for (; e->placeholder && (len = strlen(e->placeholder)); e++) { 136 - if (!strncmp(placeholder, e->placeholder, len)) { 137 - if (e->value) 138 - strbuf_addstr(sb, e->value); 139 - return len; 140 - } 141 - } 142 - return 0; 143 - } 144 - 145 - size_t strbuf_fread(struct strbuf *sb, size_t size, FILE *f) 146 - { 147 - size_t res; 148 - size_t oldalloc = sb->alloc; 149 - 150 - strbuf_grow(sb, size); 151 - res = fread(sb->buf + sb->len, 1, size, f); 152 - if (res > 0) 153 - strbuf_setlen(sb, sb->len + res); 154 - else if (oldalloc == 0) 155 - strbuf_release(sb); 156 - return res; 157 - } 158 - 159 217 ssize_t strbuf_read(struct strbuf *sb, int fd, ssize_t hint) 160 218 { 161 219 size_t oldlen = sb->len; ··· 130 290 131 291 sb->buf[sb->len] = '\0'; 132 292 return sb->len - oldlen; 133 - } 134 - 135 - #define STRBUF_MAXLINK (2*PATH_MAX) 136 - 137 - int strbuf_readlink(struct strbuf *sb, const char *path, ssize_t hint) 138 - { 139 - size_t oldalloc = sb->alloc; 140 - 141 - if (hint < 32) 142 - hint = 32; 143 - 144 - while (hint < STRBUF_MAXLINK) { 145 - ssize_t len; 146 - 147 - strbuf_grow(sb, hint); 148 - len = readlink(path, sb->buf, hint); 149 - if (len < 0) { 150 - if (errno != ERANGE) 151 - break; 152 - } else if (len < hint) { 153 - strbuf_setlen(sb, len); 154 - return 0; 155 - } 156 - 157 - /* .. the buffer was too small - try again */ 158 - hint *= 2; 159 - } 160 - if (oldalloc == 0) 161 - strbuf_release(sb); 162 - return -1; 163 - } 164 - 165 - int strbuf_getline(struct strbuf *sb, FILE *fp, int term) 166 - { 167 - int ch; 168 - 169 - strbuf_grow(sb, 0); 170 - if (feof(fp)) 171 - return EOF; 172 - 173 - strbuf_reset(sb); 174 - while ((ch = fgetc(fp)) != EOF) { 175 - if (ch == term) 176 - break; 177 - strbuf_grow(sb, 1); 178 - sb->buf[sb->len++] = ch; 179 - } 180 - if (ch == EOF && sb->len == 0) 181 - return EOF; 182 - 183 - sb->buf[sb->len] = '\0'; 184 - return 0; 185 - } 186 - 187 - int strbuf_read_file(struct strbuf *sb, const char *path, ssize_t hint) 188 - { 189 - int fd, len; 190 - 191 - fd = open(path, O_RDONLY); 192 - if (fd < 0) 193 - return -1; 194 - len = strbuf_read(sb, fd, hint); 195 - close(fd); 196 - if (len < 0) 197 - return -1; 198 - 199 - return len; 200 293 }
-45
tools/perf/util/strbuf.h
··· 53 53 extern void strbuf_init(struct strbuf *buf, ssize_t hint); 54 54 extern void strbuf_release(struct strbuf *); 55 55 extern char *strbuf_detach(struct strbuf *, size_t *); 56 - extern void strbuf_attach(struct strbuf *, void *, size_t, size_t); 57 - static inline void strbuf_swap(struct strbuf *a, struct strbuf *b) { 58 - struct strbuf tmp = *a; 59 - *a = *b; 60 - *b = tmp; 61 - } 62 56 63 57 /*----- strbuf size related -----*/ 64 58 static inline ssize_t strbuf_avail(const struct strbuf *sb) { ··· 68 74 sb->len = len; 69 75 sb->buf[len] = '\0'; 70 76 } 71 - #define strbuf_reset(sb) strbuf_setlen(sb, 0) 72 - 73 - /*----- content related -----*/ 74 - extern void strbuf_trim(struct strbuf *); 75 - extern void strbuf_rtrim(struct strbuf *); 76 - extern void strbuf_ltrim(struct strbuf *); 77 - extern int strbuf_cmp(const struct strbuf *, const struct strbuf *); 78 - extern void strbuf_tolower(struct strbuf *); 79 - 80 - extern struct strbuf **strbuf_split(const struct strbuf *, int delim); 81 - extern void strbuf_list_free(struct strbuf **); 82 77 83 78 /*----- add data in your buffer -----*/ 84 79 static inline void strbuf_addch(struct strbuf *sb, int c) { ··· 76 93 sb->buf[sb->len] = '\0'; 77 94 } 78 95 79 - extern void strbuf_insert(struct strbuf *, size_t pos, const void *, size_t); 80 96 extern void strbuf_remove(struct strbuf *, size_t pos, size_t len); 81 - 82 - /* splice pos..pos+len with given data */ 83 - extern void strbuf_splice(struct strbuf *, size_t pos, size_t len, 84 - const void *, size_t); 85 97 86 98 extern void strbuf_add(struct strbuf *, const void *, size_t); 87 99 static inline void strbuf_addstr(struct strbuf *sb, const char *s) { 88 100 strbuf_add(sb, s, strlen(s)); 89 101 } 90 - static inline void strbuf_addbuf(struct strbuf *sb, const struct strbuf *sb2) { 91 - strbuf_add(sb, sb2->buf, sb2->len); 92 - } 93 - extern void strbuf_adddup(struct strbuf *sb, size_t pos, size_t len); 94 - 95 - typedef size_t (*expand_fn_t) (struct strbuf *sb, const char *placeholder, void *context); 96 - extern void strbuf_expand(struct strbuf *sb, const char *format, expand_fn_t fn, void *context); 97 - struct strbuf_expand_dict_entry { 98 - const char *placeholder; 99 - const char *value; 100 - }; 101 - extern size_t strbuf_expand_dict_cb(struct strbuf *sb, const char *placeholder, void *context); 102 102 103 103 __attribute__((format(printf,2,3))) 104 104 extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...); 105 105 106 - extern size_t strbuf_fread(struct strbuf *, size_t, FILE *); 107 106 /* XXX: if read fails, any partial read is undone */ 108 107 extern ssize_t strbuf_read(struct strbuf *, int fd, ssize_t hint); 109 - extern int strbuf_read_file(struct strbuf *sb, const char *path, ssize_t hint); 110 - extern int strbuf_readlink(struct strbuf *sb, const char *path, ssize_t hint); 111 - 112 - extern int strbuf_getline(struct strbuf *, FILE *, int); 113 - 114 - extern void stripspace(struct strbuf *buf, int skip_comments); 115 - extern int launch_editor(const char *path, struct strbuf *buffer, const char *const *env); 116 - 117 - extern int strbuf_branchname(struct strbuf *sb, const char *name); 118 - extern int strbuf_check_branch_ref(struct strbuf *sb, const char *name); 119 108 120 109 #endif /* __PERF_STRBUF_H */
-154
tools/perf/util/util.h
··· 152 152 extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN); 153 153 154 154 extern int prefixcmp(const char *str, const char *prefix); 155 - extern time_t tm_to_time_t(const struct tm *tm); 156 155 157 156 static inline const char *skip_prefix(const char *str, const char *prefix) 158 157 { 159 158 size_t len = strlen(prefix); 160 159 return strncmp(str, prefix, len) ? NULL : str + len; 161 160 } 162 - 163 - #if defined(NO_MMAP) || defined(USE_WIN32_MMAP) 164 - 165 - #ifndef PROT_READ 166 - #define PROT_READ 1 167 - #define PROT_WRITE 2 168 - #define MAP_PRIVATE 1 169 - #define MAP_FAILED ((void*)-1) 170 - #endif 171 - 172 - #define mmap git_mmap 173 - #define munmap git_munmap 174 - extern void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset); 175 - extern int git_munmap(void *start, size_t length); 176 - 177 - #else /* NO_MMAP || USE_WIN32_MMAP */ 178 - 179 - #include <sys/mman.h> 180 - 181 - #endif /* NO_MMAP || USE_WIN32_MMAP */ 182 - 183 - #ifdef NO_MMAP 184 - 185 - /* This value must be multiple of (pagesize * 2) */ 186 - #define DEFAULT_PACKED_GIT_WINDOW_SIZE (1 * 1024 * 1024) 187 - 188 - #else /* NO_MMAP */ 189 - 190 - /* This value must be multiple of (pagesize * 2) */ 191 - #define DEFAULT_PACKED_GIT_WINDOW_SIZE \ 192 - (sizeof(void*) >= 8 \ 193 - ? 1 * 1024 * 1024 * 1024 \ 194 - : 32 * 1024 * 1024) 195 - 196 - #endif /* NO_MMAP */ 197 - 198 - #ifdef NO_ST_BLOCKS_IN_STRUCT_STAT 199 - #define on_disk_bytes(st) ((st).st_size) 200 - #else 201 - #define on_disk_bytes(st) ((st).st_blocks * 512) 202 - #endif 203 - 204 - #define DEFAULT_PACKED_GIT_LIMIT \ 205 - ((1024L * 1024L) * (sizeof(void*) >= 8 ? 8192 : 256)) 206 - 207 - #ifdef NO_PREAD 208 - #define pread git_pread 209 - extern ssize_t git_pread(int fd, void *buf, size_t count, off_t offset); 210 - #endif 211 - /* 212 - * Forward decl that will remind us if its twin in cache.h changes. 213 - * This function is used in compat/pread.c. But we can't include 214 - * cache.h there. 215 - */ 216 - extern ssize_t read_in_full(int fd, void *buf, size_t count); 217 - 218 - #ifdef NO_SETENV 219 - #define setenv gitsetenv 220 - extern int gitsetenv(const char *, const char *, int); 221 - #endif 222 - 223 - #ifdef NO_MKDTEMP 224 - #define mkdtemp gitmkdtemp 225 - extern char *gitmkdtemp(char *); 226 - #endif 227 - 228 - #ifdef NO_UNSETENV 229 - #define unsetenv gitunsetenv 230 - extern void gitunsetenv(const char *); 231 - #endif 232 - 233 - #ifdef NO_STRCASESTR 234 - #define strcasestr gitstrcasestr 235 - extern char *gitstrcasestr(const char *haystack, const char *needle); 236 - #endif 237 - 238 - #ifdef NO_STRLCPY 239 - #define strlcpy gitstrlcpy 240 - extern size_t gitstrlcpy(char *, const char *, size_t); 241 - #endif 242 - 243 - #ifdef NO_STRTOUMAX 244 - #define strtoumax gitstrtoumax 245 - extern uintmax_t gitstrtoumax(const char *, char **, int); 246 - #endif 247 - 248 - #ifdef NO_HSTRERROR 249 - #define hstrerror githstrerror 250 - extern const char *githstrerror(int herror); 251 - #endif 252 - 253 - #ifdef NO_MEMMEM 254 - #define memmem gitmemmem 255 - void *gitmemmem(const void *haystack, size_t haystacklen, 256 - const void *needle, size_t needlelen); 257 - #endif 258 - 259 - #ifdef FREAD_READS_DIRECTORIES 260 - #ifdef fopen 261 - #undef fopen 262 - #endif 263 - #define fopen(a,b) git_fopen(a,b) 264 - extern FILE *git_fopen(const char*, const char*); 265 - #endif 266 - 267 - #ifdef SNPRINTF_RETURNS_BOGUS 268 - #define snprintf git_snprintf 269 - extern int git_snprintf(char *str, size_t maxsize, 270 - const char *format, ...); 271 - #define vsnprintf git_vsnprintf 272 - extern int git_vsnprintf(char *str, size_t maxsize, 273 - const char *format, va_list ap); 274 - #endif 275 161 276 162 #ifdef __GLIBC_PREREQ 277 163 #if __GLIBC_PREREQ(2, 1) ··· 180 294 */ 181 295 extern char *xstrdup(const char *str); 182 296 extern void *xmalloc(size_t size) __attribute__((weak)); 183 - extern void *xmemdupz(const void *data, size_t len); 184 297 extern char *xstrndup(const char *str, size_t len); 185 298 extern void *xrealloc(void *ptr, size_t size) __attribute__((weak)); 186 299 ··· 193 308 static inline void *zalloc(size_t size) 194 309 { 195 310 return calloc(1, size); 196 - } 197 - 198 - static inline size_t xsize_t(off_t len) 199 - { 200 - return (size_t)len; 201 311 } 202 312 203 313 static inline int has_extension(const char *filename, const char *ext) ··· 231 351 #define isalpha(x) sane_istest(x,GIT_ALPHA) 232 352 #define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT) 233 353 #define isprint(x) sane_istest(x,GIT_PRINT) 234 - #define is_glob_special(x) sane_istest(x,GIT_GLOB_SPECIAL) 235 - #define is_regex_special(x) sane_istest(x,GIT_GLOB_SPECIAL | GIT_REGEX_SPECIAL) 236 354 #define tolower(x) sane_case((unsigned char)(x), 0x20) 237 355 #define toupper(x) sane_case((unsigned char)(x), 0) 238 356 ··· 240 362 x = (x & ~0x20) | high; 241 363 return x; 242 364 } 243 - 244 - static inline int strtoul_ui(char const *s, int base, unsigned int *result) 245 - { 246 - unsigned long ul; 247 - char *p; 248 - 249 - errno = 0; 250 - ul = strtoul(s, &p, base); 251 - if (errno || *p || p == s || (unsigned int) ul != ul) 252 - return -1; 253 - *result = ul; 254 - return 0; 255 - } 256 - 257 - static inline int strtol_i(char const *s, int base, int *result) 258 - { 259 - long ul; 260 - char *p; 261 - 262 - errno = 0; 263 - ul = strtol(s, &p, base); 264 - if (errno || *p || p == s || (int) ul != ul) 265 - return -1; 266 - *result = ul; 267 - return 0; 268 - } 269 - 270 - #ifdef INTERNAL_QSORT 271 - void git_qsort(void *base, size_t nmemb, size_t size, 272 - int(*compar)(const void *, const void *)); 273 - #define qsort git_qsort 274 - #endif 275 365 276 366 #ifndef DIR_HAS_BSD_GROUP_SEMANTICS 277 367 # define FORCE_DIR_SET_GID S_ISGID
+1 -71
tools/perf/util/wrapper.c
··· 48 48 * and returns a pointer to the allocated memory. If the allocation fails, 49 49 * the program dies. 50 50 */ 51 - void *xmemdupz(const void *data, size_t len) 51 + static void *xmemdupz(const void *data, size_t len) 52 52 { 53 53 char *p = xmalloc(len + 1); 54 54 memcpy(p, data, len); ··· 77 77 die("Out of memory, realloc failed"); 78 78 } 79 79 return ret; 80 - } 81 - 82 - /* 83 - * xread() is the same a read(), but it automatically restarts read() 84 - * operations with a recoverable error (EAGAIN and EINTR). xread() 85 - * DOES NOT GUARANTEE that "len" bytes is read even if the data is available. 86 - */ 87 - static ssize_t xread(int fd, void *buf, size_t len) 88 - { 89 - ssize_t nr; 90 - while (1) { 91 - nr = read(fd, buf, len); 92 - if ((nr < 0) && (errno == EAGAIN || errno == EINTR)) 93 - continue; 94 - return nr; 95 - } 96 - } 97 - 98 - /* 99 - * xwrite() is the same a write(), but it automatically restarts write() 100 - * operations with a recoverable error (EAGAIN and EINTR). xwrite() DOES NOT 101 - * GUARANTEE that "len" bytes is written even if the operation is successful. 102 - */ 103 - static ssize_t xwrite(int fd, const void *buf, size_t len) 104 - { 105 - ssize_t nr; 106 - while (1) { 107 - nr = write(fd, buf, len); 108 - if ((nr < 0) && (errno == EAGAIN || errno == EINTR)) 109 - continue; 110 - return nr; 111 - } 112 - } 113 - 114 - ssize_t read_in_full(int fd, void *buf, size_t count) 115 - { 116 - char *p = buf; 117 - ssize_t total = 0; 118 - 119 - while (count > 0) { 120 - ssize_t loaded = xread(fd, p, count); 121 - if (loaded <= 0) 122 - return total ? total : loaded; 123 - count -= loaded; 124 - p += loaded; 125 - total += loaded; 126 - } 127 - 128 - return total; 129 - } 130 - 131 - ssize_t write_in_full(int fd, const void *buf, size_t count) 132 - { 133 - const char *p = buf; 134 - ssize_t total = 0; 135 - 136 - while (count > 0) { 137 - ssize_t written = xwrite(fd, p, count); 138 - if (written < 0) 139 - return -1; 140 - if (!written) { 141 - errno = ENOSPC; 142 - return -1; 143 - } 144 - count -= written; 145 - p += written; 146 - total += written; 147 - } 148 - 149 - return total; 150 80 }