Skip to content

Commit

Permalink
libc: common: implement ctime() & ctime_r()
Browse files Browse the repository at this point in the history
Add implementation & test for `ctime()` & `ctime_r()`.
Since this function is equivalent to
`asctime(localtime(clock))`, it inherits the limitation of
`localtime()` as well, which only supports UTC results
currently.

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
  • Loading branch information
ycsin committed Jun 21, 2024
1 parent b6f768f commit 75e322a
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 2 deletions.
2 changes: 1 addition & 1 deletion doc/services/portability/posix/option_groups/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -900,7 +900,7 @@ _POSIX_THREAD_SAFE_FUNCTIONS
:widths: 50,10

asctime_r(), yes
ctime_r(),
ctime_r(), yes (UTC timezone only)
flockfile(),
ftrylockfile(),
funlockfile(),
Expand Down
1 change: 1 addition & 0 deletions lib/libc/common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_ABORT source/stdlib/abort.c)
zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_ASCTIME source/time/asctime.c)
zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_GMTIME_R source/time/gmtime_r.c)
zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_LOCALTIME_R_UTC source/time/localtime_r_utc.c)
zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_CTIME source/time/ctime.c)
zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_TIME source/time/time.c)
zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_MALLOC source/stdlib/malloc.c)
zephyr_library_sources_ifdef(CONFIG_COMMON_LIBC_STRNLEN source/string/strnlen.c)
Expand Down
13 changes: 13 additions & 0 deletions lib/libc/common/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,19 @@ config COMMON_LIBC_ASCTIME_R
help
common implementation of asctime_r().

config COMMON_LIBC_CTIME
bool
select COMMON_LIBC_LOCALTIME_R_UTC
help
common implementation of ctime().

config COMMON_LIBC_CTIME_R
bool "Thread-safe version of ctime()"
default y if POSIX_THREAD_SAFE_FUNCTIONS
select COMMON_LIBC_CTIME
help
common implementation of ctime_r().

config COMMON_LIBC_GMTIME_R
bool
help
Expand Down
26 changes: 26 additions & 0 deletions lib/libc/common/source/time/ctime.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (c) 2024 Meta Platforms
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <time.h>

/**
* `ctime()` is equivalent to `asctime(localtime(clock))`
* See: https://pubs.opengroup.org/onlinepubs/009695399/functions/ctime.html
*/

char *ctime(const time_t *clock)
{
return asctime(localtime(clock));
}

#if defined(CONFIG_COMMON_LIBC_CTIME_R)
char *ctime_r(const time_t *clock, char *buf)
{
struct tm tmp;

return asctime_r(localtime_r(clock, &tmp), buf);
}
#endif /* CONFIG_COMMON_LIBC_CTIME_R */
1 change: 1 addition & 0 deletions lib/libc/minimal/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ config MINIMAL_LIBC_TIME
select COMMON_LIBC_GMTIME_R
select COMMON_LIBC_ASCTIME
select COMMON_LIBC_LOCALTIME_R_UTC
select COMMON_LIBC_CTIME
default y
help
Enable time() and gmtime_r() for the minimal libc.
Expand Down
5 changes: 5 additions & 0 deletions lib/libc/minimal/include/time.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,16 @@ struct tm *gmtime_r(const time_t *ZRESTRICT timep,
char *asctime(const struct tm *timeptr);
struct tm *localtime(const time_t *timer);
struct tm *localtime_r(const time_t *ZRESTRICT timer, struct tm *ZRESTRICT result);
char *ctime(const time_t *clock);

#if defined(CONFIG_COMMON_LIBC_ASCTIME_R) || defined(__DOXYGEN__)
char *asctime_r(const struct tm *ZRESTRICT tp, char *ZRESTRICT buf);
#endif /* CONFIG_COMMON_LIBC_ASCTIME_R */

#if defined(CONFIG_COMMON_LIBC_CTIME_R) || defined(__DOXYGEN__)
char *ctime_r(const time_t *clock, char *buf);
#endif /* CONFIG_COMMON_LIBC_CTIME_R */

time_t time(time_t *tloc);

#ifdef __cplusplus
Expand Down
1 change: 1 addition & 0 deletions lib/posix/options/Kconfig.pthread
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ config POSIX_THREAD_SAFE_FUNCTIONS
select COMMON_LIBC_ASCTIME_R
select COMMON_LIBC_GMTIME_R
select COMMON_LIBC_LOCALTIME_R_UTC
select COMMON_LIBC_CTIME_R
help
Select 'y' here to enable POSIX thread-safe functions including asctime_r(), ctime_r(),
flockfile(), ftrylockfile(), funlockfile(), getc_unlocked(), getchar_unlocked(),
Expand Down
19 changes: 18 additions & 1 deletion tests/lib/c_lib/common/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1135,7 +1135,7 @@ ZTEST(libc_common, test_time_asctime)
}

/**
* @brief Test time function
* @brief Test time function
*
* @see localtime(), localtime_r().
*/
Expand All @@ -1156,6 +1156,23 @@ ZTEST(libc_common, test_time_localtime)
zassert_not_null(localtime_r(&tests4, &tp), "localtime_r failed");
}

/**
* @brief Test time function
*
* @see ctime(), ctime_r().
*/
ZTEST(libc_common, test_time_ctime)
{
char buf[26] = {0};
time_t time = 1718260000;

zassert_not_null(ctime_r(&time, buf));
zassert_equal(strncmp("Thu Jun 13 06:26:40 2024\n", buf, sizeof(buf)), 0);

zassert_not_null(ctime(&time));
zassert_equal(strncmp("Thu Jun 13 06:26:40 2024\n", ctime(&time), sizeof(buf)), 0);
}

/**
*
* @brief Test rand function
Expand Down
1 change: 1 addition & 0 deletions tests/lib/c_lib/common/testcase.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ tests:
- CONFIG_MINIMAL_LIBC_NON_REENTRANT_FUNCTIONS=y
- CONFIG_MINIMAL_LIBC_RAND=y
- CONFIG_COMMON_LIBC_ASCTIME_R=y
- CONFIG_COMMON_LIBC_CTIME_R=y
libraries.libc.common.newlib:
filter: CONFIG_NEWLIB_LIBC_SUPPORTED
min_ram: 32
Expand Down

0 comments on commit 75e322a

Please sign in to comment.