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