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 in = zconf_fopen(env); 364 if (in) { 365 conf_message("using defaults found in %s", 366 env); 367 goto load; 368 } 369 370 if (is_last) 371 break; 372 373 env = p + 1; 374 } 375 } 376 if (!in) 377 return 1; 378 379 load: 380 conf_filename = name; 381 conf_lineno = 0; 382 conf_warnings = 0; 383 384 def_flags = SYMBOL_DEF << def; 385 for_all_symbols(sym) { 386 sym->flags &= ~(def_flags|SYMBOL_VALID); 387 switch (sym->type) { 388 case S_INT: 389 case S_HEX: 390 case S_STRING: 391 free(sym->def[def].val); 392 /* fall through */ 393 default: 394 sym->def[def].val = NULL; 395 sym->def[def].tri = no; 396 } 397 } 398 399 expr_invalidate_all(); 400 401 while (getline_stripped(&line, &line_asize, in) != -1) { 402 struct menu *choice; 403 404 conf_lineno++; 405 406 if (!line[0]) /* blank line */ 407 continue; 408 409 if (line[0] == '#') { 410 if (line[1] != ' ') 411 continue; 412 p = line + 2; 413 if (memcmp(p, CONFIG_, strlen(CONFIG_))) 414 continue; 415 sym_name = p + strlen(CONFIG_); 416 p = strchr(sym_name, ' '); 417 if (!p) 418 continue; 419 *p++ = 0; 420 if (strcmp(p, "is not set")) 421 continue; 422 423 val = "n"; 424 } else { 425 if (memcmp(line, CONFIG_, strlen(CONFIG_))) { 426 conf_warning("unexpected data: %s", line); 427 continue; 428 } 429 430 sym_name = line + strlen(CONFIG_); 431 p = strchr(sym_name, '='); 432 if (!p) { 433 conf_warning("unexpected data: %s", line); 434 continue; 435 } 436 *p = 0; 437 val = p + 1; 438 } 439 440 sym = sym_find(sym_name); 441 if (!sym) { 442 if (def == S_DEF_AUTO) { 443 /* 444 * Reading from include/config/auto.conf. 445 * If CONFIG_FOO previously existed in auto.conf 446 * but it is missing now, include/config/FOO 447 * must be touched. 448 */ 449 conf_touch_dep(sym_name); 450 } else { 451 if (warn_unknown) 452 conf_warning("unknown symbol: %s", sym_name); 453 454 conf_set_changed(true); 455 } 456 continue; 457 } 458 459 if (sym->flags & def_flags) 460 conf_warning("override: reassigning to symbol %s", sym->name); 461 462 if (conf_set_sym_val(sym, def, def_flags, val)) 463 continue; 464 465 /* 466 * If this is a choice member, give it the highest priority. 467 * If conflicting CONFIG options are given from an input file, 468 * the last one wins. 469 */ 470 choice = sym_get_choice_menu(sym); 471 if (choice) 472 list_move(&sym->choice_link, &choice->choice_members); 473 } 474 free(line); 475 fclose(in); 476 477 return 0; 478 } 479 480 int conf_read(const char *name) 481 { 482 struct symbol *sym; 483 484 conf_set_changed(false); 485 486 if (conf_read_simple(name, S_DEF_USER)) { 487 sym_calc_value(modules_sym); 488 return 1; 489 } 490 491 sym_calc_value(modules_sym); 492 493 for_all_symbols(sym) { 494 sym_calc_value(sym); 495 if (sym_is_choice(sym)) 496 continue; 497 if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) { 498 /* check that calculated value agrees with saved value */ 499 switch (sym->type) { 500 case S_BOOLEAN: 501 case S_TRISTATE: 502 if (sym->def[S_DEF_USER].tri == sym_get_tristate_value(sym)) 503 continue; 504 break; 505 default: 506 if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val)) 507 continue; 508 break; 509 } 510 } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE)) 511 /* no previous value and not saved */ 512 continue; 513 conf_set_changed(true); 514 /* maybe print value in verbose mode... */ 515 } 516 517 if (conf_warnings) 518 conf_set_changed(true); 519 520 return 0; 521 } 522 523 struct comment_style { 524 const char *decoration; 525 const char *prefix; 526 const char *postfix; 527 }; 528 529 static const struct comment_style comment_style_pound = { 530 .decoration = "#", 531 .prefix = "#", 532 .postfix = "#", 533 }; 534 535 static const struct comment_style comment_style_c = { 536 .decoration = " *", 537 .prefix = "/*", 538 .postfix = " */", 539 }; 540 541 static void conf_write_heading(FILE *fp, const struct comment_style *cs) 542 { 543 if (!cs) 544 return; 545 546 fprintf(fp, "%s\n", cs->prefix); 547 548 fprintf(fp, "%s Automatically generated file; DO NOT EDIT.\n", 549 cs->decoration); 550 551 fprintf(fp, "%s %s\n", cs->decoration, rootmenu.prompt->text); 552 553 fprintf(fp, "%s\n", cs->postfix); 554 } 555 556 /* The returned pointer must be freed on the caller side */ 557 static char *escape_string_value(const char *in) 558 { 559 const char *p; 560 char *out; 561 size_t len; 562 563 len = strlen(in) + strlen("\"\"") + 1; 564 565 p = in; 566 while (1) { 567 p += strcspn(p, "\"\\"); 568 569 if (p[0] == '\0') 570 break; 571 572 len++; 573 p++; 574 } 575 576 out = xmalloc(len); 577 out[0] = '\0'; 578 579 strcat(out, "\""); 580 581 p = in; 582 while (1) { 583 len = strcspn(p, "\"\\"); 584 strncat(out, p, len); 585 p += len; 586 587 if (p[0] == '\0') 588 break; 589 590 strcat(out, "\\"); 591 strncat(out, p++, 1); 592 } 593 594 strcat(out, "\""); 595 596 return out; 597 } 598 599 enum output_n { OUTPUT_N, OUTPUT_N_AS_UNSET, OUTPUT_N_NONE }; 600 601 static void __print_symbol(FILE *fp, struct symbol *sym, enum output_n output_n, 602 bool escape_string) 603 { 604 const char *val; 605 char *escaped = NULL; 606 607 if (sym->type == S_UNKNOWN) 608 return; 609 610 val = sym_get_string_value(sym); 611 612 if ((sym->type == S_BOOLEAN || sym->type == S_TRISTATE) && 613 output_n != OUTPUT_N && *val == 'n') { 614 if (output_n == OUTPUT_N_AS_UNSET) 615 fprintf(fp, "# %s%s is not set\n", CONFIG_, sym->name); 616 return; 617 } 618 619 if (sym->type == S_STRING && escape_string) { 620 escaped = escape_string_value(val); 621 val = escaped; 622 } 623 624 fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, val); 625 626 free(escaped); 627 } 628 629 static void print_symbol_for_dotconfig(FILE *fp, struct symbol *sym) 630 { 631 __print_symbol(fp, sym, OUTPUT_N_AS_UNSET, true); 632 } 633 634 static void print_symbol_for_autoconf(FILE *fp, struct symbol *sym) 635 { 636 __print_symbol(fp, sym, OUTPUT_N_NONE, false); 637 } 638 639 void print_symbol_for_listconfig(struct symbol *sym) 640 { 641 __print_symbol(stdout, sym, OUTPUT_N, true); 642 } 643 644 static void print_symbol_for_c(FILE *fp, struct symbol *sym) 645 { 646 const char *val; 647 const char *sym_suffix = ""; 648 const char *val_prefix = ""; 649 char *escaped = NULL; 650 651 if (sym->type == S_UNKNOWN) 652 return; 653 654 val = sym_get_string_value(sym); 655 656 switch (sym->type) { 657 case S_BOOLEAN: 658 case S_TRISTATE: 659 switch (*val) { 660 case 'n': 661 return; 662 case 'm': 663 sym_suffix = "_MODULE"; 664 /* fall through */ 665 default: 666 val = "1"; 667 } 668 break; 669 case S_HEX: 670 if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X')) 671 val_prefix = "0x"; 672 break; 673 case S_STRING: 674 escaped = escape_string_value(val); 675 val = escaped; 676 default: 677 break; 678 } 679 680 fprintf(fp, "#define %s%s%s %s%s\n", CONFIG_, sym->name, sym_suffix, 681 val_prefix, val); 682 683 free(escaped); 684 } 685 686 static void print_symbol_for_rustccfg(FILE *fp, struct symbol *sym) 687 { 688 const char *val; 689 const char *val_prefix = ""; 690 char *val_prefixed = NULL; 691 size_t val_prefixed_len; 692 char *escaped = NULL; 693 694 if (sym->type == S_UNKNOWN) 695 return; 696 697 val = sym_get_string_value(sym); 698 699 switch (sym->type) { 700 case S_BOOLEAN: 701 case S_TRISTATE: 702 /* 703 * We do not care about disabled ones, i.e. no need for 704 * what otherwise are "comments" in other printers. 705 */ 706 if (*val == 'n') 707 return; 708 709 /* 710 * To have similar functionality to the C macro `IS_ENABLED()` 711 * we provide an empty `--cfg CONFIG_X` here in both `y` 712 * and `m` cases. 713 * 714 * Then, the common `fprintf()` below will also give us 715 * a `--cfg CONFIG_X="y"` or `--cfg CONFIG_X="m"`, which can 716 * be used as the equivalent of `IS_BUILTIN()`/`IS_MODULE()`. 717 */ 718 fprintf(fp, "--cfg=%s%s\n", CONFIG_, sym->name); 719 break; 720 case S_HEX: 721 if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X')) 722 val_prefix = "0x"; 723 break; 724 default: 725 break; 726 } 727 728 if (strlen(val_prefix) > 0) { 729 val_prefixed_len = strlen(val) + strlen(val_prefix) + 1; 730 val_prefixed = xmalloc(val_prefixed_len); 731 snprintf(val_prefixed, val_prefixed_len, "%s%s", val_prefix, val); 732 val = val_prefixed; 733 } 734 735 /* All values get escaped: the `--cfg` option only takes strings */ 736 escaped = escape_string_value(val); 737 val = escaped; 738 739 fprintf(fp, "--cfg=%s%s=%s\n", CONFIG_, sym->name, val); 740 741 free(escaped); 742 free(val_prefixed); 743 } 744 745 /* 746 * Write out a minimal config. 747 * All values that has default values are skipped as this is redundant. 748 */ 749 int conf_write_defconfig(const char *filename) 750 { 751 struct symbol *sym; 752 struct menu *menu; 753 FILE *out; 754 755 out = fopen(filename, "w"); 756 if (!out) 757 return 1; 758 759 sym_clear_all_valid(); 760 761 menu_for_each_entry(menu) { 762 struct menu *choice; 763 764 sym = menu->sym; 765 766 if (!sym || sym_is_choice(sym)) 767 continue; 768 769 sym_calc_value(sym); 770 if (!(sym->flags & SYMBOL_WRITE)) 771 continue; 772 sym->flags &= ~SYMBOL_WRITE; 773 /* Skip unchangeable symbols */ 774 if (!sym_is_changeable(sym)) 775 continue; 776 /* Skip symbols that are equal to the default */ 777 if (!strcmp(sym_get_string_value(sym), sym_get_string_default(sym))) 778 continue; 779 780 /* Skip choice values that are equal to the default */ 781 choice = sym_get_choice_menu(sym); 782 if (choice) { 783 struct symbol *ds; 784 785 ds = sym_choice_default(choice); 786 if (sym == ds && sym_get_tristate_value(sym) == yes) 787 continue; 788 } 789 print_symbol_for_dotconfig(out, sym); 790 } 791 fclose(out); 792 return 0; 793 } 794 795 int conf_write(const char *name) 796 { 797 FILE *out; 798 struct symbol *sym; 799 struct menu *menu; 800 const char *str; 801 char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1]; 802 char *env; 803 bool need_newline = false; 804 805 if (!name) 806 name = conf_get_configname(); 807 808 if (!*name) { 809 fprintf(stderr, "config name is empty\n"); 810 return -1; 811 } 812 813 if (is_dir(name)) { 814 fprintf(stderr, "%s: Is a directory\n", name); 815 return -1; 816 } 817 818 if (make_parent_dir(name)) 819 return -1; 820 821 env = getenv("KCONFIG_OVERWRITECONFIG"); 822 if (env && *env) { 823 *tmpname = 0; 824 out = fopen(name, "w"); 825 } else { 826 snprintf(tmpname, sizeof(tmpname), "%s.%d.tmp", 827 name, (int)getpid()); 828 out = fopen(tmpname, "w"); 829 } 830 if (!out) 831 return 1; 832 833 conf_write_heading(out, &comment_style_pound); 834 835 if (!conf_get_changed()) 836 sym_clear_all_valid(); 837 838 menu = rootmenu.list; 839 while (menu) { 840 sym = menu->sym; 841 if (!sym) { 842 if (!menu_is_visible(menu)) 843 goto next; 844 str = menu_get_prompt(menu); 845 fprintf(out, "\n" 846 "#\n" 847 "# %s\n" 848 "#\n", str); 849 need_newline = false; 850 } else if (!sym_is_choice(sym) && 851 !(sym->flags & SYMBOL_WRITTEN)) { 852 sym_calc_value(sym); 853 if (!(sym->flags & SYMBOL_WRITE)) 854 goto next; 855 if (need_newline) { 856 fprintf(out, "\n"); 857 need_newline = false; 858 } 859 sym->flags |= SYMBOL_WRITTEN; 860 print_symbol_for_dotconfig(out, sym); 861 } 862 863 next: 864 if (menu->list) { 865 menu = menu->list; 866 continue; 867 } 868 869 end_check: 870 if (!menu->sym && menu_is_visible(menu) && menu != &rootmenu && 871 menu->prompt->type == P_MENU) { 872 fprintf(out, "# end of %s\n", menu_get_prompt(menu)); 873 need_newline = true; 874 } 875 876 if (menu->next) { 877 menu = menu->next; 878 } else { 879 menu = menu->parent; 880 if (menu) 881 goto end_check; 882 } 883 } 884 fclose(out); 885 886 for_all_symbols(sym) 887 sym->flags &= ~SYMBOL_WRITTEN; 888 889 if (*tmpname) { 890 if (is_same(name, tmpname)) { 891 conf_message("No change to %s", name); 892 unlink(tmpname); 893 conf_set_changed(false); 894 return 0; 895 } 896 897 snprintf(oldname, sizeof(oldname), "%s.old", name); 898 rename(name, oldname); 899 if (rename(tmpname, name)) 900 return 1; 901 } 902 903 conf_message("configuration written to %s", name); 904 905 conf_set_changed(false); 906 907 return 0; 908 } 909 910 /* write a dependency file as used by kbuild to track dependencies */ 911 static int conf_write_autoconf_cmd(const char *autoconf_name) 912 { 913 char name[PATH_MAX], tmp[PATH_MAX]; 914 FILE *out; 915 int ret; 916 917 ret = snprintf(name, sizeof(name), "%s.cmd", autoconf_name); 918 if (ret >= sizeof(name)) /* check truncation */ 919 return -1; 920 921 if (make_parent_dir(name)) 922 return -1; 923 924 ret = snprintf(tmp, sizeof(tmp), "%s.cmd.tmp", autoconf_name); 925 if (ret >= sizeof(tmp)) /* check truncation */ 926 return -1; 927 928 out = fopen(tmp, "w"); 929 if (!out) { 930 perror("fopen"); 931 return -1; 932 } 933 934 fprintf(out, "autoconfig := %s\n", autoconf_name); 935 936 fputs(str_get(&autoconf_cmd), out); 937 938 fflush(out); 939 ret = ferror(out); /* error check for all fprintf() calls */ 940 fclose(out); 941 if (ret) 942 return -1; 943 944 if (rename(tmp, name)) { 945 perror("rename"); 946 return -1; 947 } 948 949 return 0; 950 } 951 952 static int conf_touch_deps(void) 953 { 954 const char *name, *tmp; 955 struct symbol *sym; 956 int res; 957 958 name = conf_get_autoconfig_name(); 959 tmp = strrchr(name, '/'); 960 depfile_prefix_len = tmp ? tmp - name + 1 : 0; 961 if (depfile_prefix_len + 1 > sizeof(depfile_path)) 962 return -1; 963 964 strncpy(depfile_path, name, depfile_prefix_len); 965 depfile_path[depfile_prefix_len] = 0; 966 967 conf_read_simple(name, S_DEF_AUTO); 968 sym_calc_value(modules_sym); 969 970 for_all_symbols(sym) { 971 sym_calc_value(sym); 972 if (sym_is_choice(sym)) 973 continue; 974 if (sym->flags & SYMBOL_WRITE) { 975 if (sym->flags & SYMBOL_DEF_AUTO) { 976 /* 977 * symbol has old and new value, 978 * so compare them... 979 */ 980 switch (sym->type) { 981 case S_BOOLEAN: 982 case S_TRISTATE: 983 if (sym_get_tristate_value(sym) == 984 sym->def[S_DEF_AUTO].tri) 985 continue; 986 break; 987 case S_STRING: 988 case S_HEX: 989 case S_INT: 990 if (!strcmp(sym_get_string_value(sym), 991 sym->def[S_DEF_AUTO].val)) 992 continue; 993 break; 994 default: 995 break; 996 } 997 } else { 998 /* 999 * If there is no old value, only 'no' (unset) 1000 * is allowed as new value. 1001 */ 1002 switch (sym->type) { 1003 case S_BOOLEAN: 1004 case S_TRISTATE: 1005 if (sym_get_tristate_value(sym) == no) 1006 continue; 1007 break; 1008 default: 1009 break; 1010 } 1011 } 1012 } else if (!(sym->flags & SYMBOL_DEF_AUTO)) 1013 /* There is neither an old nor a new value. */ 1014 continue; 1015 /* else 1016 * There is an old value, but no new value ('no' (unset) 1017 * isn't saved in auto.conf, so the old value is always 1018 * different from 'no'). 1019 */ 1020 1021 res = conf_touch_dep(sym->name); 1022 if (res) 1023 return res; 1024 } 1025 1026 return 0; 1027 } 1028 1029 static int __conf_write_autoconf(const char *filename, 1030 void (*print_symbol)(FILE *, struct symbol *), 1031 const struct comment_style *comment_style) 1032 { 1033 char tmp[PATH_MAX]; 1034 FILE *file; 1035 struct symbol *sym; 1036 int ret; 1037 1038 if (make_parent_dir(filename)) 1039 return -1; 1040 1041 ret = snprintf(tmp, sizeof(tmp), "%s.tmp", filename); 1042 if (ret >= sizeof(tmp)) /* check truncation */ 1043 return -1; 1044 1045 file = fopen(tmp, "w"); 1046 if (!file) { 1047 perror("fopen"); 1048 return -1; 1049 } 1050 1051 conf_write_heading(file, comment_style); 1052 1053 for_all_symbols(sym) 1054 if ((sym->flags & SYMBOL_WRITE) && sym->name) 1055 print_symbol(file, sym); 1056 1057 fflush(file); 1058 /* check possible errors in conf_write_heading() and print_symbol() */ 1059 ret = ferror(file); 1060 fclose(file); 1061 if (ret) 1062 return -1; 1063 1064 if (rename(tmp, filename)) { 1065 perror("rename"); 1066 return -1; 1067 } 1068 1069 return 0; 1070 } 1071 1072 int conf_write_autoconf(int overwrite) 1073 { 1074 struct symbol *sym; 1075 const char *autoconf_name = conf_get_autoconfig_name(); 1076 int ret; 1077 1078 if (!overwrite && is_present(autoconf_name)) 1079 return 0; 1080 1081 ret = conf_write_autoconf_cmd(autoconf_name); 1082 if (ret) 1083 return -1; 1084 1085 if (conf_touch_deps()) 1086 return 1; 1087 1088 for_all_symbols(sym) 1089 sym_calc_value(sym); 1090 1091 ret = __conf_write_autoconf(conf_get_autoheader_name(), 1092 print_symbol_for_c, 1093 &comment_style_c); 1094 if (ret) 1095 return ret; 1096 1097 ret = __conf_write_autoconf(conf_get_rustccfg_name(), 1098 print_symbol_for_rustccfg, 1099 NULL); 1100 if (ret) 1101 return ret; 1102 1103 /* 1104 * Create include/config/auto.conf. This must be the last step because 1105 * Kbuild has a dependency on auto.conf and this marks the successful 1106 * completion of the previous steps. 1107 */ 1108 ret = __conf_write_autoconf(conf_get_autoconfig_name(), 1109 print_symbol_for_autoconf, 1110 &comment_style_pound); 1111 if (ret) 1112 return ret; 1113 1114 return 0; 1115 } 1116 1117 static bool conf_changed; 1118 static void (*conf_changed_callback)(bool); 1119 1120 void conf_set_changed(bool val) 1121 { 1122 if (conf_changed_callback && conf_changed != val) 1123 conf_changed_callback(val); 1124 1125 conf_changed = val; 1126 } 1127 1128 bool conf_get_changed(void) 1129 { 1130 return conf_changed; 1131 } 1132 1133 void conf_set_changed_callback(void (*fn)(bool)) 1134 { 1135 conf_changed_callback = fn; 1136 } 1137