locale: update Context only on success

Do not clear Context.vc, Context.x11_from_vc, and Context.x11_from_xorg
on errors like ENOMEM or so.

This does not change behavior on success.
This commit is contained in:
Yu Watanabe
2026-07-28 20:19:30 +09:00
parent d73f3879f0
commit f2718dee52
+35 -32
View File
@@ -142,8 +142,6 @@ int locale_read_data(Context *c, sd_bus_message *m) {
} }
int vconsole_read_data(Context *c, sd_bus_message *m) { int vconsole_read_data(Context *c, sd_bus_message *m) {
_cleanup_close_ int fd = -EBADF;
struct stat st;
int r; int r;
assert(c); assert(c);
@@ -157,7 +155,7 @@ int vconsole_read_data(Context *c, sd_bus_message *m) {
c->vc_cache = sd_bus_message_ref(m); c->vc_cache = sd_bus_message_ref(m);
} }
fd = RET_NERRNO(open(etc_vconsole_conf(), O_CLOEXEC | O_PATH)); _cleanup_close_ int fd = RET_NERRNO(open(etc_vconsole_conf(), O_CLOEXEC | O_PATH));
if (fd == -ENOENT) { if (fd == -ENOENT) {
c->vc_stat = (struct stat) {}; c->vc_stat = (struct stat) {};
vc_context_clear(&c->vc); vc_context_clear(&c->vc);
@@ -167,6 +165,7 @@ int vconsole_read_data(Context *c, sd_bus_message *m) {
if (fd < 0) if (fd < 0)
return fd; return fd;
struct stat st;
if (fstat(fd, &st) < 0) if (fstat(fd, &st) < 0)
return -errno; return -errno;
@@ -174,35 +173,34 @@ int vconsole_read_data(Context *c, sd_bus_message *m) {
if (stat_inode_unmodified(&c->vc_stat, &st)) if (stat_inode_unmodified(&c->vc_stat, &st))
return 0; return 0;
c->vc_stat = st; _cleanup_(vc_context_clear) VCContext vc = {};
vc_context_clear(&c->vc); _cleanup_(x11_context_clear) X11Context xc = {};
x11_context_clear(&c->x11_from_vc);
r = parse_env_file_fd( r = parse_env_file_fd(
fd, etc_vconsole_conf(), fd, etc_vconsole_conf(),
"KEYMAP", &c->vc.keymap, "KEYMAP", &vc.keymap,
"KEYMAP_TOGGLE", &c->vc.toggle, "KEYMAP_TOGGLE", &vc.toggle,
"XKBLAYOUT", &c->x11_from_vc.layout, "XKBLAYOUT", &xc.layout,
"XKBMODEL", &c->x11_from_vc.model, "XKBMODEL", &xc.model,
"XKBVARIANT", &c->x11_from_vc.variant, "XKBVARIANT", &xc.variant,
"XKBOPTIONS", &c->x11_from_vc.options); "XKBOPTIONS", &xc.options);
if (r < 0) if (r < 0)
return r; return r;
if (vc_context_verify(&c->vc) < 0) /* Do not fail when the .conf file contains an invalid setting, but discard the stored settings and
vc_context_clear(&c->vc); * save the stat to avoid re-reading it in the future. */
if (vc_context_verify(&vc) < 0)
vc_context_clear(&vc);
if (x11_context_verify(&c->x11_from_vc) < 0) if (x11_context_verify(&xc) < 0)
x11_context_clear(&c->x11_from_vc); x11_context_clear(&xc);
c->vc_stat = st;
vc_context_replace(&c->vc, &vc);
x11_context_replace(&c->x11_from_vc, &xc);
return 0; return 0;
} }
int x11_read_data(Context *c, sd_bus_message *m) { int x11_read_data(Context *c, sd_bus_message *m) {
_cleanup_close_ int fd = -EBADF;
_cleanup_fclose_ FILE *f = NULL;
bool in_section = false;
struct stat st;
int r; int r;
assert(c); assert(c);
@@ -216,7 +214,7 @@ int x11_read_data(Context *c, sd_bus_message *m) {
c->x11_cache = sd_bus_message_ref(m); c->x11_cache = sd_bus_message_ref(m);
} }
fd = RET_NERRNO(open("/etc/X11/xorg.conf.d/00-keyboard.conf", O_CLOEXEC | O_PATH)); _cleanup_close_ int fd = RET_NERRNO(open("/etc/X11/xorg.conf.d/00-keyboard.conf", O_CLOEXEC | O_PATH));
if (fd == -ENOENT) { if (fd == -ENOENT) {
c->x11_stat = (struct stat) {}; c->x11_stat = (struct stat) {};
x11_context_clear(&c->x11_from_xorg); x11_context_clear(&c->x11_from_xorg);
@@ -225,6 +223,7 @@ int x11_read_data(Context *c, sd_bus_message *m) {
if (fd < 0) if (fd < 0)
return fd; return fd;
struct stat st;
if (fstat(fd, &st) < 0) if (fstat(fd, &st) < 0)
return -errno; return -errno;
@@ -232,13 +231,13 @@ int x11_read_data(Context *c, sd_bus_message *m) {
if (stat_inode_unmodified(&c->x11_stat, &st)) if (stat_inode_unmodified(&c->x11_stat, &st))
return 0; return 0;
c->x11_stat = st; _cleanup_fclose_ FILE *f = NULL;
x11_context_clear(&c->x11_from_xorg);
r = fdopen_independent(fd, "re", &f); r = fdopen_independent(fd, "re", &f);
if (r < 0) if (r < 0)
return r; return r;
_cleanup_(x11_context_clear) X11Context xc = {};
bool in_section = false;
for (;;) { for (;;) {
_cleanup_free_ char *line = NULL; _cleanup_free_ char *line = NULL;
@@ -262,13 +261,13 @@ int x11_read_data(Context *c, sd_bus_message *m) {
char **p = NULL; char **p = NULL;
if (streq(a[1], "XkbLayout")) if (streq(a[1], "XkbLayout"))
p = &c->x11_from_xorg.layout; p = &xc.layout;
else if (streq(a[1], "XkbModel")) else if (streq(a[1], "XkbModel"))
p = &c->x11_from_xorg.model; p = &xc.model;
else if (streq(a[1], "XkbVariant")) else if (streq(a[1], "XkbVariant"))
p = &c->x11_from_xorg.variant; p = &xc.variant;
else if (streq(a[1], "XkbOptions")) else if (streq(a[1], "XkbOptions"))
p = &c->x11_from_xorg.options; p = &xc.options;
if (p) if (p)
free_and_replace(*p, a[2]); free_and_replace(*p, a[2]);
@@ -288,11 +287,15 @@ int x11_read_data(Context *c, sd_bus_message *m) {
in_section = false; in_section = false;
} }
x11_context_normalize(&c->x11_from_xorg); x11_context_normalize(&xc);
if (x11_context_verify(&c->x11_from_xorg) < 0) /* Do not fail when the .conf file contains an invalid setting, but discard the stored settings and
x11_context_clear(&c->x11_from_xorg); * save the stat to avoid re-reading it in the future. */
if (x11_context_verify(&xc) < 0)
x11_context_clear(&xc);
c->x11_stat = st;
x11_context_replace(&c->x11_from_xorg, &xc);
return 0; return 0;
} }