[libc] add ioctl (#141393) · llvm/llvm-project@4039fdb (original) (raw)

``

1

`+

//===-- Unittests for ioctl -----------------------------------------------===//

`

``

2

`+

//

`

``

3

`+

// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.

`

``

4

`+

// See https://llvm.org/LICENSE.txt for license information.

`

``

5

`+

// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

`

``

6

`+

//

`

``

7

`+

//===----------------------------------------------------------------------===//

`

``

8

+

``

9

`+

#include "src/errno/libc_errno.h"

`

``

10

`+

#include "src/fcntl/open.h"

`

``

11

`+

#include "src/sys/ioctl/ioctl.h"

`

``

12

`+

#include "src/unistd/close.h"

`

``

13

`+

#include "src/unistd/read.h"

`

``

14

`+

#include "src/unistd/write.h"

`

``

15

+

``

16

`+

#include "test/UnitTest/ErrnoSetterMatcher.h"

`

``

17

`+

#include "test/UnitTest/Test.h"

`

``

18

+

``

19

`+

#include "hdr/sys_stat_macros.h"

`

``

20

+

``

21

`+

#include "hdr/sys_ioctl_macros.h"

`

``

22

+

``

23

`+

using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds;

`

``

24

+

``

25

`+

TEST(LlvmLibcSysIoctlTest, InvalidCommandAndFIONREAD) {

`

``

26

`+

LIBC_NAMESPACE::libc_errno = 0;

`

``

27

+

``

28

`+

// Setup the test file

`

``

29

`+

constexpr const char *TEST_FILE_NAME = "ioctl.test";

`

``

30

`+

constexpr const char TEST_MSG[] = "ioctl test";

`

``

31

`+

constexpr int TEST_MSG_SIZE = sizeof(TEST_MSG) - 1;

`

``

32

`+

auto TEST_FILE = libc_make_test_file_path(TEST_FILE_NAME);

`

``

33

`+

int new_test_file_fd = LIBC_NAMESPACE::open(

`

``

34

`+

TEST_FILE, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

`

``

35

`+

ASSERT_THAT(

`

``

36

`+

(int)LIBC_NAMESPACE::write(new_test_file_fd, TEST_MSG, TEST_MSG_SIZE),

`

``

37

`+

Succeeds(TEST_MSG_SIZE));

`

``

38

`+

ASSERT_ERRNO_SUCCESS();

`

``

39

`+

ASSERT_THAT(LIBC_NAMESPACE::close(new_test_file_fd), Succeeds(0));

`

``

40

`+

ASSERT_ERRNO_SUCCESS();

`

``

41

+

``

42

`+

// Reopen the file for testing

`

``

43

`+

int fd = LIBC_NAMESPACE::open(TEST_FILE, O_RDONLY);

`

``

44

`+

ASSERT_ERRNO_SUCCESS();

`

``

45

`+

ASSERT_GT(fd, 0);

`

``

46

+

``

47

`+

// FIONREAD reports the number of available bytes to read for the passed fd

`

``

48

`+

// This will report the full size of the file, as we haven't read anything yet

`

``

49

`+

int n = -1;

`

``

50

`+

int ret = LIBC_NAMESPACE::ioctl(fd, FIONREAD, &n);

`

``

51

`+

ASSERT_ERRNO_SUCCESS();

`

``

52

`+

ASSERT_GT(ret, -1);

`

``

53

`+

ASSERT_EQ(n, TEST_MSG_SIZE);

`

``

54

+

``

55

`+

// But if we read some bytes...

`

``

56

`+

constexpr int READ_COUNT = 5;

`

``

57

`+

char read_buffer[READ_COUNT];

`

``

58

`+

ASSERT_THAT((int)LIBC_NAMESPACE::read(fd, read_buffer, READ_COUNT),

`

``

59

`+

Succeeds(READ_COUNT));

`

``

60

+

``

61

`+

// ... n should have decreased by the number of bytes we've read

`

``

62

`+

int n_after_reading = -1;

`

``

63

`+

ret = LIBC_NAMESPACE::ioctl(fd, FIONREAD, &n_after_reading);

`

``

64

`+

ASSERT_ERRNO_SUCCESS();

`

``

65

`+

ASSERT_GT(ret, -1);

`

``

66

`+

ASSERT_EQ(n - READ_COUNT, n_after_reading);

`

``

67

+

``

68

`+

// 0xDEADBEEF is just a random nonexistent command;

`

``

69

`+

// calling this should always fail with ENOTTY

`

``

70

`+

ret = LIBC_NAMESPACE::ioctl(fd, 0xDEADBEEF, NULL);

`

``

71

`+

ASSERT_ERRNO_EQ(ENOTTY);

`

``

72

`+

ASSERT_EQ(ret, -1);

`

``

73

+

``

74

`+

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

`

``

75

`+

}

`