Skip to content

Commit fe902fa

Browse files
committed
core/manager: move environment serialization out to basic/env-util.c
This protocol is generally useful, we might just as well reuse it for the env. generators. The implementation is changed a bit: instead of making a new strv and freeing the old one, just mutate the original. This is much faster with larger arrays, while in fact atomicity is preserved, since we only either insert the new entry or not, without being in inconsistent state. v2: - fix confusion with return value
1 parent 71cb7d3 commit fe902fa

3 files changed

Lines changed: 42 additions & 26 deletions

File tree

src/basic/env-util.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
#include "alloc-util.h"
2828
#include "env-util.h"
29+
#include "escape.h"
2930
#include "extract-word.h"
3031
#include "macro.h"
3132
#include "parse-util.h"
@@ -644,3 +645,36 @@ int getenv_bool(const char *p) {
644645

645646
return parse_boolean(e);
646647
}
648+
649+
int serialize_environment(FILE *f, char **environment) {
650+
char **e;
651+
652+
STRV_FOREACH(e, environment) {
653+
_cleanup_free_ char *ce;
654+
655+
ce = cescape(*e);
656+
if (!ce)
657+
return -ENOMEM;
658+
659+
fprintf(f, "env=%s\n", *e);
660+
}
661+
662+
/* caller should call ferror() */
663+
664+
return 0;
665+
}
666+
667+
int deserialize_environment(char ***environment, const char *line) {
668+
char *uce = NULL;
669+
int r;
670+
671+
assert(line);
672+
assert(environment);
673+
674+
assert(startswith(line, "env="));
675+
r = cunescape(line + 4, UNESCAPE_RELAX, &uce);
676+
if (r < 0)
677+
return r;
678+
679+
return strv_env_replace(environment, uce);
680+
}

src/basic/env-util.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include <stdbool.h>
2323
#include <stddef.h>
24+
#include <stdio.h>
2425

2526
#include "macro.h"
2627

@@ -50,3 +51,6 @@ char *strv_env_get_n(char **l, const char *name, size_t k) _pure_;
5051
char *strv_env_get(char **x, const char *n) _pure_;
5152

5253
int getenv_bool(const char *p);
54+
55+
int serialize_environment(FILE *f, char **environment);
56+
int deserialize_environment(char ***environment, const char *line);

src/core/manager.c

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2459,7 +2459,6 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) {
24592459
Iterator i;
24602460
Unit *u;
24612461
const char *t;
2462-
char **e;
24632462
int r;
24642463

24652464
assert(m);
@@ -2489,17 +2488,8 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) {
24892488
dual_timestamp_serialize(f, "units-load-finish-timestamp", &m->units_load_finish_timestamp);
24902489
}
24912490

2492-
if (!switching_root) {
2493-
STRV_FOREACH(e, m->environment) {
2494-
_cleanup_free_ char *ce;
2495-
2496-
ce = cescape(*e);
2497-
if (!ce)
2498-
return -ENOMEM;
2499-
2500-
fprintf(f, "env=%s\n", *e);
2501-
}
2502-
}
2491+
if (!switching_root)
2492+
(void) serialize_environment(f, m->environment);
25032493

25042494
if (m->notify_fd >= 0) {
25052495
int copy;
@@ -2662,21 +2652,9 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
26622652
else if ((val = startswith(l, "units-load-finish-timestamp=")))
26632653
dual_timestamp_deserialize(val, &m->units_load_finish_timestamp);
26642654
else if (startswith(l, "env=")) {
2665-
_cleanup_free_ char *uce = NULL;
2666-
char **e;
2667-
2668-
r = cunescape(l + 4, UNESCAPE_RELAX, &uce);
2655+
r = deserialize_environment(&m->environment, l);
26692656
if (r < 0)
2670-
goto finish;
2671-
2672-
e = strv_env_set(m->environment, uce);
2673-
if (!e) {
2674-
r = -ENOMEM;
2675-
goto finish;
2676-
}
2677-
2678-
strv_free(m->environment);
2679-
m->environment = e;
2657+
return r;
26802658

26812659
} else if ((val = startswith(l, "notify-fd="))) {
26822660
int fd;

0 commit comments

Comments
 (0)