calendar-spec: use SAVE_TIMEZONE

Then, we can avoid heavy fork() operation.
This commit is contained in:
Yu Watanabe
2025-09-28 10:09:47 +09:00
parent 39179ac5fe
commit 672924356f
+8 -37
View File
@@ -1426,13 +1426,7 @@ static int calendar_spec_next_usec_impl(const CalendarSpec *spec, usec_t usec, u
return 0;
}
typedef struct SpecNextResult {
usec_t next;
int return_value;
} SpecNextResult;
int calendar_spec_next_usec(const CalendarSpec *spec, usec_t usec, usec_t *ret_next) {
SpecNextResult *shared, tmp;
int r;
assert(spec);
@@ -1440,39 +1434,16 @@ int calendar_spec_next_usec(const CalendarSpec *spec, usec_t usec, usec_t *ret_n
if (isempty(spec->timezone))
return calendar_spec_next_usec_impl(spec, usec, ret_next);
shared = mmap(NULL, sizeof *shared, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
if (shared == MAP_FAILED)
return negative_errno();
SAVE_TIMEZONE;
r = safe_fork("(sd-calendar)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL|FORK_WAIT, NULL);
if (r < 0) {
(void) munmap(shared, sizeof *shared);
/* tzset(3) says $TZ should be prefixed with ":" if we reference timezone files */
const char *colon_tz = strjoina(":", spec->timezone);
r = RET_NERRNO(setenv("TZ", colon_tz, 1));
if (r < 0)
return r;
}
if (r == 0) {
char *colon_tz;
/* tzset(3) says $TZ should be prefixed with ":" if we reference timezone files */
colon_tz = strjoina(":", spec->timezone);
tzset();
if (setenv("TZ", colon_tz, 1) != 0) {
shared->return_value = negative_errno();
_exit(EXIT_FAILURE);
}
tzset();
shared->return_value = calendar_spec_next_usec_impl(spec, usec, &shared->next);
_exit(EXIT_SUCCESS);
}
tmp = *shared;
if (munmap(shared, sizeof *shared) < 0)
return negative_errno();
if (tmp.return_value == 0 && ret_next)
*ret_next = tmp.next;
return tmp.return_value;
return calendar_spec_next_usec_impl(spec, usec, ret_next);
}