| //===----------------------------------------------------------------------===// |
| // |
| // 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 |
| // |
| //===----------------------------------------------------------------------===// |
| /// |
| /// \file |
| /// Integration tests for the POSIX setenv function. |
| /// |
| //===----------------------------------------------------------------------===// |
| |
| #include "src/stdlib/getenv.h" |
| #include "src/stdlib/setenv.h" |
| #include "src/string/strcmp.h" |
| |
| #include "test/IntegrationTest/test.h" |
| |
| #include <errno.h> |
| |
| TEST_MAIN([[maybe_unused]] int argc, [[maybe_unused]] char **argv, |
| [[maybe_unused]] char **envp) { |
| // Test: Basic |
| { |
| // Set a simple environment variable |
| ASSERT_EQ(LIBC_NAMESPACE::setenv("SETENV_TEST_VAR", "test_value", 1), 0); |
| ASSERT_ERRNO_SUCCESS(); |
| |
| // Verify it was set |
| char *value = LIBC_NAMESPACE::getenv("SETENV_TEST_VAR"); |
| ASSERT_NE(value, nullptr); |
| ASSERT_EQ(LIBC_NAMESPACE::strcmp(value, "test_value"), 0); |
| } |
| |
| // Test: OverwriteExisting |
| { |
| // Set initial value |
| ASSERT_EQ(LIBC_NAMESPACE::setenv("OVERWRITE_VAR", "original", 1), 0); |
| ASSERT_ERRNO_SUCCESS(); |
| ASSERT_EQ(LIBC_NAMESPACE::strcmp(LIBC_NAMESPACE::getenv("OVERWRITE_VAR"), |
| "original"), |
| 0); |
| |
| // Overwrite with new value (overwrite = 1) |
| ASSERT_EQ(LIBC_NAMESPACE::setenv("OVERWRITE_VAR", "replaced", 1), 0); |
| ASSERT_ERRNO_SUCCESS(); |
| ASSERT_EQ(LIBC_NAMESPACE::strcmp(LIBC_NAMESPACE::getenv("OVERWRITE_VAR"), |
| "replaced"), |
| 0); |
| } |
| |
| // Test: NoOverwriteFlag |
| { |
| // Set initial value |
| ASSERT_EQ(LIBC_NAMESPACE::setenv("NO_OVERWRITE_VAR", "original", 1), 0); |
| ASSERT_ERRNO_SUCCESS(); |
| ASSERT_EQ(LIBC_NAMESPACE::strcmp(LIBC_NAMESPACE::getenv("NO_OVERWRITE_VAR"), |
| "original"), |
| 0); |
| |
| // Try to set with overwrite = 0 (should not change) |
| ASSERT_EQ(LIBC_NAMESPACE::setenv("NO_OVERWRITE_VAR", "ignored", 0), 0); |
| ASSERT_ERRNO_SUCCESS(); |
| ASSERT_EQ(LIBC_NAMESPACE::strcmp(LIBC_NAMESPACE::getenv("NO_OVERWRITE_VAR"), |
| "original"), |
| 0); |
| |
| // Verify it still works with overwrite = 1 |
| ASSERT_EQ(LIBC_NAMESPACE::setenv("NO_OVERWRITE_VAR", "changed", 1), 0); |
| ASSERT_ERRNO_SUCCESS(); |
| ASSERT_EQ(LIBC_NAMESPACE::strcmp(LIBC_NAMESPACE::getenv("NO_OVERWRITE_VAR"), |
| "changed"), |
| 0); |
| } |
| |
| // Note: passing nullptr for name or value is undefined behavior per POSIX. |
| // The implementation uses LIBC_CRASH_ON_NULLPTR for both, so there is no |
| // test for that case here. |
| |
| // Test: EmptyName |
| { |
| errno = 0; |
| ASSERT_EQ(LIBC_NAMESPACE::setenv("", "value", 1), -1); |
| ASSERT_ERRNO_EQ(EINVAL); |
| } |
| |
| // Test: NameWithEquals |
| { |
| errno = 0; |
| ASSERT_EQ(LIBC_NAMESPACE::setenv("BAD=NAME", "value", 1), -1); |
| ASSERT_ERRNO_EQ(EINVAL); |
| } |
| |
| // Test: EmptyValue |
| { |
| // Empty value is valid - just means variable is set to empty string |
| errno = 0; |
| ASSERT_EQ(LIBC_NAMESPACE::setenv("EMPTY_VALUE_VAR", "", 1), 0); |
| ASSERT_ERRNO_SUCCESS(); |
| |
| char *value = LIBC_NAMESPACE::getenv("EMPTY_VALUE_VAR"); |
| ASSERT_NE(value, nullptr); |
| ASSERT_EQ(LIBC_NAMESPACE::strcmp(value, ""), 0); |
| } |
| |
| // Test: MultipleVariables |
| { |
| // Set multiple different variables |
| errno = 0; |
| ASSERT_EQ(LIBC_NAMESPACE::setenv("VAR1", "value1", 1), 0); |
| ASSERT_ERRNO_SUCCESS(); |
| ASSERT_EQ(LIBC_NAMESPACE::setenv("VAR2", "value2", 1), 0); |
| ASSERT_ERRNO_SUCCESS(); |
| ASSERT_EQ(LIBC_NAMESPACE::setenv("VAR3", "value3", 1), 0); |
| ASSERT_ERRNO_SUCCESS(); |
| |
| // Verify all are set correctly |
| ASSERT_EQ(LIBC_NAMESPACE::strcmp(LIBC_NAMESPACE::getenv("VAR1"), "value1"), |
| 0); |
| ASSERT_EQ(LIBC_NAMESPACE::strcmp(LIBC_NAMESPACE::getenv("VAR2"), "value2"), |
| 0); |
| ASSERT_EQ(LIBC_NAMESPACE::strcmp(LIBC_NAMESPACE::getenv("VAR3"), "value3"), |
| 0); |
| } |
| |
| // Test: LongValues |
| { |
| // Test with longer strings |
| const char *long_name = "LONG_VAR_NAME_FOR_TESTING"; |
| const char *long_value = "This is a fairly long value string to test that " |
| "setenv handles longer strings correctly without " |
| "any memory issues or truncation problems"; |
| |
| ASSERT_EQ(LIBC_NAMESPACE::setenv(long_name, long_value, 1), 0); |
| ASSERT_ERRNO_SUCCESS(); |
| ASSERT_EQ( |
| LIBC_NAMESPACE::strcmp(LIBC_NAMESPACE::getenv(long_name), long_value), |
| 0); |
| } |
| |
| // Test: SpecialCharacters |
| { |
| // Test with special characters in value (but not in name) |
| ASSERT_EQ(LIBC_NAMESPACE::setenv("SPECIAL_CHARS", "!@#$%^&*()", 1), 0); |
| ASSERT_ERRNO_SUCCESS(); |
| ASSERT_EQ(LIBC_NAMESPACE::strcmp(LIBC_NAMESPACE::getenv("SPECIAL_CHARS"), |
| "!@#$%^&*()"), |
| 0); |
| } |
| |
| // Test: ReplaceMultipleTimes |
| { |
| // Replace the same variable multiple times |
| ASSERT_EQ(LIBC_NAMESPACE::setenv("MULTI_REPLACE", "value1", 1), 0); |
| ASSERT_ERRNO_SUCCESS(); |
| ASSERT_EQ(LIBC_NAMESPACE::strcmp(LIBC_NAMESPACE::getenv("MULTI_REPLACE"), |
| "value1"), |
| 0); |
| |
| ASSERT_EQ(LIBC_NAMESPACE::setenv("MULTI_REPLACE", "value2", 1), 0); |
| ASSERT_ERRNO_SUCCESS(); |
| ASSERT_EQ(LIBC_NAMESPACE::strcmp(LIBC_NAMESPACE::getenv("MULTI_REPLACE"), |
| "value2"), |
| 0); |
| |
| ASSERT_EQ(LIBC_NAMESPACE::setenv("MULTI_REPLACE", "value3", 1), 0); |
| ASSERT_ERRNO_SUCCESS(); |
| ASSERT_EQ(LIBC_NAMESPACE::strcmp(LIBC_NAMESPACE::getenv("MULTI_REPLACE"), |
| "value3"), |
| 0); |
| } |
| |
| return 0; |
| } |