1*4882a593SmuzhiyunFrom af34025ea52bdf8a33c2b6978953851e7cda95f4 Mon Sep 17 00:00:00 2001 2*4882a593SmuzhiyunFrom: Jeffy Chen <jeffy.chen@rock-chips.com> 3*4882a593SmuzhiyunDate: Wed, 7 Apr 2021 08:25:57 +0800 4*4882a593SmuzhiyunSubject: [PATCH 47/93] config-parser: Support loading multiple configs 5*4882a593Smuzhiyun 6*4882a593SmuzhiyunTry loading .ini configs under "<config>.d/". 7*4882a593Smuzhiyun 8*4882a593SmuzhiyunTested with: 9*4882a593Smuzhiyun/etc/xdg/weston/weston.ini.d/99-pixman.ini 10*4882a593Smuzhiyun[core] 11*4882a593Smuzhiyunuse-pixman=true 12*4882a593Smuzhiyun 13*4882a593SmuzhiyunSigned-off-by: Jeffy Chen <jeffy.chen@rock-chips.com> 14*4882a593Smuzhiyun--- 15*4882a593Smuzhiyun compositor/main.c | 5 +- 16*4882a593Smuzhiyun shared/config-parser.c | 146 ++++++++++++++++++++++++++++++++++------- 17*4882a593Smuzhiyun 2 files changed, 127 insertions(+), 24 deletions(-) 18*4882a593Smuzhiyun 19*4882a593Smuzhiyundiff --git a/compositor/main.c b/compositor/main.c 20*4882a593Smuzhiyunindex 6ec89f3..7a1cc20 100644 21*4882a593Smuzhiyun--- a/compositor/main.c 22*4882a593Smuzhiyun+++ b/compositor/main.c 23*4882a593Smuzhiyun@@ -1209,8 +1209,11 @@ load_configuration(struct weston_config **config, int32_t noconfig, 24*4882a593Smuzhiyun if (config_file) 25*4882a593Smuzhiyun file = config_file; 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun- if (noconfig == 0) 28*4882a593Smuzhiyun+ if (noconfig == 0) { 29*4882a593Smuzhiyun+ setenv("WESTON_MAIN_PARSE", "1", 1); 30*4882a593Smuzhiyun *config = weston_config_parse(file); 31*4882a593Smuzhiyun+ unsetenv("WESTON_MAIN_PARSE"); 32*4882a593Smuzhiyun+ } 33*4882a593Smuzhiyun 34*4882a593Smuzhiyun if (*config) { 35*4882a593Smuzhiyun full_path = weston_config_get_full_path(*config); 36*4882a593Smuzhiyundiff --git a/shared/config-parser.c b/shared/config-parser.c 37*4882a593Smuzhiyunindex 30779ae..e474963 100644 38*4882a593Smuzhiyun--- a/shared/config-parser.c 39*4882a593Smuzhiyun+++ b/shared/config-parser.c 40*4882a593Smuzhiyun@@ -31,6 +31,7 @@ 41*4882a593Smuzhiyun #include <stdlib.h> 42*4882a593Smuzhiyun #include <assert.h> 43*4882a593Smuzhiyun #include <ctype.h> 44*4882a593Smuzhiyun+#include <dirent.h> 45*4882a593Smuzhiyun #include <limits.h> 46*4882a593Smuzhiyun #include <sys/types.h> 47*4882a593Smuzhiyun #include <sys/stat.h> 48*4882a593Smuzhiyun@@ -70,6 +71,13 @@ open_config_file(struct weston_config *c, const char *name) 49*4882a593Smuzhiyun const char *p, *next; 50*4882a593Smuzhiyun int fd; 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun+ if (!c) { 53*4882a593Smuzhiyun+ if (name[0] != '/') 54*4882a593Smuzhiyun+ return -1; 55*4882a593Smuzhiyun+ 56*4882a593Smuzhiyun+ return open(name, O_RDONLY | O_CLOEXEC); 57*4882a593Smuzhiyun+ } 58*4882a593Smuzhiyun+ 59*4882a593Smuzhiyun if (name[0] == '/') { 60*4882a593Smuzhiyun snprintf(c->path, sizeof c->path, "%s", name); 61*4882a593Smuzhiyun return open(name, O_RDONLY | O_CLOEXEC); 62*4882a593Smuzhiyun@@ -337,6 +345,15 @@ config_add_section(struct weston_config *config, const char *name) 63*4882a593Smuzhiyun { 64*4882a593Smuzhiyun struct weston_config_section *section; 65*4882a593Smuzhiyun 66*4882a593Smuzhiyun+ /* squash single sessions */ 67*4882a593Smuzhiyun+ if (strcmp(name, "launcher") && strcmp(name, "ivi-launcher") && 68*4882a593Smuzhiyun+ strcmp(name, "output") && strcmp(name, "remote-output") && 69*4882a593Smuzhiyun+ strcmp(name, "pipewire-output")) { 70*4882a593Smuzhiyun+ section = weston_config_get_section(config, name, NULL, NULL); 71*4882a593Smuzhiyun+ if (section) 72*4882a593Smuzhiyun+ return section; 73*4882a593Smuzhiyun+ } 74*4882a593Smuzhiyun+ 75*4882a593Smuzhiyun section = zalloc(sizeof *section); 76*4882a593Smuzhiyun if (section == NULL) 77*4882a593Smuzhiyun return NULL; 78*4882a593Smuzhiyun@@ -355,10 +372,33 @@ config_add_section(struct weston_config *config, const char *name) 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun static struct weston_config_entry * 81*4882a593Smuzhiyun section_add_entry(struct weston_config_section *section, 82*4882a593Smuzhiyun- const char *key, const char *value) 83*4882a593Smuzhiyun+ const char *key, const char *value, const char *file_name) 84*4882a593Smuzhiyun { 85*4882a593Smuzhiyun struct weston_config_entry *entry; 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun+ /* hack for removing entry */ 88*4882a593Smuzhiyun+ if (key[0] == '-') { 89*4882a593Smuzhiyun+ key ++; 90*4882a593Smuzhiyun+ value = NULL; 91*4882a593Smuzhiyun+ } 92*4882a593Smuzhiyun+ 93*4882a593Smuzhiyun+ /* drop old entry */ 94*4882a593Smuzhiyun+ entry = config_section_get_entry(section, key); 95*4882a593Smuzhiyun+ if (entry) { 96*4882a593Smuzhiyun+ if (getenv("WESTON_MAIN_PARSE")) { 97*4882a593Smuzhiyun+ printf("%s: \"%s/%s\" from \"%s\" to \"%s\"\n", 98*4882a593Smuzhiyun+ file_name ?: "unknown", section->name, 99*4882a593Smuzhiyun+ entry->key, entry->value ?: "", value ?: ""); 100*4882a593Smuzhiyun+ } 101*4882a593Smuzhiyun+ wl_list_remove(&entry->link); 102*4882a593Smuzhiyun+ free(entry->key); 103*4882a593Smuzhiyun+ free(entry->value); 104*4882a593Smuzhiyun+ free(entry); 105*4882a593Smuzhiyun+ } 106*4882a593Smuzhiyun+ 107*4882a593Smuzhiyun+ if (!value || value[0] == '\0') 108*4882a593Smuzhiyun+ return NULL; 109*4882a593Smuzhiyun+ 110*4882a593Smuzhiyun entry = zalloc(sizeof *entry); 111*4882a593Smuzhiyun if (entry == NULL) 112*4882a593Smuzhiyun return NULL; 113*4882a593Smuzhiyun@@ -382,14 +422,13 @@ section_add_entry(struct weston_config_section *section, 114*4882a593Smuzhiyun } 115*4882a593Smuzhiyun 116*4882a593Smuzhiyun static bool 117*4882a593Smuzhiyun-weston_config_parse_internal(struct weston_config *config, FILE *fp) 118*4882a593Smuzhiyun+weston_config_parse_internal(struct weston_config *config, FILE *fp, 119*4882a593Smuzhiyun+ const char *file_name) 120*4882a593Smuzhiyun { 121*4882a593Smuzhiyun struct weston_config_section *section = NULL; 122*4882a593Smuzhiyun char line[512], *p; 123*4882a593Smuzhiyun int i; 124*4882a593Smuzhiyun 125*4882a593Smuzhiyun- wl_list_init(&config->section_list); 126*4882a593Smuzhiyun- 127*4882a593Smuzhiyun while (fgets(line, sizeof line, fp)) { 128*4882a593Smuzhiyun switch (line[0]) { 129*4882a593Smuzhiyun case '#': 130*4882a593Smuzhiyun@@ -422,7 +461,7 @@ weston_config_parse_internal(struct weston_config *config, FILE *fp) 131*4882a593Smuzhiyun p[i - 1] = '\0'; 132*4882a593Smuzhiyun i--; 133*4882a593Smuzhiyun } 134*4882a593Smuzhiyun- section_add_entry(section, line, p); 135*4882a593Smuzhiyun+ section_add_entry(section, line, p, file_name); 136*4882a593Smuzhiyun continue; 137*4882a593Smuzhiyun } 138*4882a593Smuzhiyun } 139*4882a593Smuzhiyun@@ -438,7 +477,8 @@ weston_config_parse_fp(FILE *file) 140*4882a593Smuzhiyun if (config == NULL) 141*4882a593Smuzhiyun return NULL; 142*4882a593Smuzhiyun 143*4882a593Smuzhiyun- if (!weston_config_parse_internal(config, file)) { 144*4882a593Smuzhiyun+ wl_list_init(&config->section_list); 145*4882a593Smuzhiyun+ if (!weston_config_parse_internal(config, file, NULL)) { 146*4882a593Smuzhiyun weston_config_destroy(config); 147*4882a593Smuzhiyun return NULL; 148*4882a593Smuzhiyun } 149*4882a593Smuzhiyun@@ -446,48 +486,108 @@ weston_config_parse_fp(FILE *file) 150*4882a593Smuzhiyun return config; 151*4882a593Smuzhiyun } 152*4882a593Smuzhiyun 153*4882a593Smuzhiyun-WL_EXPORT struct weston_config * 154*4882a593Smuzhiyun-weston_config_parse(const char *name) 155*4882a593Smuzhiyun+static FILE * 156*4882a593Smuzhiyun+weston_open_config_file(struct weston_config *config, const char *name) 157*4882a593Smuzhiyun { 158*4882a593Smuzhiyun FILE *fp; 159*4882a593Smuzhiyun struct stat filestat; 160*4882a593Smuzhiyun- struct weston_config *config; 161*4882a593Smuzhiyun int fd; 162*4882a593Smuzhiyun- bool ret; 163*4882a593Smuzhiyun- 164*4882a593Smuzhiyun- config = zalloc(sizeof *config); 165*4882a593Smuzhiyun- if (config == NULL) 166*4882a593Smuzhiyun- return NULL; 167*4882a593Smuzhiyun 168*4882a593Smuzhiyun fd = open_config_file(config, name); 169*4882a593Smuzhiyun- if (fd == -1) { 170*4882a593Smuzhiyun- free(config); 171*4882a593Smuzhiyun+ if (fd == -1) 172*4882a593Smuzhiyun return NULL; 173*4882a593Smuzhiyun- } 174*4882a593Smuzhiyun 175*4882a593Smuzhiyun if (fstat(fd, &filestat) < 0 || 176*4882a593Smuzhiyun !S_ISREG(filestat.st_mode)) { 177*4882a593Smuzhiyun close(fd); 178*4882a593Smuzhiyun- free(config); 179*4882a593Smuzhiyun return NULL; 180*4882a593Smuzhiyun } 181*4882a593Smuzhiyun 182*4882a593Smuzhiyun fp = fdopen(fd, "r"); 183*4882a593Smuzhiyun if (fp == NULL) { 184*4882a593Smuzhiyun close(fd); 185*4882a593Smuzhiyun- free(config); 186*4882a593Smuzhiyun return NULL; 187*4882a593Smuzhiyun } 188*4882a593Smuzhiyun 189*4882a593Smuzhiyun- ret = weston_config_parse_internal(config, fp); 190*4882a593Smuzhiyun+ return fp; 191*4882a593Smuzhiyun+} 192*4882a593Smuzhiyun 193*4882a593Smuzhiyun- fclose(fp); 194*4882a593Smuzhiyun+static int 195*4882a593Smuzhiyun+accept_config_file(const struct dirent *entry) 196*4882a593Smuzhiyun+{ 197*4882a593Smuzhiyun+ const char *suffix = ".ini"; 198*4882a593Smuzhiyun+ char *end = strstr(entry->d_name, suffix); 199*4882a593Smuzhiyun+ return end && end[strlen(suffix)] == '\0'; 200*4882a593Smuzhiyun+} 201*4882a593Smuzhiyun 202*4882a593Smuzhiyun- if (!ret) { 203*4882a593Smuzhiyun- weston_config_destroy(config); 204*4882a593Smuzhiyun+WL_EXPORT struct weston_config * 205*4882a593Smuzhiyun+weston_config_parse(const char *name) 206*4882a593Smuzhiyun+{ 207*4882a593Smuzhiyun+ FILE *fp; 208*4882a593Smuzhiyun+ struct weston_config *config; 209*4882a593Smuzhiyun+ struct stat st; 210*4882a593Smuzhiyun+ struct dirent **namelist; 211*4882a593Smuzhiyun+ char path[sizeof(config->path) + 2]; 212*4882a593Smuzhiyun+ bool ret; 213*4882a593Smuzhiyun+ int n, i; 214*4882a593Smuzhiyun+ 215*4882a593Smuzhiyun+ config = zalloc(sizeof *config); 216*4882a593Smuzhiyun+ if (config == NULL) 217*4882a593Smuzhiyun return NULL; 218*4882a593Smuzhiyun+ 219*4882a593Smuzhiyun+ wl_list_init(&config->section_list); 220*4882a593Smuzhiyun+ 221*4882a593Smuzhiyun+ fp = weston_open_config_file(config, name); 222*4882a593Smuzhiyun+ if (fp) { 223*4882a593Smuzhiyun+ ret = weston_config_parse_internal(config, fp, name); 224*4882a593Smuzhiyun+ 225*4882a593Smuzhiyun+ fclose(fp); 226*4882a593Smuzhiyun+ 227*4882a593Smuzhiyun+ if (!ret) { 228*4882a593Smuzhiyun+ fprintf(stderr, "failed to parse %s\n", config->path); 229*4882a593Smuzhiyun+ free(config); 230*4882a593Smuzhiyun+ return NULL; 231*4882a593Smuzhiyun+ } 232*4882a593Smuzhiyun+ } 233*4882a593Smuzhiyun+ 234*4882a593Smuzhiyun+ strcpy(path, config->path); 235*4882a593Smuzhiyun+ strcat(path, ".d"); 236*4882a593Smuzhiyun+ if (stat(path, &st) < 0 || !S_ISDIR(st.st_mode)) 237*4882a593Smuzhiyun+ return config; 238*4882a593Smuzhiyun+ 239*4882a593Smuzhiyun+ n = scandir(path, &namelist, accept_config_file, alphasort); 240*4882a593Smuzhiyun+ if (n < 0) 241*4882a593Smuzhiyun+ return config; 242*4882a593Smuzhiyun+ 243*4882a593Smuzhiyun+ for (i = 0; i < n; i++) { 244*4882a593Smuzhiyun+ char *file = namelist[i]->d_name; 245*4882a593Smuzhiyun+ char *sep = "/"; 246*4882a593Smuzhiyun+ char fpath[strlen(path)+strlen(sep)+strlen(file) + 1]; 247*4882a593Smuzhiyun+ strcpy(fpath, path); 248*4882a593Smuzhiyun+ strcat(fpath, sep); 249*4882a593Smuzhiyun+ strcat(fpath, file); 250*4882a593Smuzhiyun+ free(namelist[i]); 251*4882a593Smuzhiyun+ 252*4882a593Smuzhiyun+ fp = weston_open_config_file(NULL, fpath); 253*4882a593Smuzhiyun+ if (!fp) 254*4882a593Smuzhiyun+ continue; 255*4882a593Smuzhiyun+ 256*4882a593Smuzhiyun+ ret = weston_config_parse_internal(config, fp, fpath); 257*4882a593Smuzhiyun+ 258*4882a593Smuzhiyun+ fclose(fp); 259*4882a593Smuzhiyun+ 260*4882a593Smuzhiyun+ if (!ret) { 261*4882a593Smuzhiyun+ fprintf(stderr, "failed to parse '%s'\n", fpath); 262*4882a593Smuzhiyun+ free(config); 263*4882a593Smuzhiyun+ config = NULL; 264*4882a593Smuzhiyun+ break; 265*4882a593Smuzhiyun+ } 266*4882a593Smuzhiyun } 267*4882a593Smuzhiyun 268*4882a593Smuzhiyun+ for (; i < n; i++) 269*4882a593Smuzhiyun+ free(namelist[i]); 270*4882a593Smuzhiyun+ 271*4882a593Smuzhiyun+ free(namelist); 272*4882a593Smuzhiyun return config; 273*4882a593Smuzhiyun } 274*4882a593Smuzhiyun 275*4882a593Smuzhiyun-- 276*4882a593Smuzhiyun2.20.1 277*4882a593Smuzhiyun 278