1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> 4 */ 5 6 #include <sys/mman.h> 7 #include <sys/stat.h> 8 #include <sys/types.h> 9 #include <ctype.h> 10 #include <errno.h> 11 #include <fcntl.h> 12 #include <limits.h> 13 #include <stdarg.h> 14 #include <stdbool.h> 15 #include <stdio.h> 16 #include <stdlib.h> 17 #include <string.h> 18 #include <time.h> 19 #include <unistd.h> 20 21 #include <xalloc.h> 22 #include "internal.h" 23 #include "lkc.h" 24 25 struct gstr autoconf_cmd; 26 27 /* return true if 'path' exists, false otherwise */ 28 static bool is_present(const char *path) 29 { 30 struct stat st; 31 32 return !stat(path, &st); 33 } 34 35 /* return true if 'path' exists and it is a directory, false otherwise */ 36 static bool is_dir(const char *path) 37 { 38 struct stat st; 39 40 if (stat(path, &st)) 41 return false; 42 43 return S_ISDIR(st.st_mode); 44 } 45 46 /* return true if the given two files are the same, false otherwise */ 47 static bool is_same(const char *file1, const char *file2) 48 { 49 int fd1, fd2; 50 struct stat st1, st2; 51 void *map1, *map2; 52 bool ret = false; 53 54 fd1 = open(file1, O_RDONLY); 55 if (fd1 < 0) 56 return ret; 57 58 fd2 = open(file2, O_RDONLY); 59 if (fd2 < 0) 60 goto close1; 61 62 ret = fstat(fd1, &st1); 63 if (ret) 64 goto close2; 65 ret = fstat(fd2, &st2); 66 if (ret) 67 goto close2; 68 69 if (st1.st_size != st2.st_size) 70 goto close2; 71 72 map1 = mmap(NULL, st1.st_size, PROT_READ, MAP_PRIVATE, fd1, 0); 73 if (map1 == MAP_FAILED) 74 goto close2; 75 76 map2 = mmap(NULL, st2.st_size, PROT_READ, MAP_PRIVATE, fd2, 0); 77 if (map2 == MAP_FAILED) 78 goto close2; 79 80 if (bcmp(map1, map2, st1.st_size)) 81 goto close2; 82 83 ret = true; 84 close2: 85 close(fd2); 86 close1: 87 close(fd1); 88 89 return ret; 90 } 91 92 /* 93 * Create the parent directory of the given path. 94 * 95 * For example, if 'include/config/auto.conf' is given, create 'include/config'. 96 */ 97 static int make_parent_dir(const char *path) 98 { 99 char tmp[PATH_MAX + 1]; 100 char *p; 101 102 strncpy(tmp, path, sizeof(tmp)); 103 tmp[sizeof(tmp) - 1] = 0; 104 105 /* Remove the base name. Just return if nothing is left */ 106 p = strrchr(tmp, '/'); 107 if (!p) 108 return 0; 109 *(p + 1) = 0; 110 111 /* Just in case it is an absolute path */ 112 p = tmp; 113 while (*p == '/') 114 p++; 115 116 while ((p = strchr(p, '/'))) { 117 *p = 0; 118 119 /* skip if the directory exists */ 120 if (!is_dir(tmp) && mkdir(tmp, 0755)) 121 return -1; 122 123 *p = '/'; 124 while (*p == '/') 125 p++; 126 } 127 128 return 0; 129 } 130 131 static char depfile_path[PATH_MAX]; 132 static size_t depfile_prefix_len; 133 134 /* touch depfile for symbol 'name' */ 135 static int conf_touch_dep(const char *name) 136 { 137 int fd; 138 139 /* check overflow: prefix + name + '\0' must fit in buffer. */ 140 if (depfile_prefix_len + strlen(name) + 1 > sizeof(depfile_path)) 141 return -1; 142 143 strcpy(depfile_path + depfile_prefix_len, name); 144 145 fd = open(depfile_path, O_WRONLY | O_CREAT | O_TRUNC, 0644); 146 if (fd == -1) 147 return -1; 148 close(fd); 149 150 return 0; 151 } 152 153 static void conf_warning(const char *fmt, ...) 154 __attribute__ ((format (printf, 1, 2))); 155 156 static void conf_message(const char *fmt, ...) 157 __attribute__ ((format (printf, 1, 2))); 158 159 static const char *conf_filename; 160 static int conf_lineno, conf_warnings; 161 162 bool conf_errors(void) 163 { 164 if (conf_warnings) 165 return getenv("KCONFIG_WERROR"); 166 return false; 167 } 168 169 static void conf_warning(const char *fmt, ...) 170 { 171 va_list ap; 172 va_start(ap, fmt); 173 fprintf(stderr, "%s:%d:warning: ", conf_filename, conf_lineno); 174 vfprintf(stderr, fmt, ap); 175 fprintf(stderr, "\n"); 176 va_end(ap); 177 conf_warnings++; 178 } 179 180 static void conf_default_message_callback(const char *s) 181 { 182 printf("#\n# "); 183 printf("%s", s); 184 printf("\n#\n"); 185 } 186 187 static void (*conf_message_callback)(const char *s) = 188 conf_default_message_callback; 189 void conf_set_message_callback(void (*fn)(const char *s)) 190 { 191 conf_message_callback = fn; 192 } 193 194 static void conf_message(const char *fmt, ...) 195 { 196 va_list ap; 197 char buf[4096]; 198 199 if (!conf_message_callback) 200 return; 201 202 va_start(ap, fmt); 203 204 vsnprintf(buf, sizeof(buf), fmt, ap); 205 conf_message_callback(buf); 206 va_end(ap); 207 } 208 209 const char *conf_get_configname(void) 210 { 211 char *name = getenv("KCONFIG_CONFIG"); 212 213 return name ? name : ".config"; 214 } 215 216 static const char *conf_get_autoconfig_name(void) 217 { 218 char *name = getenv("KCONFIG_AUTOCONFIG"); 219 220 return name ? name : "include/config/auto.conf"; 221 } 222 223 static const char *conf_get_autoheader_name(void) 224 { 225 char *name = getenv("KCONFIG_AUTOHEADER"); 226 227 return name ? name : "include/generated/autoconf.h"; 228 } 229 230 static const char *conf_get_rustccfg_name(void) 231 { 232 char *name = getenv("KCONFIG_RUSTCCFG"); 233 234 return name ? name : "include/generated/rustc_cfg"; 235 } 236 237 static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) 238 { 239 char *p2; 240 241 switch (sym->type) { 242 case S_TRISTATE: 243 if (p[0] == 'm') { 244 sym->def[def].tri = mod; 245 sym->flags |= def_flags; 246 break; 247 } 248 /* fall through */ 249 case S_BOOLEAN: 250 if (p[0] == 'y') { 251 sym->def[def].tri = yes; 252 sym->flags |= def_flags; 253 break; 254 } 255 if (p[0] == 'n') { 256 sym->def[def].tri = no; 257 sym->flags |= def_flags; 258 break; 259 } 260 if (def != S_DEF_AUTO) 261 conf_warning("symbol value '%s' invalid for %s", 262 p, sym->name); 263 return 1; 264 case S_STRING: 265 /* No escaping for S_DEF_AUTO (include/config/auto.conf) */ 266 if (def != S_DEF_AUTO) { 267 if (*p++ != '"') 268 break; 269 for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) { 270 if (*p2 == '"') { 271 *p2 = 0; 272 break; 273 } 274 memmove(p2, p2 + 1, strlen(p2)); 275 } 276 if (!p2) { 277 conf_warning("invalid string found"); 278 return 1; 279 } 280 } 281 /* fall through */ 282 case S_INT: 283 case S_HEX: 284 if (sym_string_valid(sym, p)) { 285 sym->def[def].val = xstrdup(p); 286 sym->flags |= def_flags; 287 } else { 288 if (def != S_DEF_AUTO) 289 conf_warning("symbol value '%s' invalid for %s", 290 p, sym->name); 291 return 1; 292 } 293 break; 294 default: 295 ; 296 } 297 return 0; 298 } 299 300 /* like getline(), but the newline character is stripped away */ 301 static ssize_t getline_stripped(char **lineptr, size_t *n, FILE *stream) 302 { 303 ssize_t len; 304 305 len = getline(lineptr, n, stream); 306 307 if (len > 0 && (*lineptr)[len - 1] == '\n') { 308 len--; 309 (*lineptr)[len] = '\0'; 310 311 if (len > 0 && (*lineptr)[len - 1] == '\r') { 312 len--; 313 (*lineptr)[len] = '\0'; 314 } 315 } 316 317 return len; 318 } 319 320 int conf_read_simple(const char *name, int def) 321 { 322 FILE *in = NULL; 323 char *line = NULL; 324 size_t line_asize = 0; 325 char *p, *val; 326 struct symbol *sym; 327 int def_flags; 328 const char *warn_unknown, *sym_name; 329 330 warn_unknown = getenv("KCONFIG_WARN_UNKNOWN_SYMBOLS"); 331 if (name) { 332 in = zconf_fopen(name); 333 } else { 334 char *env; 335 336 name = conf_get_configname(); 337 in = zconf_fopen(name); 338 if (in) 339 goto load; 340 conf_set_changed(true); 341 342 env = getenv("KCONFIG_DEFCONFIG_LIST"); 343 if (!env) 344 return 1; 345 346 while (1) { 347 bool is_last; 348 349 while (isspace(*env)) 350 env++; 351 352 if (!*env) 353 break; 354 355 p = env; 356 while (*p && !isspace(*p)) 357 p++; 358 359 is_last = (*p == '\0'); 360 361 *p = '\0'; 362 363 name = env; 364 365 in = zconf_fopen(name); 366 if (in) { 367 conf_message("using defaults found in %s", 368 name); 369 goto load; 370 } 371 372 if (is_last) 373 break; 374 375 env = p + 1; 376 } 377 } 378 if (!in) 379 return 1; 380 381 load: 382 conf_filename = name; 383 conf_lineno = 0; 384 conf_warnings = 0; 385 386 def_flags = SYMBOL_DEF << def; 387 for_all_symbols(sym) { 388 sym->flags &= ~(def_flags|SYMBOL_VALID); 389 switch (sym->type) { 390 case S_INT: 391 case S_HEX: 392 case S_STRING: 393 free(sym->def[def].val); 394 /* fall through */ 395 default: 396 sym->def[def].val = NULL; 397 sym->def[def].tri = no; 398 } 399 } 400 401 expr_invalidate_all(); 402 403 while (getline_stripped(&line, &line_asize, in) != -1) { 404 struct menu *choice; 405 406 conf_lineno++; 407 408 if (!line[0]) /* blank line */ 409 continue; 410 411 if (line[0] == '#') { 412 if (line[1] != ' ') 413 continue; 414 p = line + 2; 415 if (memcmp(p, CONFIG_, strlen(CONFIG_))) 416 continue; 417 sym_name = p + strlen(CONFIG_); 418 p = strchr(sym_name, ' '); 419 if (!p) 420 continue; 421 *p++ = 0; 422 if (strcmp(p, "is not set")) 423 continue; 424 425 val = "n"; 426 } else { 427 if (memcmp(line, CONFIG_, strlen(CONFIG_))) { 428 conf_warning("unexpected data: %s", line); 429 continue; 430 } 431 432 sym_name = line + strlen(CONFIG_); 433 p = strchr(sym_name, '='); 434 if (!p) { 435 conf_warning("unexpected data: %s", line); 436 continue; 437 } 438 *p = 0; 439 val = p + 1; 440 } 441 442 sym = sym_find(sym_name); 443 if (!sym) { 444 if (def == S_DEF_AUTO) { 445 /* 446 * Reading from include/config/auto.conf. 447 * If CONFIG_FOO previously existed in auto.conf 448 * but it is missing now, include/config/FOO 449 * must be touched. 450 */ 451 conf_touch_dep(sym_name); 452 } else { 453 if (warn_unknown) 454 conf_warning("unknown symbol: %s", sym_name); 455 456 conf_set_changed(true); 457 } 458 continue; 459 } 460 461 if (sym->flags & def_flags) 462 conf_warning("override: reassigning to symbol %s", sym->name); 463 464 if (conf_set_sym_val(sym, def, def_flags, val)) 465 continue; 466 467 /* 468 * If this is a choice member, give it the highest priority. 469 * If conflicting CONFIG options are given from an input file, 470 * the last one wins. 471 */ 472 choice = sym_get_choice_menu(sym); 473 if (choice) 474 list_move(&sym->choice_link, &choice->choice_members); 475 } 476 free(line); 477 fclose(in); 478 479 return 0; 480 } 481 482 int conf_read(const char *name) 483 { 484 struct symbol *sym; 485 486 conf_set_changed(false); 487 488 if (conf_read_simple(name, S_DEF_USER)) { 489 sym_calc_value(modules_sym); 490 return 1; 491 } 492 493 sym_calc_value(modules_sym); 494 495 for_all_symbols(sym) { 496 sym_calc_value(sym); 497 if (sym_is_choice(sym)) 498 continue; 499 if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) { 500 /* check that calculated value agrees with saved value */ 501 switch (sym->type) { 502 case S_BOOLEAN: 503 case S_TRISTATE: 504 if (sym->def[S_DEF_USER].tri == sym_get_tristate_value(sym)) 505 continue; 506 break; 507 default: 508 if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val)) 509 continue; 510 break; 511 } 512 } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE)) 513 /* no previous value and not saved */ 514 continue; 515 conf_set_changed(true); 516 /* maybe print value in verbose mode... */ 517 } 518 519 if (conf_warnings) 520 conf_set_changed(true); 521 522 return 0; 523 } 524 525 struct comment_style { 526 const char *decoration; 527 const char *prefix; 528 const char *postfix; 529 }; 530 531 static const struct comment_style comment_style_pound = { 532 .decoration = "#", 533 .prefix = "#", 534 .postfix = "#", 535 }; 536 537 static const struct comment_style comment_style_c = { 538 .decoration = " *", 539 .prefix = "/*", 540 .postfix = " */", 541 }; 542 543 static void conf_write_heading(FILE *fp, const struct comment_style *cs) 544 { 545 if (!cs) 546 return; 547 548 fprintf(fp, "%s\n", cs->prefix); 549 550 fprintf(fp, "%s Automatically generated file; DO NOT EDIT.\n", 551 cs->decoration); 552 553 fprintf(fp, "%s %s\n", cs->decoration, rootmenu.prompt->text); 554 555 fprintf(fp, "%s\n", cs->postfix); 556 } 557 558 /* The returned pointer must be freed on the caller side */ 559 static char *escape_string_value(const char *in) 560 { 561 const char *p; 562 char *out; 563 size_t len; 564 565 len = strlen(in) + strlen("\"\"") + 1; 566 567 p = in; 568 while (1) { 569 p += strcspn(p, "\"\\"); 570 571 if (p[0] == '\0') 572 break; 573 574 len++; 575 p++; 576 } 577 578 out = xmalloc(len); 579 out[0] = '\0'; 580 581 strcat(out, "\""); 582 583 p = in; 584 while (1) { 585 len = strcspn(p, "\"\\"); 586 strncat(out, p, len); 587 p += len; 588 589 if (p[0] == '\0') 590 break; 591 592 strcat(out, "\\"); 593 strncat(out, p++, 1); 594 } 595 596 strcat(out, "\""); 597 598 return out; 599 } 600 601 enum output_n { OUTPUT_N, OUTPUT_N_AS_UNSET, OUTPUT_N_NONE }; 602 603 static void __print_symbol(FILE *fp, struct symbol *sym, enum output_n output_n, 604 bool escape_string) 605 { 606 const char *val; 607 char *escaped = NULL; 608 609 if (sym->type == S_UNKNOWN) 610 return; 611 612 val = sym_get_string_value(sym); 613 614 if ((sym->type == S_BOOLEAN || sym->type == S_TRISTATE) && 615 output_n != OUTPUT_N && *val == 'n') { 616 if (output_n == OUTPUT_N_AS_UNSET) 617 fprintf(fp, "# %s%s is not set\n", CONFIG_, sym->name); 618 return; 619 } 620 621 if (sym->type == S_STRING && escape_string) { 622 escaped = escape_string_value(val); 623 val = escaped; 624 } 625 626 fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, val); 627 628 free(escaped); 629 } 630 631 static void print_symbol_for_dotconfig(FILE *fp, struct symbol *sym) 632 { 633 __print_symbol(fp, sym, OUTPUT_N_AS_UNSET, true); 634 } 635 636 static void print_symbol_for_autoconf(FILE *fp, struct symbol *sym) 637 { 638 __print_symbol(fp, sym, OUTPUT_N_NONE, false); 639 } 640 641 void print_symbol_for_listconfig(struct symbol *sym) 642 { 643 __print_symbol(stdout, sym, OUTPUT_N, true); 644 } 645 646 static void print_symbol_for_c(FILE *fp, struct symbol *sym) 647 { 648 const char *val; 649 const char *sym_suffix = ""; 650 const char *val_prefix = ""; 651 char *escaped = NULL; 652 653 if (sym->type == S_UNKNOWN) 654 return; 655 656 val = sym_get_string_value(sym); 657 658 switch (sym->type) { 659 case S_BOOLEAN: 660 case S_TRISTATE: 661 switch (*val) { 662 case 'n': 663 return; 664 case 'm': 665 sym_suffix = "_MODULE"; 666 /* fall through */ 667 default: 668 val = "1"; 669 } 670 break; 671 case S_HEX: 672 if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X')) 673 val_prefix = "0x"; 674 break; 675 case S_STRING: 676 escaped = escape_string_value(val); 677 val = escaped; 678 default: 679 break; 680 } 681 682 fprintf(fp, "#define %s%s%s %s%s\n", CONFIG_, sym->name, sym_suffix, 683 val_prefix, val); 684 685 free(escaped); 686 } 687 688 static void print_symbol_for_rustccfg(FILE *fp, struct symbol *sym) 689 { 690 const char *val; 691 const char *val_prefix = ""; 692 char *val_prefixed = NULL; 693 size_t val_prefixed_len; 694 char *escaped = NULL; 695 696 if (sym->type == S_UNKNOWN) 697 return; 698 699 val = sym_get_string_value(sym); 700 701 switch (sym->type) { 702 case S_BOOLEAN: 703 case S_TRISTATE: 704 /* 705 * We do not care about disabled ones, i.e. no need for 706 * what otherwise are "comments" in other printers. 707 */ 708 if (*val == 'n') 709 return; 710 711 /* 712 * To have similar functionality to the C macro `IS_ENABLED()` 713 * we provide an empty `--cfg CONFIG_X` here in both `y` 714 * and `m` cases. 715 * 716 * Then, the common `fprintf()` below will also give us 717 * a `--cfg CONFIG_X="y"` or `--cfg CONFIG_X="m"`, which can 718 * be used as the equivalent of `IS_BUILTIN()`/`IS_MODULE()`. 719 */ 720 fprintf(fp, "--cfg=%s%s\n", CONFIG_, sym->name); 721 break; 722 case S_HEX: 723 if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X')) 724 val_prefix = "0x"; 725 break; 726 default: 727 break; 728 } 729 730 if (strlen(val_prefix) > 0) { 731 val_prefixed_len = strlen(val) + strlen(val_prefix) + 1; 732 val_prefixed = xmalloc(val_prefixed_len); 733 snprintf(val_prefixed, val_prefixed_len, "%s%s", val_prefix, val); 734 val = val_prefixed; 735 } 736 737 /* All values get escaped: the `--cfg` option only takes strings */ 738 escaped = escape_string_value(val); 739 val = escaped; 740 741 fprintf(fp, "--cfg=%s%s=%s\n", CONFIG_, sym->name, val); 742 743 free(escaped); 744 free(val_prefixed); 745 } 746 747 /* 748 * Write out a minimal config. 749 * All values that has default values are skipped as this is redundant. 750 */ 751 int conf_write_defconfig(const char *filename) 752 { 753 struct symbol *sym; 754 struct menu *menu; 755 FILE *out; 756 757 out = fopen(filename, "w"); 758 if (!out) 759 return 1; 760 761 sym_clear_all_valid(); 762 763 menu_for_each_entry(menu) { 764 struct menu *choice; 765 766 sym = menu->sym; 767 768 if (!sym || sym_is_choice(sym)) 769 continue; 770 771 sym_calc_value(sym); 772 if (!(sym->flags & SYMBOL_WRITE)) 773 continue; 774 sym->flags &= ~SYMBOL_WRITE; 775 /* Skip unchangeable symbols */ 776 if (!sym_is_changeable(sym)) 777 continue; 778 /* Skip symbols that are equal to the default */ 779 if (!strcmp(sym_get_string_value(sym), sym_get_string_default(sym))) 780 continue; 781 782 /* Skip choice values that are equal to the default */ 783 choice = sym_get_choice_menu(sym); 784 if (choice) { 785 struct symbol *ds; 786 787 ds = sym_choice_default(choice); 788 if (sym == ds && sym_get_tristate_value(sym) == yes) 789 continue; 790 } 791 print_symbol_for_dotconfig(out, sym); 792 } 793 fclose(out); 794 return 0; 795 } 796 797 int conf_write(const char *name) 798 { 799 FILE *out; 800 struct symbol *sym; 801 struct menu *menu; 802 const char *str; 803 char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1]; 804 char *env; 805 bool need_newline = false; 806 807 if (!name) 808 name = conf_get_configname(); 809 810 if (!*name) { 811 fprintf(stderr, "config name is empty\n"); 812 return -1; 813 } 814 815 if (is_dir(name)) { 816 fprintf(stderr, "%s: Is a directory\n", name); 817 return -1; 818 } 819 820 if (make_parent_dir(name)) 821 return -1; 822 823 env = getenv("KCONFIG_OVERWRITECONFIG"); 824 if (env && *env) { 825 *tmpname = 0; 826 out = fopen(name, "w"); 827 } else { 828 snprintf(tmpname, sizeof(tmpname), "%s.%d.tmp", 829 name, (int)getpid()); 830 out = fopen(tmpname, "w"); 831 } 832 if (!out) 833 return 1; 834 835 conf_write_heading(out, &comment_style_pound); 836 837 if (!conf_get_changed()) 838 sym_clear_all_valid(); 839 840 menu = rootmenu.list; 841 while (menu) { 842 sym = menu->sym; 843 if (!sym) { 844 if (!menu_is_visible(menu)) 845 goto next; 846 str = menu_get_prompt(menu); 847 fprintf(out, "\n" 848 "#\n" 849 "# %s\n" 850 "#\n", str); 851 need_newline = false; 852 } else if (!sym_is_choice(sym) && 853 !(sym->flags & SYMBOL_WRITTEN)) { 854 sym_calc_value(sym); 855 if (!(sym->flags & SYMBOL_WRITE)) 856 goto next; 857 if (need_newline) { 858 fprintf(out, "\n"); 859 need_newline = false; 860 } 861 sym->flags |= SYMBOL_WRITTEN; 862 print_symbol_for_dotconfig(out, sym); 863 } 864 865 next: 866 if (menu->list) { 867 menu = menu->list; 868 continue; 869 } 870 871 end_check: 872 if (!menu->sym && menu_is_visible(menu) && menu != &rootmenu && 873 menu->prompt->type == P_MENU) { 874 fprintf(out, "# end of %s\n", menu_get_prompt(menu)); 875 need_newline = true; 876 } 877 878 if (menu->next) { 879 menu = menu->next; 880 } else { 881 menu = menu->parent; 882 if (menu) 883 goto end_check; 884 } 885 } 886 fclose(out); 887 888 for_all_symbols(sym) 889 sym->flags &= ~SYMBOL_WRITTEN; 890 891 if (*tmpname) { 892 if (is_same(name, tmpname)) { 893 conf_message("No change to %s", name); 894 unlink(tmpname); 895 conf_set_changed(false); 896 return 0; 897 } 898 899 snprintf(oldname, sizeof(oldname), "%s.old", name); 900 rename(name, oldname); 901 if (rename(tmpname, name)) 902 return 1; 903 } 904 905 conf_message("configuration written to %s", name); 906 907 conf_set_changed(false); 908 909 return 0; 910 } 911 912 /* write a dependency file as used by kbuild to track dependencies */ 913 static int conf_write_autoconf_cmd(const char *autoconf_name) 914 { 915 char name[PATH_MAX], tmp[PATH_MAX]; 916 FILE *out; 917 int ret; 918 919 ret = snprintf(name, sizeof(name), "%s.cmd", autoconf_name); 920 if (ret >= sizeof(name)) /* check truncation */ 921 return -1; 922 923 if (make_parent_dir(name)) 924 return -1; 925 926 ret = snprintf(tmp, sizeof(tmp), "%s.cmd.tmp", autoconf_name); 927 if (ret >= sizeof(tmp)) /* check truncation */ 928 return -1; 929 930 out = fopen(tmp, "w"); 931 if (!out) { 932 perror("fopen"); 933 return -1; 934 } 935 936 fprintf(out, "autoconfig := %s\n", autoconf_name); 937 938 fputs(str_get(&autoconf_cmd), out); 939 940 fflush(out); 941 ret = ferror(out); /* error check for all fprintf() calls */ 942 fclose(out); 943 if (ret) 944 return -1; 945 946 if (rename(tmp, name)) { 947 perror("rename"); 948 return -1; 949 } 950 951 return 0; 952 } 953 954 static int conf_touch_deps(void) 955 { 956 const char *name, *tmp; 957 struct symbol *sym; 958 int res; 959 960 name = conf_get_autoconfig_name(); 961 tmp = strrchr(name, '/'); 962 depfile_prefix_len = tmp ? tmp - name + 1 : 0; 963 if (depfile_prefix_len + 1 > sizeof(depfile_path)) 964 return -1; 965 966 strncpy(depfile_path, name, depfile_prefix_len); 967 depfile_path[depfile_prefix_len] = 0; 968 969 conf_read_simple(name, S_DEF_AUTO); 970 sym_calc_value(modules_sym); 971 972 for_all_symbols(sym) { 973 sym_calc_value(sym); 974 if (sym_is_choice(sym)) 975 continue; 976 if (sym->flags & SYMBOL_WRITE) { 977 if (sym->flags & SYMBOL_DEF_AUTO) { 978 /* 979 * symbol has old and new value, 980 * so compare them... 981 */ 982 switch (sym->type) { 983 case S_BOOLEAN: 984 case S_TRISTATE: 985 if (sym_get_tristate_value(sym) == 986 sym->def[S_DEF_AUTO].tri) 987 continue; 988 break; 989 case S_STRING: 990 case S_HEX: 991 case S_INT: 992 if (!strcmp(sym_get_string_value(sym), 993 sym->def[S_DEF_AUTO].val)) 994 continue; 995 break; 996 default: 997 break; 998 } 999 } else { 1000 /* 1001 * If there is no old value, only 'no' (unset) 1002 * is allowed as new value. 1003 */ 1004 switch (sym->type) { 1005 case S_BOOLEAN: 1006 case S_TRISTATE: 1007 if (sym_get_tristate_value(sym) == no) 1008 continue; 1009 break; 1010 default: 1011 break; 1012 } 1013 } 1014 } else if (!(sym->flags & SYMBOL_DEF_AUTO)) 1015 /* There is neither an old nor a new value. */ 1016 continue; 1017 /* else 1018 * There is an old value, but no new value ('no' (unset) 1019 * isn't saved in auto.conf, so the old value is always 1020 * different from 'no'). 1021 */ 1022 1023 res = conf_touch_dep(sym->name); 1024 if (res) 1025 return res; 1026 } 1027 1028 return 0; 1029 } 1030 1031 static int __conf_write_autoconf(const char *filename, 1032 void (*print_symbol)(FILE *, struct symbol *), 1033 const struct comment_style *comment_style) 1034 { 1035 char tmp[PATH_MAX]; 1036 FILE *file; 1037 struct symbol *sym; 1038 int ret; 1039 1040 if (make_parent_dir(filename)) 1041 return -1; 1042 1043 ret = snprintf(tmp, sizeof(tmp), "%s.tmp", filename); 1044 if (ret >= sizeof(tmp)) /* check truncation */ 1045 return -1; 1046 1047 file = fopen(tmp, "w"); 1048 if (!file) { 1049 perror("fopen"); 1050 return -1; 1051 } 1052 1053 conf_write_heading(file, comment_style); 1054 1055 for_all_symbols(sym) 1056 if ((sym->flags & SYMBOL_WRITE) && sym->name) 1057 print_symbol(file, sym); 1058 1059 fflush(file); 1060 /* check possible errors in conf_write_heading() and print_symbol() */ 1061 ret = ferror(file); 1062 fclose(file); 1063 if (ret) 1064 return -1; 1065 1066 if (rename(tmp, filename)) { 1067 perror("rename"); 1068 return -1; 1069 } 1070 1071 return 0; 1072 } 1073 1074 int conf_write_autoconf(int overwrite) 1075 { 1076 struct symbol *sym; 1077 const char *autoconf_name = conf_get_autoconfig_name(); 1078 int ret; 1079 1080 if (!overwrite && is_present(autoconf_name)) 1081 return 0; 1082 1083 ret = conf_write_autoconf_cmd(autoconf_name); 1084 if (ret) 1085 return -1; 1086 1087 if (conf_touch_deps()) 1088 return 1; 1089 1090 for_all_symbols(sym) 1091 sym_calc_value(sym); 1092 1093 ret = __conf_write_autoconf(conf_get_autoheader_name(), 1094 print_symbol_for_c, 1095 &comment_style_c); 1096 if (ret) 1097 return ret; 1098 1099 ret = __conf_write_autoconf(conf_get_rustccfg_name(), 1100 print_symbol_for_rustccfg, 1101 NULL); 1102 if (ret) 1103 return ret; 1104 1105 /* 1106 * Create include/config/auto.conf. This must be the last step because 1107 * Kbuild has a dependency on auto.conf and this marks the successful 1108 * completion of the previous steps. 1109 */ 1110 ret = __conf_write_autoconf(conf_get_autoconfig_name(), 1111 print_symbol_for_autoconf, 1112 &comment_style_pound); 1113 if (ret) 1114 return ret; 1115 1116 return 0; 1117 } 1118 1119 static bool conf_changed; 1120 static void (*conf_changed_callback)(bool); 1121 1122 void conf_set_changed(bool val) 1123 { 1124 if (conf_changed_callback && conf_changed != val) 1125 conf_changed_callback(val); 1126 1127 conf_changed = val; 1128 } 1129 1130 bool conf_get_changed(void) 1131 { 1132 return conf_changed; 1133 } 1134 1135 void conf_set_changed_callback(void (*fn)(bool)) 1136 { 1137 conf_changed_callback = fn; 1138 } 1139