Skip to content
Merged
Changes from 1 commit
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
164 changes: 92 additions & 72 deletions libc/test/src/fcntl/fcntl_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,78 +94,98 @@ TEST_F(LlvmLibcFcntlTest, FcntlSetFl) {
ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
}

TEST_F(LlvmLibcFcntlTest, FcntlGetLkRead) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
constexpr const char *TEST_FILE_NAME = "testdata/fcntl_getlkread.test";
auto TEST_FILE = libc_make_test_file_path(TEST_FILE_NAME);

struct flock flk, svflk;
int retVal;
int fd =
LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_TRUNC | O_RDONLY, S_IRWXU);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(fd, 0);

flk.l_type = F_RDLCK;
flk.l_start = 0;
flk.l_whence = SEEK_SET;
flk.l_len = 50;

// copy flk into svflk
svflk = flk;

retVal = LIBC_NAMESPACE::fcntl(fd, F_GETLK, &svflk);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(retVal, -1);
ASSERT_NE((int)flk.l_type, F_WRLCK); // File should not be write locked.

retVal = LIBC_NAMESPACE::fcntl(fd, F_SETLK, &svflk);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(retVal, -1);

ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
}

TEST_F(LlvmLibcFcntlTest, FcntlGetLkWrite) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
constexpr const char *TEST_FILE_NAME = "testdata/fcntl_getlkwrite.test";
auto TEST_FILE = libc_make_test_file_path(TEST_FILE_NAME);

struct flock flk, svflk;
int retVal;
int fd = LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(fd, 0);

flk.l_type = F_WRLCK;
flk.l_start = 0;
flk.l_whence = SEEK_SET;
flk.l_len = 0;

// copy flk into svflk
svflk = flk;

retVal = LIBC_NAMESPACE::fcntl(fd, F_GETLK, &svflk);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(retVal, -1);
ASSERT_NE((int)flk.l_type, F_RDLCK); // File should not be read locked.

retVal = LIBC_NAMESPACE::fcntl(fd, F_SETLK, &svflk);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(retVal, -1);

ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
}

TEST_F(LlvmLibcFcntlTest, UseAfterClose) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
constexpr const char *TEST_FILE_NAME = "testdata/fcntl_use_after_close.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);
ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
ASSERT_EQ(-1, LIBC_NAMESPACE::fcntl(fd, F_GETFL));
ASSERT_ERRNO_EQ(EBADF);
}
/* Tests that are common between OFD and traditional variants of fcntl locks. */
template <int GETLK_CMD, int SETLK_CMD>
class LibcFcntlCommonLockTests : public LlvmLibcFcntlTest {
public:
void GetLkRead() {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
constexpr const char *TEST_FILE_NAME = "testdata/fcntl_getlkread.test";
const auto TEST_FILE = libc_make_test_file_path(TEST_FILE_NAME);

struct flock flk = {};
struct flock svflk = {};
int retVal;
int fd =
LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_TRUNC | O_RDONLY, S_IRWXU);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(fd, 0);

flk.l_type = F_RDLCK;
flk.l_start = 0;
flk.l_whence = SEEK_SET;
flk.l_len = 50;

// copy flk into svflk
svflk = flk;

retVal = LIBC_NAMESPACE::fcntl(fd, GETLK_CMD, &svflk);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(retVal, -1);
ASSERT_NE((int)svflk.l_type, F_WRLCK); // File should not be write locked.

retVal = LIBC_NAMESPACE::fcntl(fd, SETLK_CMD, &svflk);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(retVal, -1);

ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
}

void GetLkWrite() {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
constexpr const char *TEST_FILE_NAME = "testdata/fcntl_getlkwrite.test";
const auto TEST_FILE = libc_make_test_file_path(TEST_FILE_NAME);

struct flock flk = {};
struct flock svflk = {};
int retVal;
int fd =
LIBC_NAMESPACE::open(TEST_FILE, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(fd, 0);

flk.l_type = F_WRLCK;
flk.l_start = 0;
flk.l_whence = SEEK_SET;
flk.l_len = 0;

// copy flk into svflk
svflk = flk;

retVal = LIBC_NAMESPACE::fcntl(fd, GETLK_CMD, &svflk);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(retVal, -1);
ASSERT_NE((int)svflk.l_type, F_RDLCK); // File should not be read locked.

retVal = LIBC_NAMESPACE::fcntl(fd, SETLK_CMD, &svflk);
ASSERT_ERRNO_SUCCESS();
ASSERT_GT(retVal, -1);

ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
}

void UseAfterClose() {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
constexpr const char *TEST_FILE_NAME =
"testdata/fcntl_use_after_close.test";
const 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);
ASSERT_THAT(LIBC_NAMESPACE::close(fd), Succeeds(0));
ASSERT_EQ(-1, LIBC_NAMESPACE::fcntl(fd, GETLK_CMD));
ASSERT_ERRNO_EQ(EBADF);
}
};

#define COMMON_LOCK_TESTS(NAME, GETLK, SETLK) \
using NAME = LibcFcntlCommonLockTests<GETLK, SETLK>; \
TEST_F(NAME, GetLkRead) { GetLkRead(); } \
TEST_F(NAME, GetLkWrite) { GetLkWrite(); } \
TEST_F(NAME, UseAfterClose) { UseAfterClose(); }

COMMON_LOCK_TESTS(LlvmLibcFcntlProcessAssociatedLockTest, F_GETLK, F_SETLK)
COMMON_LOCK_TESTS(LlvmLibcFcntlOpenFileDescriptionLockTest, F_OFD_GETLK,
F_OFD_SETLK)

TEST_F(LlvmLibcFcntlTest, SetGetOwnerTest) {
using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;
Expand Down
Loading