hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/scripts/kconfig/confdata.c
....@@ -1,12 +1,14 @@
1
+// SPDX-License-Identifier: GPL-2.0
12 /*
23 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3
- * Released under the terms of the GNU GPL v2.0.
44 */
55
6
+#include <sys/mman.h>
67 #include <sys/stat.h>
78 #include <ctype.h>
89 #include <errno.h>
910 #include <fcntl.h>
11
+#include <limits.h>
1012 #include <stdarg.h>
1113 #include <stdio.h>
1214 #include <stdlib.h>
....@@ -33,6 +35,52 @@
3335 return 0;
3436
3537 return S_ISDIR(st.st_mode);
38
+}
39
+
40
+/* return true if the given two files are the same, false otherwise */
41
+static bool is_same(const char *file1, const char *file2)
42
+{
43
+ int fd1, fd2;
44
+ struct stat st1, st2;
45
+ void *map1, *map2;
46
+ bool ret = false;
47
+
48
+ fd1 = open(file1, O_RDONLY);
49
+ if (fd1 < 0)
50
+ return ret;
51
+
52
+ fd2 = open(file2, O_RDONLY);
53
+ if (fd2 < 0)
54
+ goto close1;
55
+
56
+ ret = fstat(fd1, &st1);
57
+ if (ret)
58
+ goto close2;
59
+ ret = fstat(fd2, &st2);
60
+ if (ret)
61
+ goto close2;
62
+
63
+ if (st1.st_size != st2.st_size)
64
+ goto close2;
65
+
66
+ map1 = mmap(NULL, st1.st_size, PROT_READ, MAP_PRIVATE, fd1, 0);
67
+ if (map1 == MAP_FAILED)
68
+ goto close2;
69
+
70
+ map2 = mmap(NULL, st2.st_size, PROT_READ, MAP_PRIVATE, fd2, 0);
71
+ if (map2 == MAP_FAILED)
72
+ goto close2;
73
+
74
+ if (bcmp(map1, map2, st1.st_size))
75
+ goto close2;
76
+
77
+ ret = true;
78
+close2:
79
+ close(fd2);
80
+close1:
81
+ close(fd1);
82
+
83
+ return ret;
3684 }
3785
3886 /*
....@@ -74,6 +122,47 @@
74122 return 0;
75123 }
76124
125
+static char depfile_path[PATH_MAX];
126
+static size_t depfile_prefix_len;
127
+
128
+/* touch depfile for symbol 'name' */
129
+static int conf_touch_dep(const char *name)
130
+{
131
+ int fd, ret;
132
+ const char *s;
133
+ char *d, c;
134
+
135
+ /* check overflow: prefix + name + ".h" + '\0' must fit in buffer. */
136
+ if (depfile_prefix_len + strlen(name) + 3 > sizeof(depfile_path))
137
+ return -1;
138
+
139
+ d = depfile_path + depfile_prefix_len;
140
+ s = name;
141
+
142
+ while ((c = *s++))
143
+ *d++ = (c == '_') ? '/' : tolower(c);
144
+ strcpy(d, ".h");
145
+
146
+ /* Assume directory path already exists. */
147
+ fd = open(depfile_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
148
+ if (fd == -1) {
149
+ if (errno != ENOENT)
150
+ return -1;
151
+
152
+ ret = make_parent_dir(depfile_path);
153
+ if (ret)
154
+ return ret;
155
+
156
+ /* Try it again. */
157
+ fd = open(depfile_path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
158
+ if (fd == -1)
159
+ return -1;
160
+ }
161
+ close(fd);
162
+
163
+ return 0;
164
+}
165
+
77166 struct conf_printer {
78167 void (*print_symbol)(FILE *, struct symbol *, const char *, void *);
79168 void (*print_comment)(FILE *, const char *, void *);
....@@ -87,8 +176,6 @@
87176
88177 static const char *conf_filename;
89178 static int conf_lineno, conf_warnings;
90
-
91
-const char conf_defname[] = "arch/$(ARCH)/defconfig";
92179
93180 static void conf_warning(const char *fmt, ...)
94181 {
....@@ -137,26 +224,11 @@
137224 return name ? name : ".config";
138225 }
139226
140
-const char *conf_get_autoconfig_name(void)
227
+static const char *conf_get_autoconfig_name(void)
141228 {
142229 char *name = getenv("KCONFIG_AUTOCONFIG");
143230
144231 return name ? name : "include/config/auto.conf";
145
-}
146
-
147
-char *conf_get_default_confname(void)
148
-{
149
- static char fullname[PATH_MAX+1];
150
- char *env, *name;
151
-
152
- name = expand_string(conf_defname);
153
- env = getenv(SRCTREE);
154
- if (env) {
155
- sprintf(fullname, "%s/%s", env, name);
156
- if (is_present(fullname))
157
- return fullname;
158
- }
159
- return name;
160232 }
161233
162234 static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
....@@ -186,14 +258,6 @@
186258 conf_warning("symbol value '%s' invalid for %s",
187259 p, sym->name);
188260 return 1;
189
- case S_OTHER:
190
- if (*p != '"') {
191
- for (p2 = p; *p2 && !isspace(*p2); p2++)
192
- ;
193
- sym->type = S_STRING;
194
- goto done;
195
- }
196
- /* fall through */
197261 case S_STRING:
198262 if (*p++ != '"')
199263 break;
....@@ -212,7 +276,6 @@
212276 /* fall through */
213277 case S_INT:
214278 case S_HEX:
215
- done:
216279 if (sym_string_valid(sym, p)) {
217280 sym->def[def].val = xstrdup(p);
218281 sym->flags |= def_flags;
....@@ -363,7 +426,7 @@
363426 sym = sym_find(line + 2 + strlen(CONFIG_));
364427 if (!sym) {
365428 sym_add_change_count(1);
366
- goto setsym;
429
+ continue;
367430 }
368431 } else {
369432 sym = sym_lookup(line + 2 + strlen(CONFIG_), 0);
....@@ -393,17 +456,22 @@
393456 if (*p2 == '\r')
394457 *p2 = 0;
395458 }
396
- if (def == S_DEF_USER) {
397
- sym = sym_find(line + strlen(CONFIG_));
398
- if (!sym) {
459
+
460
+ sym = sym_find(line + strlen(CONFIG_));
461
+ if (!sym) {
462
+ if (def == S_DEF_AUTO)
463
+ /*
464
+ * Reading from include/config/auto.conf
465
+ * If CONFIG_FOO previously existed in
466
+ * auto.conf but it is missing now,
467
+ * include/config/foo.h must be touched.
468
+ */
469
+ conf_touch_dep(line + strlen(CONFIG_));
470
+ else
399471 sym_add_change_count(1);
400
- goto setsym;
401
- }
402
- } else {
403
- sym = sym_lookup(line + strlen(CONFIG_), 0);
404
- if (sym->type == S_UNKNOWN)
405
- sym->type = S_OTHER;
472
+ continue;
406473 }
474
+
407475 if (sym->flags & def_flags) {
408476 conf_warning("override: reassigning to symbol %s", sym->name);
409477 }
....@@ -416,7 +484,7 @@
416484
417485 continue;
418486 }
419
-setsym:
487
+
420488 if (sym && sym_is_choice_value(sym)) {
421489 struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
422490 switch (sym->def[def].tri) {
....@@ -466,11 +534,9 @@
466534 switch (sym->type) {
467535 case S_BOOLEAN:
468536 case S_TRISTATE:
469
- if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym))
470
- break;
471
- if (!sym_is_choice(sym))
537
+ if (sym->def[S_DEF_USER].tri == sym_get_tristate_value(sym))
472538 continue;
473
- /* fall through */
539
+ break;
474540 default:
475541 if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val))
476542 continue;
....@@ -644,32 +710,12 @@
644710 .print_comment = header_print_comment,
645711 };
646712
647
-/*
648
- * Tristate printer
649
- *
650
- * This printer is used when generating the `include/config/tristate.conf' file.
651
- */
652
-static void
653
-tristate_print_symbol(FILE *fp, struct symbol *sym, const char *value, void *arg)
654
-{
655
-
656
- if (sym->type == S_TRISTATE && *value != 'n')
657
- fprintf(fp, "%s%s=%c\n", CONFIG_, sym->name, (char)toupper(*value));
658
-}
659
-
660
-static struct conf_printer tristate_printer_cb =
661
-{
662
- .print_symbol = tristate_print_symbol,
663
- .print_comment = kconfig_print_comment,
664
-};
665
-
666713 static void conf_write_symbol(FILE *fp, struct symbol *sym,
667714 struct conf_printer *printer, void *printer_arg)
668715 {
669716 const char *str;
670717
671718 switch (sym->type) {
672
- case S_OTHER:
673719 case S_UNKNOWN:
674720 break;
675721 case S_STRING:
....@@ -729,7 +775,7 @@
729775 goto next_menu;
730776 sym->flags &= ~SYMBOL_WRITE;
731777 /* If we cannot change the symbol - skip */
732
- if (!sym_is_changable(sym))
778
+ if (!sym_is_changeable(sym))
733779 goto next_menu;
734780 /* If symbol equals to default value - skip */
735781 if (strcmp(sym_get_string_value(sym), sym_get_string_default(sym)) == 0)
....@@ -780,41 +826,36 @@
780826 FILE *out;
781827 struct symbol *sym;
782828 struct menu *menu;
783
- const char *basename;
784829 const char *str;
785
- char dirname[PATH_MAX+1], tmpname[PATH_MAX+22], newname[PATH_MAX+8];
830
+ char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1];
786831 char *env;
787832 int i;
833
+ bool need_newline = false;
788834
789
- dirname[0] = 0;
790
- if (name && name[0]) {
791
- char *slash;
835
+ if (!name)
836
+ name = conf_get_configname();
792837
793
- if (is_dir(name)) {
794
- strcpy(dirname, name);
795
- strcat(dirname, "/");
796
- basename = conf_get_configname();
797
- } else if ((slash = strrchr(name, '/'))) {
798
- int size = slash - name + 1;
799
- memcpy(dirname, name, size);
800
- dirname[size] = 0;
801
- if (slash[1])
802
- basename = slash + 1;
803
- else
804
- basename = conf_get_configname();
805
- } else
806
- basename = name;
807
- } else
808
- basename = conf_get_configname();
838
+ if (!*name) {
839
+ fprintf(stderr, "config name is empty\n");
840
+ return -1;
841
+ }
809842
810
- sprintf(newname, "%s%s", dirname, basename);
843
+ if (is_dir(name)) {
844
+ fprintf(stderr, "%s: Is a directory\n", name);
845
+ return -1;
846
+ }
847
+
848
+ if (make_parent_dir(name))
849
+ return -1;
850
+
811851 env = getenv("KCONFIG_OVERWRITECONFIG");
812
- if (!env || !*env) {
813
- sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid());
814
- out = fopen(tmpname, "w");
815
- } else {
852
+ if (env && *env) {
816853 *tmpname = 0;
817
- out = fopen(newname, "w");
854
+ out = fopen(name, "w");
855
+ } else {
856
+ snprintf(tmpname, sizeof(tmpname), "%s.%d.tmp",
857
+ name, (int)getpid());
858
+ out = fopen(tmpname, "w");
818859 }
819860 if (!out)
820861 return 1;
....@@ -835,13 +876,17 @@
835876 "#\n"
836877 "# %s\n"
837878 "#\n", str);
879
+ need_newline = false;
838880 } else if (!(sym->flags & SYMBOL_CHOICE) &&
839881 !(sym->flags & SYMBOL_WRITTEN)) {
840882 sym_calc_value(sym);
841883 if (!(sym->flags & SYMBOL_WRITE))
842884 goto next;
885
+ if (need_newline) {
886
+ fprintf(out, "\n");
887
+ need_newline = false;
888
+ }
843889 sym->flags |= SYMBOL_WRITTEN;
844
-
845890 conf_write_symbol(out, sym, &kconfig_printer_cb, NULL);
846891 }
847892
....@@ -853,6 +898,12 @@
853898 if (menu->next)
854899 menu = menu->next;
855900 else while ((menu = menu->parent)) {
901
+ if (!menu->sym && menu_is_visible(menu) &&
902
+ menu != &rootmenu) {
903
+ str = menu_get_prompt(menu);
904
+ fprintf(out, "# end of %s\n", str);
905
+ need_newline = true;
906
+ }
856907 if (menu->next) {
857908 menu = menu->next;
858909 break;
....@@ -865,14 +916,20 @@
865916 sym->flags &= ~SYMBOL_WRITTEN;
866917
867918 if (*tmpname) {
868
- strcat(dirname, basename);
869
- strcat(dirname, ".old");
870
- rename(newname, dirname);
871
- if (rename(tmpname, newname))
919
+ if (is_same(name, tmpname)) {
920
+ conf_message("No change to %s", name);
921
+ unlink(tmpname);
922
+ sym_set_change_count(0);
923
+ return 0;
924
+ }
925
+
926
+ snprintf(oldname, sizeof(oldname), "%s.old", name);
927
+ rename(name, oldname);
928
+ if (rename(tmpname, name))
872929 return 1;
873930 }
874931
875
- conf_message("configuration written to %s", newname);
932
+ conf_message("configuration written to %s", name);
876933
877934 sym_set_change_count(0);
878935
....@@ -885,8 +942,6 @@
885942 struct file *file;
886943 FILE *out;
887944
888
- if (!name)
889
- name = ".kconfig.d";
890945 out = fopen("..config.tmp", "w");
891946 if (!out)
892947 return 1;
....@@ -911,24 +966,24 @@
911966 return 0;
912967 }
913968
914
-static int conf_split_config(void)
969
+static int conf_touch_deps(void)
915970 {
916
- const char *name;
917
- char path[PATH_MAX+1];
918
- char *s, *d, c;
971
+ const char *name, *tmp;
919972 struct symbol *sym;
920
- int res, i, fd;
973
+ int res, i;
921974
922975 name = conf_get_autoconfig_name();
976
+ tmp = strrchr(name, '/');
977
+ depfile_prefix_len = tmp ? tmp - name + 1 : 0;
978
+ if (depfile_prefix_len + 1 > sizeof(depfile_path))
979
+ return -1;
980
+
981
+ strncpy(depfile_path, name, depfile_prefix_len);
982
+ depfile_path[depfile_prefix_len] = 0;
983
+
923984 conf_read_simple(name, S_DEF_AUTO);
924985 sym_calc_value(modules_sym);
925986
926
- if (make_parent_dir("include/config/foo.h"))
927
- return 1;
928
- if (chdir("include/config"))
929
- return 1;
930
-
931
- res = 0;
932987 for_all_symbols(i, sym) {
933988 sym_calc_value(sym);
934989 if ((sym->flags & SYMBOL_NO_WRITE) || !sym->name)
....@@ -980,42 +1035,12 @@
9801035 * different from 'no').
9811036 */
9821037
983
- /* Replace all '_' and append ".h" */
984
- s = sym->name;
985
- d = path;
986
- while ((c = *s++)) {
987
- c = tolower(c);
988
- *d++ = (c == '_') ? '/' : c;
989
- }
990
- strcpy(d, ".h");
991
-
992
- /* Assume directory path already exists. */
993
- fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
994
- if (fd == -1) {
995
- if (errno != ENOENT) {
996
- res = 1;
997
- break;
998
- }
999
-
1000
- if (make_parent_dir(path)) {
1001
- res = 1;
1002
- goto out;
1003
- }
1004
-
1005
- /* Try it again. */
1006
- fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
1007
- if (fd == -1) {
1008
- res = 1;
1009
- break;
1010
- }
1011
- }
1012
- close(fd);
1038
+ res = conf_touch_dep(sym->name);
1039
+ if (res)
1040
+ return res;
10131041 }
1014
-out:
1015
- if (chdir("../.."))
1016
- return 1;
10171042
1018
- return res;
1043
+ return 0;
10191044 }
10201045
10211046 int conf_write_autoconf(int overwrite)
....@@ -1023,7 +1048,7 @@
10231048 struct symbol *sym;
10241049 const char *name;
10251050 const char *autoconf_name = conf_get_autoconfig_name();
1026
- FILE *out, *tristate, *out_h;
1051
+ FILE *out, *out_h;
10271052 int i;
10281053
10291054 if (!overwrite && is_present(autoconf_name))
....@@ -1031,30 +1056,20 @@
10311056
10321057 conf_write_dep("include/config/auto.conf.cmd");
10331058
1034
- if (conf_split_config())
1059
+ if (conf_touch_deps())
10351060 return 1;
10361061
10371062 out = fopen(".tmpconfig", "w");
10381063 if (!out)
10391064 return 1;
10401065
1041
- tristate = fopen(".tmpconfig_tristate", "w");
1042
- if (!tristate) {
1043
- fclose(out);
1044
- return 1;
1045
- }
1046
-
10471066 out_h = fopen(".tmpconfig.h", "w");
10481067 if (!out_h) {
10491068 fclose(out);
1050
- fclose(tristate);
10511069 return 1;
10521070 }
10531071
10541072 conf_write_heading(out, &kconfig_printer_cb, NULL);
1055
-
1056
- conf_write_heading(tristate, &tristate_printer_cb, NULL);
1057
-
10581073 conf_write_heading(out_h, &header_printer_cb, NULL);
10591074
10601075 for_all_symbols(i, sym) {
....@@ -1062,15 +1077,11 @@
10621077 if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
10631078 continue;
10641079
1065
- /* write symbol to auto.conf, tristate and header files */
1080
+ /* write symbols to auto.conf and autoconf.h */
10661081 conf_write_symbol(out, sym, &kconfig_printer_cb, (void *)1);
1067
-
1068
- conf_write_symbol(tristate, sym, &tristate_printer_cb, (void *)1);
1069
-
10701082 conf_write_symbol(out_h, sym, &header_printer_cb, NULL);
10711083 }
10721084 fclose(out);
1073
- fclose(tristate);
10741085 fclose(out_h);
10751086
10761087 name = getenv("KCONFIG_AUTOHEADER");
....@@ -1079,14 +1090,6 @@
10791090 if (make_parent_dir(name))
10801091 return 1;
10811092 if (rename(".tmpconfig.h", name))
1082
- return 1;
1083
-
1084
- name = getenv("KCONFIG_TRISTATE");
1085
- if (!name)
1086
- name = "include/config/tristate.conf";
1087
- if (make_parent_dir(name))
1088
- return 1;
1089
- if (rename(".tmpconfig_tristate", name))
10901093 return 1;
10911094
10921095 if (make_parent_dir(autoconf_name))
....@@ -1323,3 +1326,18 @@
13231326
13241327 return has_changed;
13251328 }
1329
+
1330
+void conf_rewrite_mod_or_yes(enum conf_def_mode mode)
1331
+{
1332
+ struct symbol *sym;
1333
+ int i;
1334
+ tristate old_val = (mode == def_y2m) ? yes : mod;
1335
+ tristate new_val = (mode == def_y2m) ? mod : yes;
1336
+
1337
+ for_all_symbols(i, sym) {
1338
+ if (sym_get_type(sym) == S_TRISTATE &&
1339
+ sym->def[S_DEF_USER].tri == old_val)
1340
+ sym->def[S_DEF_USER].tri = new_val;
1341
+ }
1342
+ sym_clear_all_valid();
1343
+}