calendarspec: warn on weekday/date conflict in systemd-analyze and systemd-run
When a fixed date (e.g. 2027-01-01) is paired with a weekday constraint (e.g. Thu) that does not match, the timer silently never elapses. Add calendar_spec_from_string_full(..., warn_on_weekday_mismatch) so user-facing tools can opt in to a log_warning() at parse time: - systemd-analyze calendar: uses _full(true) - systemd-run --on-calendar: uses _full(true) - .timer OnCalendar=: uses log_syntax() with file/line context Add test_calendar_spec_weekday_conflict(): forks a child with stderr captured in a memfd via pidref_safe_fork_full(), verifies the warning is emitted for conflicting specs and suppressed for valid ones. Fixes: #40350 Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
This commit is contained in:
committed by
Lennart Poettering
parent
9d37c618ee
commit
21de611f69
+18
-15
@@ -321,24 +321,26 @@ struct timeval *timeval_store(struct timeval *tv, usec_t u) {
|
||||
return tv;
|
||||
}
|
||||
|
||||
/* Returns the abbreviated English weekday name for wd in Mon=0 … Sun=6 order.
|
||||
* We use non-localized (English) form so that timestamps can be parsed with
|
||||
* parse_timestamp() and always read the same regardless of locale. */
|
||||
static const char *const weekday_table[_WEEKDAY_MAX] = {
|
||||
[WEEKDAY_MON] = "Mon",
|
||||
[WEEKDAY_TUE] = "Tue",
|
||||
[WEEKDAY_WED] = "Wed",
|
||||
[WEEKDAY_THU] = "Thu",
|
||||
[WEEKDAY_FRI] = "Fri",
|
||||
[WEEKDAY_SAT] = "Sat",
|
||||
[WEEKDAY_SUN] = "Sun",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP_TO_STRING(weekday, int);
|
||||
|
||||
char* format_timestamp_style(
|
||||
char *buf,
|
||||
size_t l,
|
||||
usec_t t,
|
||||
TimestampStyle style) {
|
||||
|
||||
/* The weekdays in non-localized (English) form. We use this instead of the localized form, so that
|
||||
* our generated timestamps may be parsed with parse_timestamp(), and always read the same. */
|
||||
static const char * const weekdays[] = {
|
||||
[0] = "Sun",
|
||||
[1] = "Mon",
|
||||
[2] = "Tue",
|
||||
[3] = "Wed",
|
||||
[4] = "Thu",
|
||||
[5] = "Fri",
|
||||
[6] = "Sat",
|
||||
};
|
||||
|
||||
struct tm tm;
|
||||
bool utc, us;
|
||||
size_t n;
|
||||
@@ -387,8 +389,9 @@ char* format_timestamp_style(
|
||||
return NULL;
|
||||
|
||||
/* Start with the week day */
|
||||
assert((size_t) tm.tm_wday < ELEMENTSOF(weekdays));
|
||||
memcpy(buf, weekdays[tm.tm_wday], 4);
|
||||
const char *weekday = weekday_to_string(tm.tm_wday == 0 ? 6 : tm.tm_wday - 1);
|
||||
assert(weekday);
|
||||
memcpy(buf, weekday, 4);
|
||||
|
||||
if (style == TIMESTAMP_DATE) {
|
||||
/* Special format string if only date should be shown. */
|
||||
|
||||
@@ -56,6 +56,18 @@ typedef enum TimestampStyle {
|
||||
#define USEC_PER_YEAR ((usec_t) (31557600ULL*USEC_PER_SEC))
|
||||
#define NSEC_PER_YEAR ((nsec_t) (31557600ULL*NSEC_PER_SEC))
|
||||
|
||||
enum {
|
||||
WEEKDAY_MON,
|
||||
WEEKDAY_TUE,
|
||||
WEEKDAY_WED,
|
||||
WEEKDAY_THU,
|
||||
WEEKDAY_FRI,
|
||||
WEEKDAY_SAT,
|
||||
WEEKDAY_SUN,
|
||||
_WEEKDAY_MAX,
|
||||
_WEEKDAY_INVALID = -EINVAL,
|
||||
};
|
||||
|
||||
/* We assume a maximum timezone length of 6. TZNAME_MAX is not defined on Linux, but glibc internally initializes this
|
||||
* to 6. Let's rely on that. */
|
||||
#define FORMAT_TIMESTAMP_MAX (3U+1U+10U+1U+8U+1U+6U+1U+6U+1U)
|
||||
@@ -125,6 +137,10 @@ char* format_timestamp_style(char *buf, size_t l, usec_t t, TimestampStyle style
|
||||
char* format_timestamp_relative_full(char *buf, size_t l, usec_t t, clockid_t clock, bool implicit_left) _warn_unused_result_;
|
||||
char* format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy) _warn_unused_result_;
|
||||
|
||||
/* Returns the abbreviated English weekday name for wd in Mon=0 … Sun=6 order
|
||||
* (matching systemd's weekdays_bits layout). */
|
||||
const char* weekday_to_string(int i);
|
||||
|
||||
_warn_unused_result_
|
||||
static inline char* format_timestamp_relative(char *buf, size_t l, usec_t t) {
|
||||
return format_timestamp_relative_full(buf, l, t, CLOCK_REALTIME, /* implicit_left= */ false);
|
||||
|
||||
Reference in New Issue
Block a user