diff options
Diffstat (limited to 'test/syscalls/linux/mknod.cc')
-rw-r--r-- | test/syscalls/linux/mknod.cc | 72 |
1 files changed, 58 insertions, 14 deletions
diff --git a/test/syscalls/linux/mknod.cc b/test/syscalls/linux/mknod.cc index 05dfb375a..1635c6d0c 100644 --- a/test/syscalls/linux/mknod.cc +++ b/test/syscalls/linux/mknod.cc @@ -14,6 +14,7 @@ #include <errno.h> #include <fcntl.h> +#include <sys/socket.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/un.h> @@ -92,15 +93,46 @@ TEST(MknodTest, MknodOnExistingPathFails) { } TEST(MknodTest, UnimplementedTypesReturnError) { + // TODO(gvisor.dev/issue/1624): These file types are supported by some + // filesystems in VFS2, so this test should be deleted along with VFS1. + SKIP_IF(!IsRunningWithVFS1()); + const std::string path = NewTempAbsPath(); + EXPECT_THAT(mknod(path.c_str(), S_IFSOCK, 0), + SyscallFailsWithErrno(EOPNOTSUPP)); + EXPECT_THAT(mknod(path.c_str(), S_IFCHR, 0), SyscallFailsWithErrno(EPERM)); + EXPECT_THAT(mknod(path.c_str(), S_IFBLK, 0), SyscallFailsWithErrno(EPERM)); +} + +TEST(MknodTest, Socket) { + SKIP_IF(IsRunningOnGvisor() && IsRunningWithVFS1()); + + ASSERT_THAT(chdir(GetAbsoluteTestTmpdir().c_str()), SyscallSucceeds()); + + auto filename = NewTempRelPath(); + + ASSERT_THAT(mknod(filename.c_str(), S_IFSOCK | S_IRUSR | S_IWUSR, 0), + SyscallSucceeds()); + + int sk; + ASSERT_THAT(sk = socket(AF_UNIX, SOCK_SEQPACKET, 0), SyscallSucceeds()); + FileDescriptor fd(sk); - if (IsRunningWithVFS1()) { - ASSERT_THAT(mknod(path.c_str(), S_IFSOCK, 0), - SyscallFailsWithErrno(EOPNOTSUPP)); + struct sockaddr_un addr = {.sun_family = AF_UNIX}; + absl::SNPrintF(addr.sun_path, sizeof(addr.sun_path), "%s", filename.c_str()); + ASSERT_THAT(connect(sk, (struct sockaddr *)&addr, sizeof(addr)), + SyscallFailsWithErrno(ECONNREFUSED)); + ASSERT_THAT(unlink(filename.c_str()), SyscallSucceeds()); +} + +PosixErrorOr<FileDescriptor> OpenRetryEINTR(std::string const& path, int flags, + mode_t mode = 0) { + while (true) { + auto maybe_fd = Open(path, flags, mode); + if (maybe_fd.ok() || maybe_fd.error().errno_value() != EINTR) { + return maybe_fd; + } } - // These will fail on linux as well since we don't have CAP_MKNOD. - ASSERT_THAT(mknod(path.c_str(), S_IFCHR, 0), SyscallFailsWithErrno(EPERM)); - ASSERT_THAT(mknod(path.c_str(), S_IFBLK, 0), SyscallFailsWithErrno(EPERM)); } TEST(MknodTest, Fifo) { @@ -117,14 +149,16 @@ TEST(MknodTest, Fifo) { // Read-end of the pipe. ScopedThread t([&fifo, &buf, &msg]() { - FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(fifo.c_str(), O_RDONLY)); + FileDescriptor fd = + ASSERT_NO_ERRNO_AND_VALUE(OpenRetryEINTR(fifo.c_str(), O_RDONLY)); EXPECT_THAT(ReadFd(fd.get(), buf.data(), buf.size()), SyscallSucceedsWithValue(msg.length())); EXPECT_EQ(msg, std::string(buf.data())); }); // Write-end of the pipe. - FileDescriptor wfd = ASSERT_NO_ERRNO_AND_VALUE(Open(fifo.c_str(), O_WRONLY)); + FileDescriptor wfd = + ASSERT_NO_ERRNO_AND_VALUE(OpenRetryEINTR(fifo.c_str(), O_WRONLY)); EXPECT_THAT(WriteFd(wfd.get(), msg.c_str(), msg.length()), SyscallSucceedsWithValue(msg.length())); } @@ -142,15 +176,16 @@ TEST(MknodTest, FifoOtrunc) { std::vector<char> buf(512); // Read-end of the pipe. ScopedThread t([&fifo, &buf, &msg]() { - FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(fifo.c_str(), O_RDONLY)); + FileDescriptor fd = + ASSERT_NO_ERRNO_AND_VALUE(OpenRetryEINTR(fifo.c_str(), O_RDONLY)); EXPECT_THAT(ReadFd(fd.get(), buf.data(), buf.size()), SyscallSucceedsWithValue(msg.length())); EXPECT_EQ(msg, std::string(buf.data())); }); // Write-end of the pipe. - FileDescriptor wfd = - ASSERT_NO_ERRNO_AND_VALUE(Open(fifo.c_str(), O_WRONLY | O_TRUNC)); + FileDescriptor wfd = ASSERT_NO_ERRNO_AND_VALUE( + OpenRetryEINTR(fifo.c_str(), O_WRONLY | O_TRUNC)); EXPECT_THAT(WriteFd(wfd.get(), msg.c_str(), msg.length()), SyscallSucceedsWithValue(msg.length())); } @@ -170,20 +205,29 @@ TEST(MknodTest, FifoTruncNoOp) { std::vector<char> buf(512); // Read-end of the pipe. ScopedThread t([&fifo, &buf, &msg]() { - FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(fifo.c_str(), O_RDONLY)); + FileDescriptor fd = + ASSERT_NO_ERRNO_AND_VALUE(OpenRetryEINTR(fifo.c_str(), O_RDONLY)); EXPECT_THAT(ReadFd(fd.get(), buf.data(), buf.size()), SyscallSucceedsWithValue(msg.length())); EXPECT_EQ(msg, std::string(buf.data())); }); - FileDescriptor wfd = - ASSERT_NO_ERRNO_AND_VALUE(Open(fifo.c_str(), O_WRONLY | O_TRUNC)); + FileDescriptor wfd = ASSERT_NO_ERRNO_AND_VALUE( + OpenRetryEINTR(fifo.c_str(), O_WRONLY | O_TRUNC)); EXPECT_THAT(ftruncate(wfd.get(), 0), SyscallFailsWithErrno(EINVAL)); EXPECT_THAT(WriteFd(wfd.get(), msg.c_str(), msg.length()), SyscallSucceedsWithValue(msg.length())); EXPECT_THAT(ftruncate(wfd.get(), 0), SyscallFailsWithErrno(EINVAL)); } +TEST(MknodTest, MknodAtEmptyPath) { + auto dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir()); + auto fd = + ASSERT_NO_ERRNO_AND_VALUE(Open(dir.path(), O_RDONLY | O_DIRECTORY, 0666)); + EXPECT_THAT(mknodat(fd.get(), "", S_IFREG | 0777, 0), + SyscallFailsWithErrno(ENOENT)); +} + } // namespace } // namespace testing |