Compare commits
4 Commits
b7db8b7b13
...
b219d193a2
Author | SHA1 | Date |
---|---|---|
Anita Zhang | b219d193a2 | |
Christian Rebischke | 9d9010f2e9 | |
Zbigniew Jędrzejewski-Szmek | be75c86dc6 | |
Lennart Poettering | f598255951 |
|
@ -1,5 +1,7 @@
|
|||
# systemd - System and Service Manager
|
||||
|
||||
![systemd logo](https://avatars0.githubusercontent.com/u/1918868?s=200&v=4)
|
||||
|
||||
<a href="https://in.waw.pl/systemd-github-state/systemd-systemd-issues.svg"><img align="right" src="https://in.waw.pl/systemd-github-state/systemd-systemd-issues-small.svg" alt="Count of open issues over time"></a>
|
||||
<a href="https://in.waw.pl/systemd-github-state/systemd-systemd-pull-requests.svg"><img align="right" src="https://in.waw.pl/systemd-github-state/systemd-systemd-pull-requests-small.svg" alt="Count of open pull requests over time"></a>
|
||||
[![Semaphore CI Build Status](https://semaphoreci.com/api/v1/projects/28a5a3ca-3c56-4078-8b5e-7ed6ef912e14/443470/shields_badge.svg)](https://semaphoreci.com/systemd/systemd)<br/>
|
||||
|
|
|
@ -771,11 +771,13 @@ static void source_disconnect(sd_event_source *s) {
|
|||
|
||||
event = s->event;
|
||||
|
||||
s->type = _SOURCE_EVENT_SOURCE_TYPE_INVALID;
|
||||
s->event = NULL;
|
||||
LIST_REMOVE(sources, event->sources, s);
|
||||
event->n_sources--;
|
||||
|
||||
/* Note that we don't invalidate the type here, since we still need it in order to close the fd or
|
||||
* pidfd associated with this event source, which we'll do only on source_free(). */
|
||||
|
||||
if (!s->floating)
|
||||
sd_event_unref(event);
|
||||
}
|
||||
|
|
|
@ -1146,31 +1146,32 @@ static int find_matching_component(const CalendarSpec *spec, const CalendarCompo
|
|||
return r;
|
||||
}
|
||||
|
||||
static bool tm_out_of_bounds(const struct tm *tm, bool utc) {
|
||||
static int tm_within_bounds(struct tm *tm, bool utc) {
|
||||
struct tm t;
|
||||
assert(tm);
|
||||
|
||||
t = *tm;
|
||||
|
||||
if (mktime_or_timegm(&t, utc) < 0)
|
||||
return true;
|
||||
|
||||
/*
|
||||
* Set an upper bound on the year so impossible dates like "*-02-31"
|
||||
* don't cause find_next() to loop forever. tm_year contains years
|
||||
* since 1900, so adjust it accordingly.
|
||||
*/
|
||||
if (tm->tm_year + 1900 > MAX_YEAR)
|
||||
return true;
|
||||
return -ERANGE;
|
||||
|
||||
t = *tm;
|
||||
if (mktime_or_timegm(&t, utc) < 0)
|
||||
return negative_errno();
|
||||
|
||||
/* Did any normalization take place? If so, it was out of bounds before */
|
||||
return
|
||||
t.tm_year != tm->tm_year ||
|
||||
t.tm_mon != tm->tm_mon ||
|
||||
t.tm_mday != tm->tm_mday ||
|
||||
t.tm_hour != tm->tm_hour ||
|
||||
t.tm_min != tm->tm_min ||
|
||||
t.tm_sec != tm->tm_sec;
|
||||
bool good = t.tm_year == tm->tm_year &&
|
||||
t.tm_mon == tm->tm_mon &&
|
||||
t.tm_mday == tm->tm_mday &&
|
||||
t.tm_hour == tm->tm_hour &&
|
||||
t.tm_min == tm->tm_min &&
|
||||
t.tm_sec == tm->tm_sec;
|
||||
if (!good)
|
||||
*tm = t;
|
||||
return good;
|
||||
}
|
||||
|
||||
static bool matches_weekday(int weekdays_bits, const struct tm *tm, bool utc) {
|
||||
|
@ -1217,7 +1218,7 @@ static int find_next(const CalendarSpec *spec, struct tm *tm, usec_t *usec) {
|
|||
}
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (tm_out_of_bounds(&c, spec->utc))
|
||||
if (tm_within_bounds(&c, spec->utc) <= 0)
|
||||
return -ENOENT;
|
||||
|
||||
c.tm_mon += 1;
|
||||
|
@ -1228,23 +1229,27 @@ static int find_next(const CalendarSpec *spec, struct tm *tm, usec_t *usec) {
|
|||
c.tm_mday = 1;
|
||||
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
|
||||
}
|
||||
if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
|
||||
if (r < 0 || (r = tm_within_bounds(&c, spec->utc)) < 0) {
|
||||
c.tm_year++;
|
||||
c.tm_mon = 0;
|
||||
c.tm_mday = 1;
|
||||
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
|
||||
continue;
|
||||
}
|
||||
if (r == 0)
|
||||
continue;
|
||||
|
||||
r = find_matching_component(spec, spec->day, &c, &c.tm_mday);
|
||||
if (r > 0)
|
||||
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
|
||||
if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
|
||||
if (r < 0 || (r = tm_within_bounds(&c, spec->utc)) < 0) {
|
||||
c.tm_mon++;
|
||||
c.tm_mday = 1;
|
||||
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
|
||||
continue;
|
||||
}
|
||||
if (r == 0)
|
||||
continue;
|
||||
|
||||
if (!matches_weekday(spec->weekdays_bits, &c, spec->utc)) {
|
||||
c.tm_mday++;
|
||||
|
@ -1255,31 +1260,40 @@ static int find_next(const CalendarSpec *spec, struct tm *tm, usec_t *usec) {
|
|||
r = find_matching_component(spec, spec->hour, &c, &c.tm_hour);
|
||||
if (r > 0)
|
||||
c.tm_min = c.tm_sec = tm_usec = 0;
|
||||
if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
|
||||
if (r < 0 || (r = tm_within_bounds(&c, spec->utc)) < 0) {
|
||||
c.tm_mday++;
|
||||
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
|
||||
continue;
|
||||
}
|
||||
if (r == 0)
|
||||
/* The next hour we set might be missing if there
|
||||
* are time zone changes. Let's try again starting at
|
||||
* normalized time. */
|
||||
continue;
|
||||
|
||||
r = find_matching_component(spec, spec->minute, &c, &c.tm_min);
|
||||
if (r > 0)
|
||||
c.tm_sec = tm_usec = 0;
|
||||
if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
|
||||
if (r < 0 || (r = tm_within_bounds(&c, spec->utc)) < 0) {
|
||||
c.tm_hour++;
|
||||
c.tm_min = c.tm_sec = tm_usec = 0;
|
||||
continue;
|
||||
}
|
||||
if (r == 0)
|
||||
continue;
|
||||
|
||||
c.tm_sec = c.tm_sec * USEC_PER_SEC + tm_usec;
|
||||
r = find_matching_component(spec, spec->microsecond, &c, &c.tm_sec);
|
||||
tm_usec = c.tm_sec % USEC_PER_SEC;
|
||||
c.tm_sec /= USEC_PER_SEC;
|
||||
|
||||
if (r < 0 || tm_out_of_bounds(&c, spec->utc)) {
|
||||
if (r < 0 || (r = tm_within_bounds(&c, spec->utc)) < 0) {
|
||||
c.tm_min++;
|
||||
c.tm_sec = tm_usec = 0;
|
||||
continue;
|
||||
}
|
||||
if (r == 0)
|
||||
continue;
|
||||
|
||||
*tm = c;
|
||||
*usec = tm_usec;
|
||||
|
|
Loading…
Reference in New Issue