1From 569d1effe8ceaec9f085ded004c7845957ef7b90 Mon Sep 17 00:00:00 2001 2From: Jeffy Chen <jeffy.chen@rock-chips.com> 3Date: Wed, 7 Apr 2021 08:25:57 +0800 4Subject: [PATCH 45/79] config-parser: Support loading multiple configs 5 6Try loading .ini configs under "<config>.d/". 7 8Tested with: 9/etc/xdg/weston/weston.ini.d/99-pixman.ini 10[core] 11use-pixman=true 12 13Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com> 14--- 15 shared/config-parser.c | 132 +++++++++++++++++++++++++++++++++-------- 16 1 file changed, 106 insertions(+), 26 deletions(-) 17 18diff --git a/shared/config-parser.c b/shared/config-parser.c 19index ed120d5..7df5a3b 100644 20--- a/shared/config-parser.c 21+++ b/shared/config-parser.c 22@@ -31,6 +31,7 @@ 23 #include <stdlib.h> 24 #include <assert.h> 25 #include <ctype.h> 26+#include <dirent.h> 27 #include <limits.h> 28 #include <sys/types.h> 29 #include <sys/stat.h> 30@@ -70,6 +71,13 @@ open_config_file(struct weston_config *c, const char *name) 31 const char *p, *next; 32 int fd; 33 34+ if (!c) { 35+ if (name[0] != '/') 36+ return -1; 37+ 38+ return open(name, O_RDONLY | O_CLOEXEC); 39+ } 40+ 41 if (name[0] == '/') { 42 snprintf(c->path, sizeof c->path, "%s", name); 43 return open(name, O_RDONLY | O_CLOEXEC); 44@@ -345,6 +353,15 @@ config_add_section(struct weston_config *config, const char *name) 45 { 46 struct weston_config_section *section; 47 48+ /* squash single sessions */ 49+ if (strcmp(name, "launcher") && strcmp(name, "ivi-launcher") && 50+ strcmp(name, "output") && strcmp(name, "remote-output") && 51+ strcmp(name, "pipewire-output")) { 52+ section = weston_config_get_section(config, name, NULL, NULL); 53+ if (section) 54+ return section; 55+ } 56+ 57 section = zalloc(sizeof *section); 58 if (section == NULL) 59 return NULL; 60@@ -367,6 +384,19 @@ section_add_entry(struct weston_config_section *section, 61 { 62 struct weston_config_entry *entry; 63 64+ /* hack for removing entry */ 65+ if (key[0] == '-') { 66+ entry = config_section_get_entry(section, key + 1); 67+ if (!entry) 68+ return NULL; 69+ 70+ wl_list_remove(&entry->link); 71+ free(entry->key); 72+ free(entry->value); 73+ free(entry); 74+ return NULL; 75+ } 76+ 77 entry = zalloc(sizeof *entry); 78 if (entry == NULL) 79 return NULL; 80@@ -389,41 +419,27 @@ section_add_entry(struct weston_config_section *section, 81 return entry; 82 } 83 84-WL_EXPORT 85-struct weston_config * 86-weston_config_parse(const char *name) 87+static bool 88+weston_config_parse_fd(struct weston_config *config, int fd) 89 { 90 FILE *fp; 91 char line[512], *p; 92 struct stat filestat; 93- struct weston_config *config; 94 struct weston_config_section *section = NULL; 95- int i, fd; 96- 97- config = zalloc(sizeof *config); 98- if (config == NULL) 99- return NULL; 100+ int i; 101 102- wl_list_init(&config->section_list); 103- 104- fd = open_config_file(config, name); 105- if (fd == -1) { 106- free(config); 107- return NULL; 108- } 109+ if (fd < 0 || !config) 110+ return false; 111 112 if (fstat(fd, &filestat) < 0 || 113 !S_ISREG(filestat.st_mode)) { 114 close(fd); 115- free(config); 116- return NULL; 117+ return false; 118 } 119 120 fp = fdopen(fd, "r"); 121- if (fp == NULL) { 122- free(config); 123- return NULL; 124- } 125+ if (fp == NULL) 126+ return false; 127 128 while (fgets(line, sizeof line, fp)) { 129 switch (line[0]) { 130@@ -436,8 +452,7 @@ weston_config_parse(const char *name) 131 fprintf(stderr, "malformed " 132 "section header: %s\n", line); 133 fclose(fp); 134- weston_config_destroy(config); 135- return NULL; 136+ return false; 137 } 138 p[0] = '\0'; 139 section = config_add_section(config, &line[1]); 140@@ -448,8 +463,7 @@ weston_config_parse(const char *name) 141 fprintf(stderr, "malformed " 142 "config line: %s\n", line); 143 fclose(fp); 144- weston_config_destroy(config); 145- return NULL; 146+ return false; 147 } 148 149 p[0] = '\0'; 150@@ -468,6 +482,72 @@ weston_config_parse(const char *name) 151 152 fclose(fp); 153 154+ return true; 155+} 156+ 157+static int 158+accept_config_file(const struct dirent *entry) 159+{ 160+ const char *suffix = ".ini"; 161+ char *end = strstr(entry->d_name, suffix); 162+ return end && end[strlen(suffix)] == '\0'; 163+} 164+ 165+WL_EXPORT 166+struct weston_config * 167+weston_config_parse(const char *name) 168+{ 169+ struct stat st; 170+ struct dirent **namelist; 171+ struct weston_config *config; 172+ char path[sizeof(config->path) + 2]; 173+ int n, fd; 174+ 175+ config = zalloc(sizeof *config); 176+ if (config == NULL) 177+ return NULL; 178+ 179+ wl_list_init(&config->section_list); 180+ 181+ fd = open_config_file(config, name); 182+ if (fd >= 0 && !weston_config_parse_fd(config, fd)) { 183+ fprintf(stderr, "failed to parse %s\n", config->path); 184+ free(config); 185+ return NULL; 186+ } 187+ 188+ strcpy(path, config->path); 189+ strcat(path, ".d"); 190+ if (stat(path, &st) < 0 || !S_ISDIR(st.st_mode)) 191+ return config; 192+ 193+ n = scandir(path, &namelist, accept_config_file, alphasort); 194+ if (n < 0) 195+ return config; 196+ 197+ while (n--) { 198+ char *file = namelist[n]->d_name; 199+ char *sep = "/"; 200+ char fpath[strlen(path)+strlen(sep)+strlen(file) + 1]; 201+ strcpy(fpath, path); 202+ strcat(fpath, sep); 203+ strcat(fpath, file); 204+ free(namelist[n]); 205+ 206+ fd = open_config_file(NULL, fpath); 207+ if (fd < 0) 208+ continue; 209+ 210+ if (!weston_config_parse_fd(config, fd)) { 211+ fprintf(stderr, "failed to parse '%s'\n", fpath); 212+ free(namelist); 213+ free(config); 214+ return NULL; 215+ } 216+ } 217+ 218+ free(namelist); 219+ 220 return config; 221 } 222 223-- 2242.20.1 225 226