Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion libc/docs/configure.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ to learn about the defaults for your platform and target.
- ``LIBC_CONF_ENABLE_STRONG_STACK_PROTECTOR``: Enable -fstack-protector-strong to defend against stack smashing attack.
- ``LIBC_CONF_KEEP_FRAME_POINTER``: Keep frame pointer in functions for better debugging experience.
* **"errno" options**
- ``LIBC_CONF_ERRNO_MODE``: The implementation used for errno, acceptable values are LIBC_ERRNO_MODE_DEFAULT, LIBC_ERRNO_MODE_UNDEFINED, LIBC_ERRNO_MODE_THREAD_LOCAL, LIBC_ERRNO_MODE_SHARED, LIBC_ERRNO_MODE_EXTERNAL, and LIBC_ERRNO_MODE_SYSTEM.
- ``LIBC_CONF_ERRNO_MODE``: The implementation used for errno, acceptable values are LIBC_ERRNO_MODE_DEFAULT, LIBC_ERRNO_MODE_UNDEFINED, LIBC_ERRNO_MODE_THREAD_LOCAL, LIBC_ERRNO_MODE_SHARED, LIBC_ERRNO_MODE_EXTERNAL, LIBC_ERRNO_MODE_SYSTEM, and LIBC_ERRNO_MODE_SYSTEM_INLINE.
* **"general" options**
- ``LIBC_ADD_NULL_CHECKS``: Add nullptr checks in the library's implementations to some functions for which passing nullptr is undefined behavior.
* **"math" options**
Expand Down
13 changes: 13 additions & 0 deletions libc/test/src/stdio/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ add_libc_test(
libc.src.stdio.fread
libc.src.stdio.fseek
libc.src.stdio.fwrite
libc.test.UnitTest.ErrnoCheckingTest
)

add_libc_test(
Expand Down Expand Up @@ -68,6 +69,7 @@ add_libc_test(
libc.src.stdio.fread
libc.src.stdio.fwrite
libc.src.stdio.setvbuf
libc.test.UnitTest.ErrnoCheckingTest
)

add_libc_test(
Expand All @@ -88,6 +90,7 @@ add_libc_test(
libc.src.stdio.fread_unlocked
libc.src.stdio.funlockfile
libc.src.stdio.fwrite_unlocked
libc.test.UnitTest.ErrnoCheckingTest
)

add_libc_test(
Expand All @@ -109,6 +112,7 @@ add_libc_test(
libc.src.stdio.fread
libc.src.stdio.fseek
libc.src.stdio.fwrite
libc.test.UnitTest.ErrnoCheckingTest
LINK_LIBRARIES
LibcMemoryHelpers
)
Expand Down Expand Up @@ -438,6 +442,7 @@ if(${LIBC_TARGET_OS} STREQUAL "linux")
libc.src.sys.stat.mkdirat
libc.src.unistd.access
libc.src.unistd.close
libc.test.UnitTest.ErrnoCheckingTest
)

add_libc_test(
Expand All @@ -452,6 +457,7 @@ if(${LIBC_TARGET_OS} STREQUAL "linux")
libc.src.stdio.rename
libc.src.unistd.access
libc.src.unistd.close
libc.test.UnitTest.ErrnoCheckingTest
libc.test.UnitTest.ErrnoSetterMatcher
)

Expand All @@ -468,6 +474,7 @@ if(${LIBC_TARGET_OS} STREQUAL "linux")
libc.src.stdio.fgets
libc.src.stdio.fputs
libc.src.unistd.close
libc.test.UnitTest.ErrnoCheckingTest
libc.test.UnitTest.ErrnoSetterMatcher
)
endif()
Expand All @@ -488,6 +495,8 @@ add_libc_test(
libc.src.stdio.fopen
libc.src.stdio.fwrite
libc.src.stdio.getc
libc.test.UnitTest.ErrnoCheckingTest
libc.test.UnitTest.ErrnoSetterMatcher
)

add_libc_test(
Expand All @@ -510,6 +519,8 @@ add_libc_test(
libc.src.stdio.funlockfile
libc.src.stdio.fwrite
libc.src.stdio.getc_unlocked
libc.test.UnitTest.ErrnoCheckingTest
libc.test.UnitTest.ErrnoSetterMatcher
)

add_libc_test(
Expand All @@ -527,6 +538,8 @@ add_libc_test(
libc.src.stdio.fgets
libc.src.stdio.fopen
libc.src.stdio.fwrite
libc.test.UnitTest.ErrnoCheckingTest
libc.test.UnitTest.ErrnoSetterMatcher
)

add_libc_test(
Expand Down
14 changes: 6 additions & 8 deletions libc/test/src/stdio/fdopen_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,21 @@
#include "src/stdio/fdopen.h"

#include "hdr/fcntl_macros.h"
#include "src/__support/libc_errno.h"
#include "src/fcntl/open.h"
#include "src/stdio/fclose.h"
#include "src/stdio/fgets.h"
#include "src/stdio/fputs.h"
#include "src/unistd/close.h"
#include "test/UnitTest/ErrnoCheckingTest.h"
#include "test/UnitTest/ErrnoSetterMatcher.h"
#include "test/UnitTest/Test.h"

#include <sys/stat.h> // For S_IRWXU

TEST(LlvmLibcStdioFdopenTest, WriteAppendRead) {
using LlvmLibcStdioFdopenTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;

TEST_F(LlvmLibcStdioFdopenTest, WriteAppendRead) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
libc_errno = 0;
constexpr const char *TEST_FILE_NAME = "testdata/write_read_append.test";
auto TEST_FILE = libc_make_test_file_path(TEST_FILE_NAME);
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU);
Expand Down Expand Up @@ -52,8 +53,7 @@ TEST(LlvmLibcStdioFdopenTest, WriteAppendRead) {
ASSERT_ERRNO_SUCCESS();
}

TEST(LlvmLibcStdioFdopenTest, InvalidFd) {
libc_errno = 0;
TEST_F(LlvmLibcStdioFdopenTest, InvalidFd) {
constexpr const char *TEST_FILE_NAME = "testdata/invalid_fd.test";
auto TEST_FILE = libc_make_test_file_path(TEST_FILE_NAME);
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_TRUNC);
Expand All @@ -64,8 +64,7 @@ TEST(LlvmLibcStdioFdopenTest, InvalidFd) {
ASSERT_TRUE(nullptr == fp);
}

TEST(LlvmLibcStdioFdopenTest, InvalidMode) {
libc_errno = 0;
TEST_F(LlvmLibcStdioFdopenTest, InvalidMode) {
constexpr const char *TEST_FILE_NAME = "testdata/invalid_mode.test";
auto TEST_FILE = libc_make_test_file_path(TEST_FILE_NAME);
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_RDONLY, S_IRWXU);
Expand All @@ -83,7 +82,6 @@ TEST(LlvmLibcStdioFdopenTest, InvalidMode) {
auto *fp2 = LIBC_NAMESPACE::fdopen(fd, "w");
ASSERT_ERRNO_EQ(EINVAL);
ASSERT_TRUE(nullptr == fp2);
libc_errno = 0;
LIBC_NAMESPACE::close(fd);
ASSERT_ERRNO_SUCCESS();
}
22 changes: 12 additions & 10 deletions libc/test/src/stdio/fgetc_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,42 +14,44 @@
#include "src/stdio/fopen.h"
#include "src/stdio/fwrite.h"
#include "src/stdio/getc.h"
#include "test/UnitTest/ErrnoCheckingTest.h"
#include "test/UnitTest/ErrnoSetterMatcher.h"
#include "test/UnitTest/Test.h"

#include "hdr/stdio_macros.h"
#include "src/__support/libc_errno.h"

class LlvmLibcGetcTest : public LIBC_NAMESPACE::testing::Test {
using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;

class LlvmLibcGetcTest : public LIBC_NAMESPACE::testing::ErrnoCheckingTest {
public:
using GetcFunc = int(FILE *);
void test_with_func(GetcFunc *func, const char *filename) {
::FILE *file = LIBC_NAMESPACE::fopen(filename, "w");
ASSERT_FALSE(file == nullptr);
constexpr char CONTENT[] = "123456789";
constexpr size_t WRITE_SIZE = sizeof(CONTENT) - 1;
ASSERT_EQ(WRITE_SIZE, LIBC_NAMESPACE::fwrite(CONTENT, 1, WRITE_SIZE, file));
ASSERT_THAT(LIBC_NAMESPACE::fwrite(CONTENT, 1, WRITE_SIZE, file),
Succeeds(WRITE_SIZE));
// This is a write-only file so reads should fail.
ASSERT_EQ(func(file), EOF);
ASSERT_THAT(func(file), Fails(EBADF, EOF));
// This is an error and not a real EOF.
ASSERT_EQ(LIBC_NAMESPACE::feof(file), 0);
ASSERT_NE(LIBC_NAMESPACE::ferror(file), 0);
libc_errno = 0;

ASSERT_EQ(0, LIBC_NAMESPACE::fclose(file));
ASSERT_THAT(LIBC_NAMESPACE::fclose(file), Succeeds());

file = LIBC_NAMESPACE::fopen(filename, "r");
ASSERT_FALSE(file == nullptr);

for (size_t i = 0; i < WRITE_SIZE; ++i) {
int c = func(file);
ASSERT_EQ(c, int('1' + i));
ASSERT_THAT(func(file), Succeeds(int('1' + i)));
}
// Reading more should return EOF but not set error.
ASSERT_EQ(func(file), EOF);
ASSERT_THAT(func(file), Succeeds(EOF));
ASSERT_NE(LIBC_NAMESPACE::feof(file), 0);
ASSERT_EQ(LIBC_NAMESPACE::ferror(file), 0);

ASSERT_EQ(0, LIBC_NAMESPACE::fclose(file));
ASSERT_THAT(LIBC_NAMESPACE::fclose(file), Succeeds());
}
};

Expand Down
22 changes: 12 additions & 10 deletions libc/test/src/stdio/fgetc_unlocked_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,44 +17,46 @@
#include "src/stdio/funlockfile.h"
#include "src/stdio/fwrite.h"
#include "src/stdio/getc_unlocked.h"
#include "test/UnitTest/ErrnoCheckingTest.h"
#include "test/UnitTest/ErrnoSetterMatcher.h"
#include "test/UnitTest/Test.h"

#include "hdr/stdio_macros.h"
#include "src/__support/libc_errno.h"

class LlvmLibcGetcTest : public LIBC_NAMESPACE::testing::Test {
using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;

class LlvmLibcGetcTest : public LIBC_NAMESPACE::testing::ErrnoCheckingTest {
public:
using GetcFunc = int(FILE *);
void test_with_func(GetcFunc *func, const char *filename) {
::FILE *file = LIBC_NAMESPACE::fopen(filename, "w");
ASSERT_FALSE(file == nullptr);
constexpr char CONTENT[] = "123456789";
constexpr size_t WRITE_SIZE = sizeof(CONTENT) - 1;
ASSERT_EQ(WRITE_SIZE, LIBC_NAMESPACE::fwrite(CONTENT, 1, WRITE_SIZE, file));
ASSERT_THAT(LIBC_NAMESPACE::fwrite(CONTENT, 1, WRITE_SIZE, file),
Succeeds(WRITE_SIZE));
// This is a write-only file so reads should fail.
ASSERT_EQ(func(file), EOF);
ASSERT_THAT(func(file), Fails(EBADF, EOF));
// This is an error and not a real EOF.
ASSERT_EQ(LIBC_NAMESPACE::feof(file), 0);
ASSERT_NE(LIBC_NAMESPACE::ferror(file), 0);
libc_errno = 0;

ASSERT_EQ(0, LIBC_NAMESPACE::fclose(file));
ASSERT_THAT(LIBC_NAMESPACE::fclose(file), Succeeds());

file = LIBC_NAMESPACE::fopen(filename, "r");
ASSERT_FALSE(file == nullptr);

LIBC_NAMESPACE::flockfile(file);
for (size_t i = 0; i < WRITE_SIZE; ++i) {
int c = func(file);
ASSERT_EQ(c, int('1' + i));
ASSERT_THAT(func(file), Succeeds(int('1' + i)));
}
// Reading more should return EOF but not set error.
ASSERT_EQ(func(file), EOF);
ASSERT_THAT(func(file), Succeeds(EOF));
ASSERT_NE(LIBC_NAMESPACE::feof_unlocked(file), 0);
ASSERT_EQ(LIBC_NAMESPACE::ferror_unlocked(file), 0);

LIBC_NAMESPACE::funlockfile(file);
ASSERT_EQ(0, LIBC_NAMESPACE::fclose(file));
ASSERT_THAT(LIBC_NAMESPACE::fclose(file), Succeeds());
}
};

Expand Down
18 changes: 11 additions & 7 deletions libc/test/src/stdio/fgets_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@
#include "src/stdio/fgets.h"
#include "src/stdio/fopen.h"
#include "src/stdio/fwrite.h"
#include "test/UnitTest/ErrnoCheckingTest.h"
#include "test/UnitTest/ErrnoSetterMatcher.h"
#include "test/UnitTest/Test.h"

#include "src/__support/libc_errno.h"
using LlvmLibcFgetsTest = LIBC_NAMESPACE::testing::ErrnoCheckingTest;
using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher;

TEST(LlvmLibcFgetsTest, WriteAndReadCharacters) {
TEST_F(LlvmLibcFgetsTest, WriteAndReadCharacters) {
constexpr char FILENAME[] = "testdata/fgets.test";
::FILE *file = LIBC_NAMESPACE::fopen(FILENAME, "w");
ASSERT_FALSE(file == nullptr);
Expand All @@ -29,15 +32,15 @@ TEST(LlvmLibcFgetsTest, WriteAndReadCharacters) {
char buff[8];
char *output;

ASSERT_EQ(WRITE_SIZE, LIBC_NAMESPACE::fwrite(CONTENT, 1, WRITE_SIZE, file));
ASSERT_THAT(LIBC_NAMESPACE::fwrite(CONTENT, 1, WRITE_SIZE, file),
Succeeds(WRITE_SIZE));
// This is a write-only file so reads should fail.
ASSERT_TRUE(LIBC_NAMESPACE::fgets(buff, 8, file) == nullptr);
ASSERT_THAT(LIBC_NAMESPACE::fgets(buff, 8, file), Fails(EBADF, nullptr));
// This is an error and not a real EOF.
ASSERT_EQ(LIBC_NAMESPACE::feof(file), 0);
ASSERT_NE(LIBC_NAMESPACE::ferror(file), 0);
libc_errno = 0;

ASSERT_EQ(0, LIBC_NAMESPACE::fclose(file));
ASSERT_THAT(LIBC_NAMESPACE::fclose(file), Succeeds());

file = LIBC_NAMESPACE::fopen(FILENAME, "r");
ASSERT_FALSE(file == nullptr);
Expand All @@ -55,6 +58,7 @@ TEST(LlvmLibcFgetsTest, WriteAndReadCharacters) {
// This is also implementation defined.
output = LIBC_NAMESPACE::fgets(buff, 0, file);
ASSERT_TRUE(output == nullptr);
ASSERT_ERRNO_SUCCESS();
#endif

const char *output_arr[] = {
Expand Down Expand Up @@ -86,5 +90,5 @@ TEST(LlvmLibcFgetsTest, WriteAndReadCharacters) {
ASSERT_NE(LIBC_NAMESPACE::feof(file), 0);
ASSERT_ERRNO_SUCCESS();

ASSERT_EQ(0, LIBC_NAMESPACE::fclose(file));
ASSERT_THAT(LIBC_NAMESPACE::fclose(file), Succeeds());
}
Loading
Loading