-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[libc] Add ctime_s
#110676
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[libc] Add ctime_s
#110676
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| //===-- Proxy for errno_t -------------------------------------------------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| #ifndef LLVM_LIBC_HDR_TYPES_ERRNO_T_H | ||
| #define LLVM_LIBC_HDR_TYPES_ERRNO_T_H | ||
|
|
||
| #ifdef LIBC_FULL_BUILD | ||
|
|
||
| #include "include/llvm-libc-types/errno_t.h" | ||
|
|
||
| #else | ||
|
|
||
| #define __STDC_WANT_LIB_EXT1__ 1 | ||
| #include <errno.h> | ||
|
|
||
| #endif // LIBC_FULL_BUILD | ||
|
|
||
| #endif // LLVM_LIBC_HDR_TYPES_ERRNO_T_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| //===-- Proxy for rsize_t -------------------------------------------------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| #ifndef LLVM_LIBC_HDR_TYPES_RSIZE_T_H | ||
| #define LLVM_LIBC_HDR_TYPES_RSIZE_T_H | ||
|
|
||
| #ifdef LIBC_FULL_BUILD | ||
|
|
||
| #include "include/llvm-libc-types/rsize_t.h" | ||
|
|
||
| #else | ||
|
|
||
| #define __need_rsize_t | ||
| #include <stddef.h> | ||
| #undef __need_rsize_t | ||
|
|
||
| #endif // LIBC_FULL_BUILD | ||
|
|
||
| #endif // LLVM_LIBC_HDR_TYPES_RSIZE_T_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| //===-- Definition of errno_t type ----------------------------------------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_LIBC_TYPES_ERRNO_T_H | ||
| #define LLVM_LIBC_TYPES_ERRNO_T_H | ||
|
|
||
| typedef int errno_t; | ||
|
|
||
| #endif // LLVM_LIBC_TYPES_ERRNO_T_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| //===-- Definition of rsize_t type ----------------------------------------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_LIBC_TYPES_RSIZE_T_H | ||
| #define LLVM_LIBC_TYPES_RSIZE_T_H | ||
|
|
||
| #include "size_t.h" | ||
|
|
||
| typedef size_t rsize_t; | ||
|
|
||
| #endif // LLVM_LIBC_TYPES_RSIZE_T_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| //===-- Implementation of ctime_s function --------------------------------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #define __STDC_WANT_LIB_EXT1__ 1 | ||
|
|
||
| #include "ctime_s.h" | ||
| #include "hdr/errno_macros.h" | ||
Rajveer100 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| #include "hdr/types/errno_t.h" | ||
| #include "hdr/types/rsize_t.h" | ||
| #include "src/__support/CPP/limits.h" | ||
| #include "src/__support/common.h" | ||
| #include "src/__support/macros/config.h" | ||
| #include "time_utils.h" | ||
|
|
||
| namespace LIBC_NAMESPACE_DECL { | ||
|
|
||
| LLVM_LIBC_FUNCTION(errno_t, ctime_s, | ||
| (char *buffer, rsize_t buffer_size, const time_t *t_ptr)) { | ||
| // TODO (https://github.com/llvm/llvm-project/issues/115907): invoke | ||
| // constraint handler | ||
| if (buffer == nullptr || t_ptr == nullptr) | ||
| return EINVAL; | ||
Rajveer100 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| if (buffer_size < time_constants::ASCTIME_MAX_BYTES || | ||
| buffer_size > RSIZE_MAX) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm...so I went to test this with GCC and found that: Looking into it, I found that clang's stdint provides Grepping gcc's sources for Which links to this paper documenting in explicit detail glibc developers experience with trying to implement Annex K: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1967.htm 95f1de3 added support for RSIZE_MAX and rsize_t without mentioning who was interested in Annex K support. https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2336.pdf looks like a more recent rebuttal to n1967. |
||
| buffer[0] = '\0'; | ||
Rajveer100 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return ERANGE; | ||
Rajveer100 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| if (*t_ptr > cpp::numeric_limits<int32_t>::max()) | ||
| return EINVAL; | ||
|
|
||
| if (time_utils::asctime(time_utils::localtime(t_ptr), buffer, buffer_size) == | ||
| nullptr) | ||
| return EINVAL; | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| } // namespace LIBC_NAMESPACE_DECL | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| //===-- Implementation header of ctime_s ------------------------*- C++ -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_LIBC_SRC_TIME_CTIME_S_H | ||
| #define LLVM_LIBC_SRC_TIME_CTIME_S_H | ||
|
|
||
| #include "hdr/types/errno_t.h" | ||
| #include "hdr/types/rsize_t.h" | ||
| #include "hdr/types/time_t.h" | ||
| #include "src/__support/macros/config.h" | ||
|
|
||
| namespace LIBC_NAMESPACE_DECL { | ||
|
|
||
| errno_t ctime_s(char *buffer, rsize_t buffer_size, const time_t *t_ptr); | ||
|
|
||
| } // namespace LIBC_NAMESPACE_DECL | ||
|
|
||
| #endif // LLVM_LIBC_SRC_TIME_CTIME_S_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| //===-- Unittests for ctime_s ---------------------------------------------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #define __STDC_WANT_LIB_EXT1__ 1 | ||
|
|
||
| #include "hdr/errno_macros.h" | ||
| #include "hdr/types/errno_t.h" | ||
| #include "hdr/types/rsize_t.h" | ||
| #include "src/errno/libc_errno.h" | ||
| #include "src/time/ctime_s.h" | ||
| #include "src/time/time_utils.h" | ||
Rajveer100 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| #include "test/UnitTest/Test.h" | ||
| #include "test/src/time/TmHelper.h" | ||
|
|
||
| TEST(LlvmLibcCtimeS, Nullptr) { | ||
| errno_t result = LIBC_NAMESPACE::ctime_s(nullptr, 0, nullptr); | ||
| ASSERT_EQ(EINVAL, result); | ||
|
|
||
| char buffer[LIBC_NAMESPACE::time_constants::ASCTIME_BUFFER_SIZE]; | ||
| result = LIBC_NAMESPACE::ctime_s(buffer, sizeof(buffer), nullptr); | ||
| ASSERT_EQ(EINVAL, result); | ||
|
|
||
| time_t t; | ||
| result = LIBC_NAMESPACE::ctime_s(nullptr, 0, &t); | ||
| ASSERT_EQ(EINVAL, result); | ||
| } | ||
|
|
||
| TEST(LlvmLibcCtimeS, InvalidBufferSize) { | ||
| char buffer[LIBC_NAMESPACE::time_constants::ASCTIME_BUFFER_SIZE]; | ||
|
|
||
| time_t t = 0; | ||
| errno_t result = LIBC_NAMESPACE::ctime_s(buffer, 0, &t); | ||
| ASSERT_EQ(ERANGE, result); | ||
|
|
||
| result = LIBC_NAMESPACE::ctime_s(buffer, RSIZE_MAX + 1, &t); | ||
| ASSERT_EQ(ERANGE, result); | ||
| } | ||
|
|
||
| TEST(LlvmLibcCtimeS, ValidUnixTimestamp0) { | ||
| char buffer[LIBC_NAMESPACE::time_constants::ASCTIME_BUFFER_SIZE]; | ||
| // 1970-01-01 00:00:00. Test with a valid buffer size. | ||
| time_t t = 0; | ||
| errno_t result = LIBC_NAMESPACE::ctime_s(buffer, sizeof(buffer), &t); | ||
| ASSERT_STREQ("Thu Jan 1 00:00:00 1970\n", buffer); | ||
| ASSERT_EQ(0, result); | ||
| } | ||
|
|
||
| TEST(LlvmLibcCtimeS, ValidUnixTimestamp32Int) { | ||
| char buffer[LIBC_NAMESPACE::time_constants::ASCTIME_BUFFER_SIZE]; | ||
| // 2038-01-19 03:14:07. Test with a valid buffer size. | ||
| time_t t = 2147483647; | ||
| errno_t result = LIBC_NAMESPACE::ctime_s(buffer, sizeof(buffer), &t); | ||
| ASSERT_STREQ("Tue Jan 19 03:14:07 2038\n", buffer); | ||
| ASSERT_EQ(0, result); | ||
| } | ||
|
|
||
| TEST(LlvmLibcCtimeS, InvalidArgument) { | ||
| char buffer[LIBC_NAMESPACE::time_constants::ASCTIME_BUFFER_SIZE]; | ||
| time_t t = 2147483648; | ||
| errno_t result = LIBC_NAMESPACE::ctime_s(buffer, sizeof(buffer), &t); | ||
| ASSERT_EQ(EINVAL, result); | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.