diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/syscalls/linux/BUILD | 1 | ||||
-rw-r--r-- | test/syscalls/linux/pty.cc | 54 | ||||
-rw-r--r-- | test/util/pty_util.cc | 7 | ||||
-rw-r--r-- | test/util/pty_util.h | 8 |
4 files changed, 68 insertions, 2 deletions
diff --git a/test/syscalls/linux/BUILD b/test/syscalls/linux/BUILD index 42fc363a2..31dc2525c 100644 --- a/test/syscalls/linux/BUILD +++ b/test/syscalls/linux/BUILD @@ -1441,6 +1441,7 @@ cc_binary( "@com_google_absl//absl/synchronization", "@com_google_absl//absl/time", gtest, + "//test/util:cleanup", "//test/util:posix_error", "//test/util:pty_util", "//test/util:test_main", diff --git a/test/syscalls/linux/pty.cc b/test/syscalls/linux/pty.cc index 85ff258df..e6b12f81c 100644 --- a/test/syscalls/linux/pty.cc +++ b/test/syscalls/linux/pty.cc @@ -36,6 +36,7 @@ #include "absl/time/clock.h" #include "absl/time/time.h" #include "test/util/capability_util.h" +#include "test/util/cleanup.h" #include "test/util/file_descriptor.h" #include "test/util/posix_error.h" #include "test/util/pty_util.h" @@ -459,6 +460,59 @@ TEST(BasicPtyTest, OpenMasterReplica) { FileDescriptor replica = ASSERT_NO_ERRNO_AND_VALUE(OpenReplica(master)); } +TEST(BasicPtyTest, OpenSetsControllingTTY) { + SKIP_IF(IsRunningWithVFS1()); + // setsid either puts us in a new session or fails because we're already the + // session leader. Either way, this ensures we're the session leader. + setsid(); + + // Make sure we're ignoring SIGHUP, which will be sent to this process once we + // disconnect they TTY. + struct sigaction sa = {}; + sa.sa_handler = SIG_IGN; + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); + struct sigaction old_sa; + ASSERT_THAT(sigaction(SIGHUP, &sa, &old_sa), SyscallSucceeds()); + auto cleanup = Cleanup([old_sa] { + EXPECT_THAT(sigaction(SIGHUP, &old_sa, NULL), SyscallSucceeds()); + }); + + FileDescriptor master = ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/ptmx", O_RDWR)); + FileDescriptor replica = + ASSERT_NO_ERRNO_AND_VALUE(OpenReplica(master, O_NONBLOCK | O_RDWR)); + + // Opening replica should make it our controlling TTY, and therefore we are + // able to give it up. + ASSERT_THAT(ioctl(replica.get(), TIOCNOTTY), SyscallSucceeds()); +} + +TEST(BasicPtyTest, OpenMasterDoesNotSetsControllingTTY) { + SKIP_IF(IsRunningWithVFS1()); + // setsid either puts us in a new session or fails because we're already the + // session leader. Either way, this ensures we're the session leader. + setsid(); + FileDescriptor master = ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/ptmx", O_RDWR)); + + // Opening master does not set the controlling TTY, and therefore we are + // unable to give it up. + ASSERT_THAT(ioctl(master.get(), TIOCNOTTY), SyscallFailsWithErrno(ENOTTY)); +} + +TEST(BasicPtyTest, OpenNOCTTY) { + SKIP_IF(IsRunningWithVFS1()); + // setsid either puts us in a new session or fails because we're already the + // session leader. Either way, this ensures we're the session leader. + setsid(); + FileDescriptor master = ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/ptmx", O_RDWR)); + FileDescriptor replica = ASSERT_NO_ERRNO_AND_VALUE( + OpenReplica(master, O_NOCTTY | O_NONBLOCK | O_RDWR)); + + // Opening replica with O_NOCTTY won't make it our controlling TTY, and + // therefore we are unable to give it up. + ASSERT_THAT(ioctl(replica.get(), TIOCNOTTY), SyscallFailsWithErrno(ENOTTY)); +} + // The replica entry in /dev/pts/ disappears when the master is closed, even if // the replica is still open. TEST(BasicPtyTest, ReplicaEntryGoneAfterMasterClose) { diff --git a/test/util/pty_util.cc b/test/util/pty_util.cc index 2cf0bea74..351f4730c 100644 --- a/test/util/pty_util.cc +++ b/test/util/pty_util.cc @@ -24,11 +24,16 @@ namespace gvisor { namespace testing { PosixErrorOr<FileDescriptor> OpenReplica(const FileDescriptor& master) { + return OpenReplica(master, O_NONBLOCK | O_RDWR | O_NOCTTY); +} + +PosixErrorOr<FileDescriptor> OpenReplica(const FileDescriptor& master, + int flags) { PosixErrorOr<int> n = ReplicaID(master); if (!n.ok()) { return PosixErrorOr<FileDescriptor>(n.error()); } - return Open(absl::StrCat("/dev/pts/", n.ValueOrDie()), O_RDWR | O_NONBLOCK); + return Open(absl::StrCat("/dev/pts/", n.ValueOrDie()), flags); } PosixErrorOr<int> ReplicaID(const FileDescriptor& master) { diff --git a/test/util/pty_util.h b/test/util/pty_util.h index ed7658868..0cca2182c 100644 --- a/test/util/pty_util.h +++ b/test/util/pty_util.h @@ -21,9 +21,15 @@ namespace gvisor { namespace testing { -// Opens the replica end of the passed master as R/W and nonblocking. +// Opens the replica end of the passed master as R/W and nonblocking. It does +// not set the replica as the controlling TTY. PosixErrorOr<FileDescriptor> OpenReplica(const FileDescriptor& master); +// Identical to the above OpenReplica, but flags are all specified by the +// caller. +PosixErrorOr<FileDescriptor> OpenReplica(const FileDescriptor& master, + int flags); + // Get the number of the replica end of the master. PosixErrorOr<int> ReplicaID(const FileDescriptor& master); |