X Tutup
Skip to content

Commit bdaeafe

Browse files
committed
time-util: add variant of timezone_is_valid() that returns errno
This will be useful for tests to skip missing time zones.
1 parent 2f15b35 commit bdaeafe

File tree

3 files changed

+34
-26
lines changed

3 files changed

+34
-26
lines changed

src/basic/time-util.c

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,73 +1381,66 @@ int get_timezones(char ***ret) {
13811381
return 0;
13821382
}
13831383

1384-
bool timezone_is_valid(const char *name, int log_level) {
1384+
int verify_timezone(const char *name, int log_level) {
13851385
bool slash = false;
13861386
const char *p, *t;
13871387
_cleanup_close_ int fd = -1;
13881388
char buf[4];
13891389
int r;
13901390

13911391
if (isempty(name))
1392-
return false;
1392+
return -EINVAL;
13931393

13941394
/* Always accept "UTC" as valid timezone, since it's the fallback, even if user has no timezones installed. */
13951395
if (streq(name, "UTC"))
1396-
return true;
1396+
return 0;
13971397

13981398
if (name[0] == '/')
1399-
return false;
1399+
return -EINVAL;
14001400

14011401
for (p = name; *p; p++) {
14021402
if (!(*p >= '0' && *p <= '9') &&
14031403
!(*p >= 'a' && *p <= 'z') &&
14041404
!(*p >= 'A' && *p <= 'Z') &&
14051405
!IN_SET(*p, '-', '_', '+', '/'))
1406-
return false;
1406+
return -EINVAL;
14071407

14081408
if (*p == '/') {
14091409

14101410
if (slash)
1411-
return false;
1411+
return -EINVAL;
14121412

14131413
slash = true;
14141414
} else
14151415
slash = false;
14161416
}
14171417

14181418
if (slash)
1419-
return false;
1419+
return -EINVAL;
14201420

14211421
if (p - name >= PATH_MAX)
1422-
return false;
1422+
return -ENAMETOOLONG;
14231423

14241424
t = strjoina("/usr/share/zoneinfo/", name);
14251425

14261426
fd = open(t, O_RDONLY|O_CLOEXEC);
1427-
if (fd < 0) {
1428-
log_full_errno(log_level, errno, "Failed to open timezone file '%s': %m", t);
1429-
return false;
1430-
}
1427+
if (fd < 0)
1428+
return log_full_errno(log_level, errno, "Failed to open timezone file '%s': %m", t);
14311429

14321430
r = fd_verify_regular(fd);
1433-
if (r < 0) {
1434-
log_full_errno(log_level, r, "Timezone file '%s' is not a regular file: %m", t);
1435-
return false;
1436-
}
1431+
if (r < 0)
1432+
return log_full_errno(log_level, r, "Timezone file '%s' is not a regular file: %m", t);
14371433

14381434
r = loop_read_exact(fd, buf, 4, false);
1439-
if (r < 0) {
1440-
log_full_errno(log_level, r, "Failed to read from timezone file '%s': %m", t);
1441-
return false;
1442-
}
1435+
if (r < 0)
1436+
return log_full_errno(log_level, r, "Failed to read from timezone file '%s': %m", t);
14431437

14441438
/* Magic from tzfile(5) */
1445-
if (memcmp(buf, "TZif", 4) != 0) {
1446-
log_full(log_level, "Timezone file '%s' has wrong magic bytes", t);
1447-
return false;
1448-
}
1439+
if (memcmp(buf, "TZif", 4) != 0)
1440+
return log_full_errno(log_level, SYNTHETIC_ERRNO(EIO),
1441+
"Timezone file '%s' has wrong magic bytes", t);
14491442

1450-
return true;
1443+
return 0;
14511444
}
14521445

14531446
bool clock_boottime_supported(void) {

src/basic/time-util.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,10 @@ int parse_time(const char *t, usec_t *usec, usec_t default_unit);
134134
int parse_nsec(const char *t, nsec_t *nsec);
135135

136136
int get_timezones(char ***l);
137-
bool timezone_is_valid(const char *name, int log_level);
137+
int verify_timezone(const char *name, int log_level);
138+
static inline bool timezone_is_valid(const char *name, int log_level) {
139+
return verify_timezone(name, log_level) >= 0;
140+
}
138141

139142
bool clock_boottime_supported(void);
140143
bool clock_supported(clockid_t clock);

src/test/test-time-util.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,17 @@ static void test_format_timespan(usec_t accuracy) {
243243
test_format_timespan_one(USEC_INFINITY, accuracy);
244244
}
245245

246+
static void test_verify_timezone(void) {
247+
log_info("/* %s */", __func__);
248+
249+
assert_se(verify_timezone("Europe/Berlin", LOG_DEBUG) == 0);
250+
assert_se(verify_timezone("Australia/Sydney", LOG_DEBUG) == 0);
251+
assert_se(verify_timezone("Europe/Do not exist", LOG_DEBUG) == -EINVAL);
252+
assert_se(verify_timezone("Europe/DoNotExist", LOG_DEBUG) == -ENOENT);
253+
assert_se(verify_timezone("/DoNotExist", LOG_DEBUG) == -EINVAL);
254+
assert_se(verify_timezone("DoNotExist/", LOG_DEBUG) == -EINVAL);
255+
}
256+
246257
static void test_timezone_is_valid(void) {
247258
log_info("/* %s */", __func__);
248259

@@ -607,6 +618,7 @@ int main(int argc, char *argv[]) {
607618
test_format_timespan(1);
608619
test_format_timespan(USEC_PER_MSEC);
609620
test_format_timespan(USEC_PER_SEC);
621+
test_verify_timezone();
610622
test_timezone_is_valid();
611623
test_get_timezones();
612624
test_usec_add();

0 commit comments

Comments
 (0)
X Tutup