Repository: google/gvisor
File: test/syscalls/linux/pwrite64.cc (C++)

Code before:

TEST_F(Pwrite64, Overflow) {
  int fd;
  ASSERT_THAT(fd = open(name_.c_str(), O_APPEND | O_RDWR), SyscallSucceeds());
  constexpr int64_t kBufSize = 1024;
  std::vector<char> buf(kBufSize);
  std::fill(buf.begin(), buf.end(), 'a');
  EXPECT_THAT(PwriteFd(fd, buf.data(), buf.size(), 0x7fffffffffffffffull),
              SyscallFailsWithErrno(EINVAL));
  EXPECT_THAT(close(fd), SyscallSucceeds());
}

TEST_F(Pwrite64, Pwrite64WithOpath) {
  const TempPath file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
  const FileDescriptor fd =
      ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_PATH));

  std::vector<char> buf(1);
  EXPECT_THAT(PwriteFd(fd.get(), buf.data(), 1, 0),
              SyscallFailsWithErrno(EBADF));
}

// Test that pwrite64 with a nullptr buffer fails with EFAULT.
TEST_F(Pwrite64, NullBuffer) {
  int fd;
  ASSERT_THAT(fd = open(name_.c_str(), O_RDWR), SyscallSucceeds());
  EXPECT_THAT(pwrite64(fd, nullptr, 1, 0), SyscallFailsWithErrno(EFAULT));
  EXPECT_THAT(close(fd), SyscallSucceeds());
}

// Test that pwrite64 with zero length and nullptr buffer succeeds.
TEST_F(Pwrite64, ZeroLengthNullBuffer) {
  int fd;
  ASSERT_THAT(fd = open(name_.c_str(), O_RDWR), SyscallSucceeds());
  EXPECT_THAT(pwrite64(fd, nullptr, 0, 0), SyscallSucceedsWithValue(0));
  EXPECT_THAT(close(fd), SyscallSucceeds());
}

// Test that pwrite64 to a closed fd fails with EBADF.
TEST_F(Pwrite64, ClosedFd) {
  int fd;
  ASSERT_THAT(fd = open(name_.c_str(), O_RDWR), SyscallSucceeds());
  ASSERT_THAT(close(fd), SyscallSucceeds());

  char buf[16];
  EXPECT_THAT(pwrite64(fd, buf, sizeof(buf), 0), SyscallFailsWithErrno(EBADF));
}

// Test that pwrite64 to a read-only fd fails with EBADF.
TEST_F(Pwrite64, ReadOnlyFd) {
  int fd;

Review comment (suggestion):
Instead of using `open()` and `close()` (which are easy to mess up and leak an FD in the test), use our `FileDescriptor` type, which is a RAII object which will close the FD once the variable goes out of scope. See other examples in this file. 

```
// Instead of:
int fd;
ASSERT_THAT(fd = open(...), SyscallSucceeds());
...
close(fd);

// Use:
FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(...));
```

For tests requiring a closed FD, use the following to immediately close the FD in the test body:
```
fd.reset();
```

Code after:
  EXPECT_THAT(close(fd), SyscallSucceeds());
}

TEST_F(Pwrite64, Overflow) {
  int fd;
  ASSERT_THAT(fd = open(name_.c_str(), O_APPEND | O_RDWR), SyscallSucceeds());
  constexpr int64_t kBufSize = 1024;
  std::vector<char> buf(kBufSize);
  std::fill(buf.begin(), buf.end(), 'a');
  EXPECT_THAT(PwriteFd(fd, buf.data(), buf.size(), 0x7fffffffffffffffull),
              SyscallFailsWithErrno(EINVAL));
  EXPECT_THAT(close(fd), SyscallSucceeds());
}

TEST_F(Pwrite64, Pwrite64WithOpath) {
  const TempPath file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
  const FileDescriptor fd =
      ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_PATH));

  std::vector<char> buf(1);
  EXPECT_THAT(PwriteFd(fd.get(), buf.data(), 1, 0),
              SyscallFailsWithErrno(EBADF));
}

// Test that pwrite64 with a nullptr buffer fails with EFAULT.
TEST_F(Pwrite64, NullBuffer) {
  FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(name_.c_str(), O_RDWR));

  // Use raw syscall to bypass libc's nonnull annotation.
  EXPECT_THAT(syscall(SYS_pwrite64, fd.get(), nullptr, 1, 0),
              SyscallFailsWithErrno(EFAULT));
}

// Test that pwrite64 with zero length and nullptr buffer succeeds.
TEST_F(Pwrite64, ZeroLengthNullBuffer) {
  FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(name_.c_str(), O_RDWR));
  EXPECT_THAT(pwrite64(fd.get(), nullptr, 0, 0), SyscallSucceedsWithValue(0));
}

// Test that pwrite64 to a closed fd fails with EBADF.
TEST_F(Pwrite64, ClosedFd) {
  FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(name_.c_str(), O_RDWR));
  int raw_fd = fd.get();
  fd.reset();

  char buf[16] = {};
  EXPECT_THAT(pwrite64(raw_fd, buf, sizeof(buf), 0),
              SyscallFailsWithErrno(EBADF));
}

// Test that pwrite64 to a read-only fd fails with EBADF.