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 - 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-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>
|
<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/>
|
[![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;
|
event = s->event;
|
||||||
|
|
||||||
s->type = _SOURCE_EVENT_SOURCE_TYPE_INVALID;
|
|
||||||
s->event = NULL;
|
s->event = NULL;
|
||||||
LIST_REMOVE(sources, event->sources, s);
|
LIST_REMOVE(sources, event->sources, s);
|
||||||
event->n_sources--;
|
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)
|
if (!s->floating)
|
||||||
sd_event_unref(event);
|
sd_event_unref(event);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1146,31 +1146,32 @@ static int find_matching_component(const CalendarSpec *spec, const CalendarCompo
|
||||||
return r;
|
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;
|
struct tm t;
|
||||||
assert(tm);
|
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"
|
* 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
|
* don't cause find_next() to loop forever. tm_year contains years
|
||||||
* since 1900, so adjust it accordingly.
|
* since 1900, so adjust it accordingly.
|
||||||
*/
|
*/
|
||||||
if (tm->tm_year + 1900 > MAX_YEAR)
|
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 */
|
/* Did any normalization take place? If so, it was out of bounds before */
|
||||||
return
|
bool good = t.tm_year == tm->tm_year &&
|
||||||
t.tm_year != tm->tm_year ||
|
t.tm_mon == tm->tm_mon &&
|
||||||
t.tm_mon != tm->tm_mon ||
|
t.tm_mday == tm->tm_mday &&
|
||||||
t.tm_mday != tm->tm_mday ||
|
t.tm_hour == tm->tm_hour &&
|
||||||
t.tm_hour != tm->tm_hour ||
|
t.tm_min == tm->tm_min &&
|
||||||
t.tm_min != tm->tm_min ||
|
t.tm_sec == tm->tm_sec;
|
||||||
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) {
|
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)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
if (tm_out_of_bounds(&c, spec->utc))
|
if (tm_within_bounds(&c, spec->utc) <= 0)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
c.tm_mon += 1;
|
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_mday = 1;
|
||||||
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 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_year++;
|
c.tm_year++;
|
||||||
c.tm_mon = 0;
|
c.tm_mon = 0;
|
||||||
c.tm_mday = 1;
|
c.tm_mday = 1;
|
||||||
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
|
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (r == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
r = find_matching_component(spec, spec->day, &c, &c.tm_mday);
|
r = find_matching_component(spec, spec->day, &c, &c.tm_mday);
|
||||||
if (r > 0)
|
if (r > 0)
|
||||||
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 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_mon++;
|
||||||
c.tm_mday = 1;
|
c.tm_mday = 1;
|
||||||
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
|
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (r == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!matches_weekday(spec->weekdays_bits, &c, spec->utc)) {
|
if (!matches_weekday(spec->weekdays_bits, &c, spec->utc)) {
|
||||||
c.tm_mday++;
|
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);
|
r = find_matching_component(spec, spec->hour, &c, &c.tm_hour);
|
||||||
if (r > 0)
|
if (r > 0)
|
||||||
c.tm_min = c.tm_sec = tm_usec = 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_mday++;
|
||||||
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
|
c.tm_hour = c.tm_min = c.tm_sec = tm_usec = 0;
|
||||||
continue;
|
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);
|
r = find_matching_component(spec, spec->minute, &c, &c.tm_min);
|
||||||
if (r > 0)
|
if (r > 0)
|
||||||
c.tm_sec = tm_usec = 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_hour++;
|
||||||
c.tm_min = c.tm_sec = tm_usec = 0;
|
c.tm_min = c.tm_sec = tm_usec = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (r == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
c.tm_sec = c.tm_sec * USEC_PER_SEC + tm_usec;
|
c.tm_sec = c.tm_sec * USEC_PER_SEC + tm_usec;
|
||||||
r = find_matching_component(spec, spec->microsecond, &c, &c.tm_sec);
|
r = find_matching_component(spec, spec->microsecond, &c, &c.tm_sec);
|
||||||
tm_usec = c.tm_sec % USEC_PER_SEC;
|
tm_usec = c.tm_sec % USEC_PER_SEC;
|
||||||
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_min++;
|
||||||
c.tm_sec = tm_usec = 0;
|
c.tm_sec = tm_usec = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (r == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
*tm = c;
|
*tm = c;
|
||||||
*usec = tm_usec;
|
*usec = tm_usec;
|
||||||
|
|
Loading…
Reference in New Issue