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 (memcmp(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 static void conf_changed_input_warning(const char *s) 210 { 211 fputs(s, stderr); 212 } 213 214 static bool conf_warn_changed_input_enabled(void) 215 { 216 const char *env = getenv("KCONFIG_WARN_CHANGED_INPUT"); 217 218 return env && *env; 219 } 220 221 static const char *sym_get_user_value_string(struct symbol *sym) 222 { 223 switch (sym->type) { 224 case S_BOOLEAN: 225 case S_TRISTATE: 226 switch (sym->def[S_DEF_USER].tri) { 227 case yes: 228 return "y"; 229 case mod: 230 return "m"; 231 default: 232 return "n"; 233 } 234 default: 235 return sym->def[S_DEF_USER].val ?: ""; 236 } 237 } 238 239 static bool sym_user_value_changed(struct symbol *sym) 240 { 241 if (!sym_has_value(sym) || sym->type == S_UNKNOWN) 242 return false; 243 244 switch (sym->type) { 245 case S_BOOLEAN: 246 case S_TRISTATE: 247 return sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym); 248 default: 249 return strcmp(sym_get_user_value_string(sym), 250 sym_get_string_value(sym)); 251 } 252 } 253 254 static void conf_clear_written_flags(void) 255 { 256 struct symbol *sym; 257 258 for_all_symbols(sym) 259 sym->flags &= ~SYMBOL_WRITTEN; 260 } 261 262 static void conf_append_changed_input_warning(struct gstr *gs, 263 struct symbol *sym, 264 bool *changed_input_found) 265 { 266 if (!sym_user_value_changed(sym)) 267 return; 268 269 if (!*changed_input_found) { 270 str_printf(gs, 271 "warning: user-provided values changed by Kconfig:\n"); 272 *changed_input_found = true; 273 } 274 275 str_printf(gs, " %s%s: %s -> %s\n", 276 CONFIG_, sym->name, 277 sym_get_user_value_string(sym), 278 sym_get_string_value(sym)); 279 } 280 281 const char *conf_get_configname(void) 282 { 283 char *name = getenv("KCONFIG_CONFIG"); 284 285 return name ? name : ".config"; 286 } 287 288 static const char *conf_get_autoconfig_name(void) 289 { 290 char *name = getenv("KCONFIG_AUTOCONFIG"); 291 292 return name ? name : "include/config/auto.conf"; 293 } 294 295 static const char *conf_get_autoheader_name(void) 296 { 297 char *name = getenv("KCONFIG_AUTOHEADER"); 298 299 return name ? name : "include/generated/autoconf.h"; 300 } 301 302 static const char *conf_get_rustccfg_name(void) 303 { 304 char *name = getenv("KCONFIG_RUSTCCFG"); 305 306 return name ? name : "include/generated/rustc_cfg"; 307 } 308 309 static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) 310 { 311 char *p2; 312 313 switch (sym->type) { 314 case S_TRISTATE: 315 if (p[0] == 'm') { 316 sym->def[def].tri = mod; 317 sym->flags |= def_flags; 318 break; 319 } 320 /* fall through */ 321 case S_BOOLEAN: 322 if (p[0] == 'y') { 323 sym->def[def].tri = yes; 324 sym->flags |= def_flags; 325 break; 326 } 327 if (p[0] == 'n') { 328 sym->def[def].tri = no; 329 sym->flags |= def_flags; 330 break; 331 } 332 if (def != S_DEF_AUTO) 333 conf_warning("symbol value '%s' invalid for %s", 334 p, sym->name); 335 return 1; 336 case S_STRING: 337 /* No escaping for S_DEF_AUTO (include/config/auto.conf) */ 338 if (def != S_DEF_AUTO) { 339 if (*p++ != '"') 340 break; 341 for (p2 = p; (p2 = strpbrk(p2, "\"\\")); p2++) { 342 if (*p2 == '"') { 343 *p2 = 0; 344 break; 345 } 346 memmove(p2, p2 + 1, strlen(p2)); 347 } 348 if (!p2) { 349 conf_warning("invalid string found"); 350 return 1; 351 } 352 } 353 /* fall through */ 354 case S_INT: 355 case S_HEX: 356 if (sym_string_valid(sym, p)) { 357 sym->def[def].val = xstrdup(p); 358 sym->flags |= def_flags; 359 } else { 360 if (def != S_DEF_AUTO) 361 conf_warning("symbol value '%s' invalid for %s", 362 p, sym->name); 363 return 1; 364 } 365 break; 366 default: 367 ; 368 } 369 return 0; 370 } 371 372 /* like getline(), but the newline character is stripped away */ 373 static ssize_t getline_stripped(char **lineptr, size_t *n, FILE *stream) 374 { 375 ssize_t len; 376 377 len = getline(lineptr, n, stream); 378 379 if (len > 0 && (*lineptr)[len - 1] == '\n') { 380 len--; 381 (*lineptr)[len] = '\0'; 382 383 if (len > 0 && (*lineptr)[len - 1] == '\r') { 384 len--; 385 (*lineptr)[len] = '\0'; 386 } 387 } 388 389 return len; 390 } 391 392 int conf_read_simple(const char *name, int def) 393 { 394 FILE *in = NULL; 395 char *line = NULL; 396 size_t line_asize = 0; 397 char *p, *val; 398 struct symbol *sym; 399 int def_flags; 400 const char *warn_unknown, *sym_name; 401 402 warn_unknown = getenv("KCONFIG_WARN_UNKNOWN_SYMBOLS"); 403 if (name) { 404 in = zconf_fopen(name); 405 } else { 406 char *env; 407 408 name = conf_get_configname(); 409 in = zconf_fopen(name); 410 if (in) 411 goto load; 412 conf_set_changed(true); 413 414 env = getenv("KCONFIG_DEFCONFIG_LIST"); 415 if (!env) 416 return 1; 417 418 while (1) { 419 bool is_last; 420 421 while (isspace(*env)) 422 env++; 423 424 if (!*env) 425 break; 426 427 p = env; 428 while (*p && !isspace(*p)) 429 p++; 430 431 is_last = (*p == '\0'); 432 433 *p = '\0'; 434 435 name = env; 436 437 in = zconf_fopen(name); 438 if (in) { 439 conf_message("using defaults found in %s", 440 name); 441 goto load; 442 } 443 444 if (is_last) 445 break; 446 447 env = p + 1; 448 } 449 } 450 if (!in) 451 return 1; 452 453 load: 454 conf_filename = name; 455 conf_lineno = 0; 456 conf_warnings = 0; 457 458 def_flags = SYMBOL_DEF << def; 459 for_all_symbols(sym) { 460 sym->flags &= ~def_flags; 461 switch (sym->type) { 462 case S_INT: 463 case S_HEX: 464 case S_STRING: 465 free(sym->def[def].val); 466 /* fall through */ 467 default: 468 sym->def[def].val = NULL; 469 sym->def[def].tri = no; 470 } 471 } 472 473 if (def == S_DEF_USER) { 474 for_all_symbols(sym) 475 sym->flags &= ~SYMBOL_VALID; 476 expr_invalidate_all(); 477 } 478 479 while (getline_stripped(&line, &line_asize, in) != -1) { 480 struct menu *choice; 481 482 conf_lineno++; 483 484 if (!line[0]) /* blank line */ 485 continue; 486 487 if (line[0] == '#') { 488 if (line[1] != ' ') 489 continue; 490 p = line + 2; 491 if (memcmp(p, CONFIG_, strlen(CONFIG_))) 492 continue; 493 sym_name = p + strlen(CONFIG_); 494 p = strchr(sym_name, ' '); 495 if (!p) 496 continue; 497 *p++ = 0; 498 if (strcmp(p, "is not set")) 499 continue; 500 501 val = "n"; 502 } else { 503 if (memcmp(line, CONFIG_, strlen(CONFIG_))) { 504 conf_warning("unexpected data: %s", line); 505 continue; 506 } 507 508 sym_name = line + strlen(CONFIG_); 509 p = strchr(sym_name, '='); 510 if (!p) { 511 conf_warning("unexpected data: %s", line); 512 continue; 513 } 514 *p = 0; 515 val = p + 1; 516 } 517 518 sym = sym_find(sym_name); 519 if (!sym) { 520 if (def == S_DEF_AUTO) { 521 /* 522 * Reading from include/config/auto.conf. 523 * If CONFIG_FOO previously existed in auto.conf 524 * but it is missing now, include/config/FOO 525 * must be touched. 526 */ 527 conf_touch_dep(sym_name); 528 } else { 529 if (warn_unknown) 530 conf_warning("unknown symbol: %s", sym_name); 531 532 conf_set_changed(true); 533 } 534 continue; 535 } 536 537 if (sym->flags & def_flags) 538 conf_warning("override: reassigning to symbol %s", sym->name); 539 540 if (conf_set_sym_val(sym, def, def_flags, val)) 541 continue; 542 543 if (def != S_DEF_USER) 544 continue; 545 546 /* 547 * If this is a choice member, give it the highest priority. 548 * If conflicting CONFIG options are given from an input file, 549 * the last one wins. 550 */ 551 choice = sym_get_choice_menu(sym); 552 if (choice) 553 list_move(&sym->choice_link, &choice->choice_members); 554 } 555 free(line); 556 fclose(in); 557 558 return 0; 559 } 560 561 int conf_read(const char *name) 562 { 563 struct symbol *sym; 564 565 conf_set_changed(false); 566 567 if (conf_read_simple(name, S_DEF_USER)) { 568 sym_calc_value(modules_sym); 569 return 1; 570 } 571 572 sym_calc_value(modules_sym); 573 574 for_all_symbols(sym) { 575 sym_calc_value(sym); 576 if (sym_is_choice(sym)) 577 continue; 578 if (sym_has_value(sym) && (sym->flags & SYMBOL_WRITE)) { 579 /* check that calculated value agrees with saved value */ 580 switch (sym->type) { 581 case S_BOOLEAN: 582 case S_TRISTATE: 583 if (sym->def[S_DEF_USER].tri == sym_get_tristate_value(sym)) 584 continue; 585 break; 586 default: 587 if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val)) 588 continue; 589 break; 590 } 591 } else if (!sym_has_value(sym) && !(sym->flags & SYMBOL_WRITE)) 592 /* no previous value and not saved */ 593 continue; 594 conf_set_changed(true); 595 /* maybe print value in verbose mode... */ 596 } 597 598 if (conf_warnings) 599 conf_set_changed(true); 600 601 return 0; 602 } 603 604 struct comment_style { 605 const char *decoration; 606 const char *prefix; 607 const char *postfix; 608 }; 609 610 static const struct comment_style comment_style_pound = { 611 .decoration = "#", 612 .prefix = "#", 613 .postfix = "#", 614 }; 615 616 static const struct comment_style comment_style_c = { 617 .decoration = " *", 618 .prefix = "/*", 619 .postfix = " */", 620 }; 621 622 static void conf_write_heading(FILE *fp, const struct comment_style *cs) 623 { 624 if (!cs) 625 return; 626 627 fprintf(fp, "%s\n", cs->prefix); 628 629 fprintf(fp, "%s Automatically generated file; DO NOT EDIT.\n", 630 cs->decoration); 631 632 fprintf(fp, "%s %s\n", cs->decoration, rootmenu.prompt->text); 633 634 fprintf(fp, "%s\n", cs->postfix); 635 } 636 637 /* The returned pointer must be freed on the caller side */ 638 static char *escape_string_value(const char *in) 639 { 640 const char *p; 641 char *out; 642 size_t len; 643 644 len = strlen(in) + strlen("\"\"") + 1; 645 646 p = in; 647 while (1) { 648 p += strcspn(p, "\"\\"); 649 650 if (p[0] == '\0') 651 break; 652 653 len++; 654 p++; 655 } 656 657 out = xmalloc(len); 658 out[0] = '\0'; 659 660 strcat(out, "\""); 661 662 p = in; 663 while (1) { 664 len = strcspn(p, "\"\\"); 665 strncat(out, p, len); 666 p += len; 667 668 if (p[0] == '\0') 669 break; 670 671 strcat(out, "\\"); 672 strncat(out, p++, 1); 673 } 674 675 strcat(out, "\""); 676 677 return out; 678 } 679 680 enum output_n { OUTPUT_N, OUTPUT_N_AS_UNSET, OUTPUT_N_NONE }; 681 682 static void __print_symbol(FILE *fp, struct symbol *sym, enum output_n output_n, 683 bool escape_string) 684 { 685 const char *val; 686 char *escaped = NULL; 687 688 if (sym->type == S_UNKNOWN) 689 return; 690 691 val = sym_get_string_value(sym); 692 693 if ((sym->type == S_BOOLEAN || sym->type == S_TRISTATE) && 694 output_n != OUTPUT_N && *val == 'n') { 695 if (output_n == OUTPUT_N_AS_UNSET) 696 fprintf(fp, "# %s%s is not set\n", CONFIG_, sym->name); 697 return; 698 } 699 700 if (sym->type == S_STRING && escape_string) { 701 escaped = escape_string_value(val); 702 val = escaped; 703 } 704 705 fprintf(fp, "%s%s=%s\n", CONFIG_, sym->name, val); 706 707 free(escaped); 708 } 709 710 static void print_symbol_for_dotconfig(FILE *fp, struct symbol *sym) 711 { 712 __print_symbol(fp, sym, OUTPUT_N_AS_UNSET, true); 713 } 714 715 static void print_symbol_for_autoconf(FILE *fp, struct symbol *sym) 716 { 717 __print_symbol(fp, sym, OUTPUT_N_NONE, false); 718 } 719 720 void print_symbol_for_listconfig(struct symbol *sym) 721 { 722 __print_symbol(stdout, sym, OUTPUT_N, true); 723 } 724 725 static void print_symbol_for_c(FILE *fp, struct symbol *sym) 726 { 727 const char *val; 728 const char *sym_suffix = ""; 729 const char *val_prefix = ""; 730 char *escaped = NULL; 731 732 if (sym->type == S_UNKNOWN) 733 return; 734 735 val = sym_get_string_value(sym); 736 737 switch (sym->type) { 738 case S_BOOLEAN: 739 case S_TRISTATE: 740 switch (*val) { 741 case 'n': 742 return; 743 case 'm': 744 sym_suffix = "_MODULE"; 745 /* fall through */ 746 default: 747 val = "1"; 748 } 749 break; 750 case S_HEX: 751 if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X')) 752 val_prefix = "0x"; 753 break; 754 case S_STRING: 755 escaped = escape_string_value(val); 756 val = escaped; 757 default: 758 break; 759 } 760 761 fprintf(fp, "#define %s%s%s %s%s\n", CONFIG_, sym->name, sym_suffix, 762 val_prefix, val); 763 764 free(escaped); 765 } 766 767 static void print_symbol_for_rustccfg(FILE *fp, struct symbol *sym) 768 { 769 const char *val; 770 const char *val_prefix = ""; 771 char *val_prefixed = NULL; 772 size_t val_prefixed_len; 773 char *escaped = NULL; 774 775 if (sym->type == S_UNKNOWN) 776 return; 777 778 val = sym_get_string_value(sym); 779 780 switch (sym->type) { 781 case S_BOOLEAN: 782 case S_TRISTATE: 783 /* 784 * We do not care about disabled ones, i.e. no need for 785 * what otherwise are "comments" in other printers. 786 */ 787 if (*val == 'n') 788 return; 789 790 /* 791 * To have similar functionality to the C macro `IS_ENABLED()` 792 * we provide an empty `--cfg CONFIG_X` here in both `y` 793 * and `m` cases. 794 * 795 * Then, the common `fprintf()` below will also give us 796 * a `--cfg CONFIG_X="y"` or `--cfg CONFIG_X="m"`, which can 797 * be used as the equivalent of `IS_BUILTIN()`/`IS_MODULE()`. 798 */ 799 fprintf(fp, "--cfg=%s%s\n", CONFIG_, sym->name); 800 break; 801 case S_HEX: 802 if (val[0] != '0' || (val[1] != 'x' && val[1] != 'X')) 803 val_prefix = "0x"; 804 break; 805 default: 806 break; 807 } 808 809 if (strlen(val_prefix) > 0) { 810 val_prefixed_len = strlen(val) + strlen(val_prefix) + 1; 811 val_prefixed = xmalloc(val_prefixed_len); 812 snprintf(val_prefixed, val_prefixed_len, "%s%s", val_prefix, val); 813 val = val_prefixed; 814 } 815 816 /* All values get escaped: the `--cfg` option only takes strings */ 817 escaped = escape_string_value(val); 818 val = escaped; 819 820 fprintf(fp, "--cfg=%s%s=%s\n", CONFIG_, sym->name, val); 821 822 free(escaped); 823 free(val_prefixed); 824 } 825 826 /* 827 * Write out a minimal config. 828 * All values that has default values are skipped as this is redundant. 829 */ 830 int conf_write_defconfig(const char *filename) 831 { 832 struct symbol *sym; 833 struct menu *menu; 834 struct gstr gs; 835 FILE *out; 836 bool warn_changed_input = conf_warn_changed_input_enabled(); 837 bool changed_input_found = false; 838 839 out = fopen(filename, "w"); 840 if (!out) 841 return 1; 842 gs = str_new(); 843 844 sym_clear_all_valid(); 845 846 menu_for_each_entry(menu) { 847 struct menu *choice; 848 849 sym = menu->sym; 850 851 if (!sym || sym_is_choice(sym) || sym->flags & SYMBOL_WRITTEN) 852 continue; 853 854 sym_calc_value(sym); 855 if (warn_changed_input) 856 conf_append_changed_input_warning(&gs, sym, 857 &changed_input_found); 858 sym->flags |= SYMBOL_WRITTEN; 859 if (!(sym->flags & SYMBOL_WRITE)) 860 continue; 861 sym->flags &= ~SYMBOL_WRITE; 862 /* Skip unchangeable symbols */ 863 if (!sym_is_changeable(sym)) 864 continue; 865 /* Skip symbols that are equal to the default */ 866 if (!strcmp(sym_get_string_value(sym), sym_get_string_default(sym))) 867 continue; 868 869 /* Skip choice values that are equal to the default */ 870 choice = sym_get_choice_menu(sym); 871 if (choice) { 872 struct symbol *ds; 873 874 ds = sym_choice_default(choice); 875 if (sym == ds && sym_get_tristate_value(sym) == yes) 876 continue; 877 } 878 print_symbol_for_dotconfig(out, sym); 879 } 880 fclose(out); 881 882 conf_clear_written_flags(); 883 884 if (changed_input_found) 885 conf_changed_input_warning(str_get(&gs)); 886 887 str_free(&gs); 888 return 0; 889 } 890 891 int conf_write(const char *name) 892 { 893 FILE *out; 894 struct symbol *sym; 895 struct menu *menu; 896 const char *str; 897 char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1]; 898 char *env; 899 struct gstr gs; 900 bool need_newline = false; 901 bool warn_changed_input = conf_warn_changed_input_enabled(); 902 bool changed_input_found = false; 903 904 if (!name) 905 name = conf_get_configname(); 906 907 if (!*name) { 908 fprintf(stderr, "config name is empty\n"); 909 return -1; 910 } 911 912 if (is_dir(name)) { 913 fprintf(stderr, "%s: Is a directory\n", name); 914 return -1; 915 } 916 917 if (make_parent_dir(name)) 918 return -1; 919 920 env = getenv("KCONFIG_OVERWRITECONFIG"); 921 if (env && *env) { 922 *tmpname = 0; 923 out = fopen(name, "w"); 924 } else { 925 snprintf(tmpname, sizeof(tmpname), "%s.%d.tmp", 926 name, (int)getpid()); 927 out = fopen(tmpname, "w"); 928 } 929 if (!out) 930 return 1; 931 gs = str_new(); 932 933 conf_write_heading(out, &comment_style_pound); 934 935 if (!conf_get_changed()) 936 sym_clear_all_valid(); 937 938 menu = rootmenu.list; 939 while (menu) { 940 sym = menu->sym; 941 if (!sym) { 942 if (!menu_is_visible(menu)) 943 goto next; 944 str = menu_get_prompt(menu); 945 fprintf(out, "\n" 946 "#\n" 947 "# %s\n" 948 "#\n", str); 949 need_newline = false; 950 } else if (!sym_is_choice(sym) && 951 !(sym->flags & SYMBOL_WRITTEN)) { 952 sym_calc_value(sym); 953 if (warn_changed_input) 954 conf_append_changed_input_warning(&gs, sym, 955 &changed_input_found); 956 sym->flags |= SYMBOL_WRITTEN; 957 if (!(sym->flags & SYMBOL_WRITE)) 958 goto next; 959 if (need_newline) { 960 fprintf(out, "\n"); 961 need_newline = false; 962 } 963 print_symbol_for_dotconfig(out, sym); 964 } 965 966 next: 967 if (menu->list) { 968 menu = menu->list; 969 continue; 970 } 971 972 end_check: 973 if (!menu->sym && menu_is_visible(menu) && menu != &rootmenu && 974 menu->prompt->type == P_MENU) { 975 fprintf(out, "# end of %s\n", menu_get_prompt(menu)); 976 need_newline = true; 977 } 978 979 if (menu->next) { 980 menu = menu->next; 981 } else { 982 menu = menu->parent; 983 if (menu) 984 goto end_check; 985 } 986 } 987 fclose(out); 988 989 conf_clear_written_flags(); 990 991 if (changed_input_found) 992 conf_changed_input_warning(str_get(&gs)); 993 994 str_free(&gs); 995 996 if (*tmpname) { 997 if (is_same(name, tmpname)) { 998 conf_message("No change to %s", name); 999 unlink(tmpname); 1000 conf_set_changed(false); 1001 return 0; 1002 } 1003 1004 snprintf(oldname, sizeof(oldname), "%s.old", name); 1005 rename(name, oldname); 1006 if (rename(tmpname, name)) 1007 return 1; 1008 } 1009 1010 conf_message("configuration written to %s", name); 1011 1012 conf_set_changed(false); 1013 1014 return 0; 1015 } 1016 1017 /* write a dependency file as used by kbuild to track dependencies */ 1018 static int conf_write_autoconf_cmd(const char *autoconf_name) 1019 { 1020 char name[PATH_MAX], tmp[PATH_MAX]; 1021 FILE *out; 1022 int ret; 1023 1024 ret = snprintf(name, sizeof(name), "%s.cmd", autoconf_name); 1025 if (ret >= sizeof(name)) /* check truncation */ 1026 return -1; 1027 1028 if (make_parent_dir(name)) 1029 return -1; 1030 1031 ret = snprintf(tmp, sizeof(tmp), "%s.cmd.tmp", autoconf_name); 1032 if (ret >= sizeof(tmp)) /* check truncation */ 1033 return -1; 1034 1035 out = fopen(tmp, "w"); 1036 if (!out) { 1037 perror("fopen"); 1038 return -1; 1039 } 1040 1041 fprintf(out, "autoconfig := %s\n", autoconf_name); 1042 1043 fputs(str_get(&autoconf_cmd), out); 1044 1045 fflush(out); 1046 ret = ferror(out); /* error check for all fprintf() calls */ 1047 fclose(out); 1048 if (ret) 1049 return -1; 1050 1051 if (rename(tmp, name)) { 1052 perror("rename"); 1053 return -1; 1054 } 1055 1056 return 0; 1057 } 1058 1059 static int conf_touch_deps(void) 1060 { 1061 const char *name, *tmp; 1062 struct symbol *sym; 1063 int res; 1064 1065 name = conf_get_autoconfig_name(); 1066 tmp = strrchr(name, '/'); 1067 depfile_prefix_len = tmp ? tmp - name + 1 : 0; 1068 if (depfile_prefix_len + 1 > sizeof(depfile_path)) 1069 return -1; 1070 1071 strncpy(depfile_path, name, depfile_prefix_len); 1072 depfile_path[depfile_prefix_len] = 0; 1073 1074 conf_read_simple(name, S_DEF_AUTO); 1075 1076 for_all_symbols(sym) { 1077 if (sym_is_choice(sym)) 1078 continue; 1079 if (sym->flags & SYMBOL_WRITE) { 1080 if (sym->flags & SYMBOL_DEF_AUTO) { 1081 /* 1082 * symbol has old and new value, 1083 * so compare them... 1084 */ 1085 switch (sym->type) { 1086 case S_BOOLEAN: 1087 case S_TRISTATE: 1088 if (sym_get_tristate_value(sym) == 1089 sym->def[S_DEF_AUTO].tri) 1090 continue; 1091 break; 1092 case S_STRING: 1093 case S_HEX: 1094 case S_INT: 1095 if (!strcmp(sym_get_string_value(sym), 1096 sym->def[S_DEF_AUTO].val)) 1097 continue; 1098 break; 1099 default: 1100 break; 1101 } 1102 } else { 1103 /* 1104 * If there is no old value, only 'no' (unset) 1105 * is allowed as new value. 1106 */ 1107 switch (sym->type) { 1108 case S_BOOLEAN: 1109 case S_TRISTATE: 1110 if (sym_get_tristate_value(sym) == no) 1111 continue; 1112 break; 1113 default: 1114 break; 1115 } 1116 } 1117 } else if (!(sym->flags & SYMBOL_DEF_AUTO)) 1118 /* There is neither an old nor a new value. */ 1119 continue; 1120 /* else 1121 * There is an old value, but no new value ('no' (unset) 1122 * isn't saved in auto.conf, so the old value is always 1123 * different from 'no'). 1124 */ 1125 1126 res = conf_touch_dep(sym->name); 1127 if (res) 1128 return res; 1129 } 1130 1131 return 0; 1132 } 1133 1134 static int __conf_write_autoconf(const char *filename, 1135 void (*print_symbol)(FILE *, struct symbol *), 1136 const struct comment_style *comment_style) 1137 { 1138 char tmp[PATH_MAX]; 1139 FILE *file; 1140 struct symbol *sym; 1141 int ret; 1142 1143 if (make_parent_dir(filename)) 1144 return -1; 1145 1146 ret = snprintf(tmp, sizeof(tmp), "%s.tmp", filename); 1147 if (ret >= sizeof(tmp)) /* check truncation */ 1148 return -1; 1149 1150 file = fopen(tmp, "w"); 1151 if (!file) { 1152 perror("fopen"); 1153 return -1; 1154 } 1155 1156 conf_write_heading(file, comment_style); 1157 1158 for_all_symbols(sym) 1159 if ((sym->flags & SYMBOL_WRITE) && sym->name) 1160 print_symbol(file, sym); 1161 1162 fflush(file); 1163 /* check possible errors in conf_write_heading() and print_symbol() */ 1164 ret = ferror(file); 1165 fclose(file); 1166 if (ret) 1167 return -1; 1168 1169 if (rename(tmp, filename)) { 1170 perror("rename"); 1171 return -1; 1172 } 1173 1174 return 0; 1175 } 1176 1177 int conf_write_autoconf(int overwrite) 1178 { 1179 struct symbol *sym; 1180 const char *autoconf_name = conf_get_autoconfig_name(); 1181 int ret; 1182 1183 if (!overwrite && is_present(autoconf_name)) 1184 return 0; 1185 1186 ret = conf_write_autoconf_cmd(autoconf_name); 1187 if (ret) 1188 return -1; 1189 1190 for_all_symbols(sym) 1191 sym_calc_value(sym); 1192 1193 if (conf_touch_deps()) 1194 return 1; 1195 1196 ret = __conf_write_autoconf(conf_get_autoheader_name(), 1197 print_symbol_for_c, 1198 &comment_style_c); 1199 if (ret) 1200 return ret; 1201 1202 ret = __conf_write_autoconf(conf_get_rustccfg_name(), 1203 print_symbol_for_rustccfg, 1204 NULL); 1205 if (ret) 1206 return ret; 1207 1208 /* 1209 * Create include/config/auto.conf. This must be the last step because 1210 * Kbuild has a dependency on auto.conf and this marks the successful 1211 * completion of the previous steps. 1212 */ 1213 ret = __conf_write_autoconf(conf_get_autoconfig_name(), 1214 print_symbol_for_autoconf, 1215 &comment_style_pound); 1216 if (ret) 1217 return ret; 1218 1219 return 0; 1220 } 1221 1222 static bool conf_changed; 1223 static void (*conf_changed_callback)(bool); 1224 1225 void conf_set_changed(bool val) 1226 { 1227 if (conf_changed_callback && conf_changed != val) 1228 conf_changed_callback(val); 1229 1230 conf_changed = val; 1231 } 1232 1233 bool conf_get_changed(void) 1234 { 1235 return conf_changed; 1236 } 1237 1238 void conf_set_changed_callback(void (*fn)(bool)) 1239 { 1240 conf_changed_callback = fn; 1241 } 1242