summaryrefslogtreecommitdiffhomepage
path: root/test
diff options
context:
space:
mode:
authorKevin Krakauer <krakauer@google.com>2021-02-11 11:06:56 -0800
committergVisor bot <gvisor-bot@google.com>2021-02-11 11:09:22 -0800
commitae8d966f5af0bba9978a1aedac64038ef65a4cc9 (patch)
treec6540f92ac18e178dcd0189302ee94e13c12b3d6 /test
parent192780946fdf584c5e504b24f47dbd9bd411a3a6 (diff)
Assign controlling terminal when tty is opened and support NOCTTY
PiperOrigin-RevId: 357015186
Diffstat (limited to 'test')
-rw-r--r--test/syscalls/linux/BUILD1
-rw-r--r--test/syscalls/linux/pty.cc54
-rw-r--r--test/util/pty_util.cc7
-rw-r--r--test/util/pty_util.h8
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);