gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/syscalls/linux/pty.cc (about)

     1  // Copyright 2018 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  #include <fcntl.h>
    16  #include <linux/capability.h>
    17  #include <linux/major.h>
    18  #include <poll.h>
    19  #include <sched.h>
    20  #include <signal.h>
    21  #include <string.h>
    22  #include <sys/ioctl.h>
    23  #include <sys/mman.h>
    24  #include <sys/poll.h>
    25  #include <sys/select.h>
    26  #include <sys/stat.h>
    27  #include <sys/sysmacros.h>
    28  #include <sys/types.h>
    29  #include <sys/wait.h>
    30  #include <termios.h>
    31  #include <unistd.h>
    32  
    33  #include <csignal>
    34  #include <iostream>
    35  #include <string>
    36  
    37  #include "gmock/gmock.h"
    38  #include "gtest/gtest.h"
    39  #include "absl/base/macros.h"
    40  #include "absl/strings/str_cat.h"
    41  #include "absl/synchronization/notification.h"
    42  #include "absl/time/clock.h"
    43  #include "absl/time/time.h"
    44  #include "test/util/cleanup.h"
    45  #include "test/util/file_descriptor.h"
    46  #include "test/util/fs_util.h"
    47  #include "test/util/linux_capability_util.h"
    48  #include "test/util/mount_util.h"
    49  #include "test/util/posix_error.h"
    50  #include "test/util/pty_util.h"
    51  #include "test/util/signal_util.h"
    52  #include "test/util/temp_path.h"
    53  #include "test/util/test_util.h"
    54  #include "test/util/thread_util.h"
    55  
    56  namespace gvisor {
    57  namespace testing {
    58  
    59  namespace {
    60  
    61  using ::testing::AnyOf;
    62  using ::testing::Contains;
    63  using ::testing::Eq;
    64  using ::testing::Not;
    65  using SubprocessCallback = std::function<void()>;
    66  
    67  // Tests Unix98 pseudoterminals.
    68  //
    69  // These tests assume that /dev/ptmx exists and is associated with a devpts
    70  // filesystem mounted at /dev/pts/. While a Linux distribution could
    71  // theoretically place those anywhere, glibc expects those locations, so they
    72  // are effectively fixed.
    73  
    74  // Minor device number for an unopened ptmx file.
    75  constexpr int kPtmxMinor = 2;
    76  
    77  // The timeout when polling for data from a pty. When data is written to one end
    78  // of a pty, Linux asynchronously makes it available to the other end, so we
    79  // have to wait.
    80  constexpr absl::Duration kTimeout = absl::Seconds(20);
    81  
    82  // Similar to kTimeout, but shorter: This timeout is used for tests where
    83  // the expected behavior is to observe a timeout, which helps speed up tests.
    84  constexpr absl::Duration kTimeoutShort = absl::Seconds(2);
    85  
    86  // The maximum line size in bytes returned per read from a pty file.
    87  constexpr int kMaxLineSize = 4096;
    88  
    89  constexpr char kMasterPath[] = "/dev/ptmx";
    90  
    91  // glibc defines its own, different, version of struct termios. We care about
    92  // what the kernel does, not glibc.
    93  #define KERNEL_NCCS 19
    94  struct kernel_termios {
    95    tcflag_t c_iflag;
    96    tcflag_t c_oflag;
    97    tcflag_t c_cflag;
    98    tcflag_t c_lflag;
    99    cc_t c_line;
   100    cc_t c_cc[KERNEL_NCCS];
   101  };
   102  
   103  bool operator==(struct kernel_termios const &a,
   104                  struct kernel_termios const &b) {
   105    return memcmp(&a, &b, sizeof(a)) == 0;
   106  }
   107  
   108  // Returns the termios-style control character for the passed character.
   109  //
   110  // e.g., for Ctrl-C, i.e., ^C, call ControlCharacter('C').
   111  //
   112  // Standard control characters are ASCII bytes 0 through 31.
   113  constexpr char ControlCharacter(char c) {
   114    // A is 1, B is 2, etc.
   115    return c - 'A' + 1;
   116  }
   117  
   118  // Returns the printable character the given control character represents.
   119  constexpr char FromControlCharacter(char c) { return c + 'A' - 1; }
   120  
   121  // Returns true if c is a control character.
   122  //
   123  // Standard control characters are ASCII bytes 0 through 31.
   124  constexpr bool IsControlCharacter(char c) { return c <= 31; }
   125  
   126  struct Field {
   127    const char *name;
   128    uint64_t mask;
   129    uint64_t value;
   130  };
   131  
   132  // ParseFields returns a string representation of value, using the names in
   133  // fields.
   134  std::string ParseFields(const Field *fields, size_t len, uint64_t value) {
   135    bool first = true;
   136    std::string s;
   137    for (size_t i = 0; i < len; i++) {
   138      const Field f = fields[i];
   139      if ((value & f.mask) == f.value) {
   140        if (!first) {
   141          s += "|";
   142        }
   143        s += f.name;
   144        first = false;
   145        value &= ~f.mask;
   146      }
   147    }
   148  
   149    if (value) {
   150      if (!first) {
   151        s += "|";
   152      }
   153      absl::StrAppend(&s, value);
   154    }
   155  
   156    return s;
   157  }
   158  
   159  const Field kIflagFields[] = {
   160      {"IGNBRK", IGNBRK, IGNBRK}, {"BRKINT", BRKINT, BRKINT},
   161      {"IGNPAR", IGNPAR, IGNPAR}, {"PARMRK", PARMRK, PARMRK},
   162      {"INPCK", INPCK, INPCK},    {"ISTRIP", ISTRIP, ISTRIP},
   163      {"INLCR", INLCR, INLCR},    {"IGNCR", IGNCR, IGNCR},
   164      {"ICRNL", ICRNL, ICRNL},    {"IUCLC", IUCLC, IUCLC},
   165      {"IXON", IXON, IXON},       {"IXANY", IXANY, IXANY},
   166      {"IXOFF", IXOFF, IXOFF},    {"IMAXBEL", IMAXBEL, IMAXBEL},
   167      {"IUTF8", IUTF8, IUTF8},
   168  };
   169  
   170  const Field kOflagFields[] = {
   171      {"OPOST", OPOST, OPOST}, {"OLCUC", OLCUC, OLCUC},
   172      {"ONLCR", ONLCR, ONLCR}, {"OCRNL", OCRNL, OCRNL},
   173      {"ONOCR", ONOCR, ONOCR}, {"ONLRET", ONLRET, ONLRET},
   174      {"OFILL", OFILL, OFILL}, {"OFDEL", OFDEL, OFDEL},
   175      {"NL0", NLDLY, NL0},     {"NL1", NLDLY, NL1},
   176      {"CR0", CRDLY, CR0},     {"CR1", CRDLY, CR1},
   177      {"CR2", CRDLY, CR2},     {"CR3", CRDLY, CR3},
   178      {"TAB0", TABDLY, TAB0},  {"TAB1", TABDLY, TAB1},
   179      {"TAB2", TABDLY, TAB2},  {"TAB3", TABDLY, TAB3},
   180      {"BS0", BSDLY, BS0},     {"BS1", BSDLY, BS1},
   181      {"FF0", FFDLY, FF0},     {"FF1", FFDLY, FF1},
   182      {"VT0", VTDLY, VT0},     {"VT1", VTDLY, VT1},
   183      {"XTABS", XTABS, XTABS},
   184  };
   185  
   186  #ifndef IBSHIFT
   187  // Shift from CBAUD to CIBAUD.
   188  #define IBSHIFT 16
   189  #endif
   190  
   191  const Field kCflagFields[] = {
   192      {"B0", CBAUD, B0},
   193      {"B50", CBAUD, B50},
   194      {"B75", CBAUD, B75},
   195      {"B110", CBAUD, B110},
   196      {"B134", CBAUD, B134},
   197      {"B150", CBAUD, B150},
   198      {"B200", CBAUD, B200},
   199      {"B300", CBAUD, B300},
   200      {"B600", CBAUD, B600},
   201      {"B1200", CBAUD, B1200},
   202      {"B1800", CBAUD, B1800},
   203      {"B2400", CBAUD, B2400},
   204      {"B4800", CBAUD, B4800},
   205      {"B9600", CBAUD, B9600},
   206      {"B19200", CBAUD, B19200},
   207      {"B38400", CBAUD, B38400},
   208      {"CS5", CSIZE, CS5},
   209      {"CS6", CSIZE, CS6},
   210      {"CS7", CSIZE, CS7},
   211      {"CS8", CSIZE, CS8},
   212      {"CSTOPB", CSTOPB, CSTOPB},
   213      {"CREAD", CREAD, CREAD},
   214      {"PARENB", PARENB, PARENB},
   215      {"PARODD", PARODD, PARODD},
   216      {"HUPCL", HUPCL, HUPCL},
   217      {"CLOCAL", CLOCAL, CLOCAL},
   218      {"B57600", CBAUD, B57600},
   219      {"B115200", CBAUD, B115200},
   220      {"B230400", CBAUD, B230400},
   221      {"B460800", CBAUD, B460800},
   222      {"B500000", CBAUD, B500000},
   223      {"B576000", CBAUD, B576000},
   224      {"B921600", CBAUD, B921600},
   225      {"B1000000", CBAUD, B1000000},
   226      {"B1152000", CBAUD, B1152000},
   227      {"B1500000", CBAUD, B1500000},
   228      {"B2000000", CBAUD, B2000000},
   229      {"B2500000", CBAUD, B2500000},
   230      {"B3000000", CBAUD, B3000000},
   231      {"B3500000", CBAUD, B3500000},
   232      {"B4000000", CBAUD, B4000000},
   233      {"CMSPAR", CMSPAR, CMSPAR},
   234      {"CRTSCTS", CRTSCTS, CRTSCTS},
   235      {"IB0", CIBAUD, B0 << IBSHIFT},
   236      {"IB50", CIBAUD, B50 << IBSHIFT},
   237      {"IB75", CIBAUD, B75 << IBSHIFT},
   238      {"IB110", CIBAUD, B110 << IBSHIFT},
   239      {"IB134", CIBAUD, B134 << IBSHIFT},
   240      {"IB150", CIBAUD, B150 << IBSHIFT},
   241      {"IB200", CIBAUD, B200 << IBSHIFT},
   242      {"IB300", CIBAUD, B300 << IBSHIFT},
   243      {"IB600", CIBAUD, B600 << IBSHIFT},
   244      {"IB1200", CIBAUD, B1200 << IBSHIFT},
   245      {"IB1800", CIBAUD, B1800 << IBSHIFT},
   246      {"IB2400", CIBAUD, B2400 << IBSHIFT},
   247      {"IB4800", CIBAUD, B4800 << IBSHIFT},
   248      {"IB9600", CIBAUD, B9600 << IBSHIFT},
   249      {"IB19200", CIBAUD, B19200 << IBSHIFT},
   250      {"IB38400", CIBAUD, B38400 << IBSHIFT},
   251      {"IB57600", CIBAUD, B57600 << IBSHIFT},
   252      {"IB115200", CIBAUD, B115200 << IBSHIFT},
   253      {"IB230400", CIBAUD, B230400 << IBSHIFT},
   254      {"IB460800", CIBAUD, B460800 << IBSHIFT},
   255      {"IB500000", CIBAUD, B500000 << IBSHIFT},
   256      {"IB576000", CIBAUD, B576000 << IBSHIFT},
   257      {"IB921600", CIBAUD, B921600 << IBSHIFT},
   258      {"IB1000000", CIBAUD, B1000000 << IBSHIFT},
   259      {"IB1152000", CIBAUD, B1152000 << IBSHIFT},
   260      {"IB1500000", CIBAUD, B1500000 << IBSHIFT},
   261      {"IB2000000", CIBAUD, B2000000 << IBSHIFT},
   262      {"IB2500000", CIBAUD, B2500000 << IBSHIFT},
   263      {"IB3000000", CIBAUD, B3000000 << IBSHIFT},
   264      {"IB3500000", CIBAUD, B3500000 << IBSHIFT},
   265      {"IB4000000", CIBAUD, B4000000 << IBSHIFT},
   266  };
   267  
   268  const Field kLflagFields[] = {
   269      {"ISIG", ISIG, ISIG},          {"ICANON", ICANON, ICANON},
   270      {"XCASE", XCASE, XCASE},       {"ECHO", ECHO, ECHO},
   271      {"ECHOE", ECHOE, ECHOE},       {"ECHOK", ECHOK, ECHOK},
   272      {"ECHONL", ECHONL, ECHONL},    {"NOFLSH", NOFLSH, NOFLSH},
   273      {"TOSTOP", TOSTOP, TOSTOP},    {"ECHOCTL", ECHOCTL, ECHOCTL},
   274      {"ECHOPRT", ECHOPRT, ECHOPRT}, {"ECHOKE", ECHOKE, ECHOKE},
   275      {"FLUSHO", FLUSHO, FLUSHO},    {"PENDIN", PENDIN, PENDIN},
   276      {"IEXTEN", IEXTEN, IEXTEN},    {"EXTPROC", EXTPROC, EXTPROC},
   277  };
   278  
   279  std::string FormatCC(char c) {
   280    if (isgraph(c)) {
   281      return std::string(1, c);
   282    } else if (c == ' ') {
   283      return " ";
   284    } else if (c == '\t') {
   285      return "\\t";
   286    } else if (c == '\r') {
   287      return "\\r";
   288    } else if (c == '\n') {
   289      return "\\n";
   290    } else if (c == '\0') {
   291      return "\\0";
   292    } else if (IsControlCharacter(c)) {
   293      return absl::StrCat("^", std::string(1, FromControlCharacter(c)));
   294    }
   295    return absl::StrCat("\\x", absl::Hex(c));
   296  }
   297  
   298  std::ostream &operator<<(std::ostream &os, struct kernel_termios const &a) {
   299    os << "{ c_iflag = "
   300       << ParseFields(kIflagFields, ABSL_ARRAYSIZE(kIflagFields), a.c_iflag);
   301    os << ", c_oflag = "
   302       << ParseFields(kOflagFields, ABSL_ARRAYSIZE(kOflagFields), a.c_oflag);
   303    os << ", c_cflag = "
   304       << ParseFields(kCflagFields, ABSL_ARRAYSIZE(kCflagFields), a.c_cflag);
   305    os << ", c_lflag = "
   306       << ParseFields(kLflagFields, ABSL_ARRAYSIZE(kLflagFields), a.c_lflag);
   307    os << ", c_line = " << a.c_line;
   308    os << ", c_cc = { [VINTR] = '" << FormatCC(a.c_cc[VINTR]);
   309    os << "', [VQUIT] = '" << FormatCC(a.c_cc[VQUIT]);
   310    os << "', [VERASE] = '" << FormatCC(a.c_cc[VERASE]);
   311    os << "', [VKILL] = '" << FormatCC(a.c_cc[VKILL]);
   312    os << "', [VEOF] = '" << FormatCC(a.c_cc[VEOF]);
   313    os << "', [VTIME] = '" << static_cast<int>(a.c_cc[VTIME]);
   314    os << "', [VMIN] = " << static_cast<int>(a.c_cc[VMIN]);
   315    os << ", [VSWTC] = '" << FormatCC(a.c_cc[VSWTC]);
   316    os << "', [VSTART] = '" << FormatCC(a.c_cc[VSTART]);
   317    os << "', [VSTOP] = '" << FormatCC(a.c_cc[VSTOP]);
   318    os << "', [VSUSP] = '" << FormatCC(a.c_cc[VSUSP]);
   319    os << "', [VEOL] = '" << FormatCC(a.c_cc[VEOL]);
   320    os << "', [VREPRINT] = '" << FormatCC(a.c_cc[VREPRINT]);
   321    os << "', [VDISCARD] = '" << FormatCC(a.c_cc[VDISCARD]);
   322    os << "', [VWERASE] = '" << FormatCC(a.c_cc[VWERASE]);
   323    os << "', [VLNEXT] = '" << FormatCC(a.c_cc[VLNEXT]);
   324    os << "', [VEOL2] = '" << FormatCC(a.c_cc[VEOL2]);
   325    os << "'}";
   326    return os;
   327  }
   328  
   329  // Return the default termios settings for a new terminal.
   330  struct kernel_termios DefaultTermios() {
   331    struct kernel_termios t = {};
   332    t.c_iflag = IXON | ICRNL;
   333    t.c_oflag = OPOST | ONLCR;
   334    t.c_cflag = B38400 | CSIZE | CS8 | CREAD;
   335    t.c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN;
   336    t.c_line = 0;
   337    t.c_cc[VINTR] = ControlCharacter('C');
   338    t.c_cc[VQUIT] = ControlCharacter('\\');
   339    t.c_cc[VERASE] = '\x7f';
   340    t.c_cc[VKILL] = ControlCharacter('U');
   341    t.c_cc[VEOF] = ControlCharacter('D');
   342    t.c_cc[VTIME] = '\0';
   343    t.c_cc[VMIN] = 1;
   344    t.c_cc[VSWTC] = '\0';
   345    t.c_cc[VSTART] = ControlCharacter('Q');
   346    t.c_cc[VSTOP] = ControlCharacter('S');
   347    t.c_cc[VSUSP] = ControlCharacter('Z');
   348    t.c_cc[VEOL] = '\0';
   349    t.c_cc[VREPRINT] = ControlCharacter('R');
   350    t.c_cc[VDISCARD] = ControlCharacter('O');
   351    t.c_cc[VWERASE] = ControlCharacter('W');
   352    t.c_cc[VLNEXT] = ControlCharacter('V');
   353    t.c_cc[VEOL2] = '\0';
   354    return t;
   355  }
   356  
   357  // PollAndReadFd tries to read count bytes from buf within timeout.
   358  //
   359  // Returns a partial read if some bytes were read.
   360  //
   361  // fd must be non-blocking.
   362  PosixErrorOr<size_t> PollAndReadFd(int fd, void *buf, size_t count,
   363                                     absl::Duration timeout) {
   364    absl::Time end = absl::Now() + timeout;
   365  
   366    size_t completed = 0;
   367    absl::Duration remaining;
   368    while ((remaining = end - absl::Now()) > absl::ZeroDuration()) {
   369      struct pollfd pfd = {fd, POLLIN, 0};
   370      int ret = RetryEINTR(poll)(&pfd, 1, absl::ToInt64Milliseconds(remaining));
   371      if (ret < 0) {
   372        return PosixError(errno, "poll failed");
   373      } else if (ret == 0) {
   374        // Timed out.
   375        continue;
   376      } else if (ret != 1) {
   377        return PosixError(EINVAL, absl::StrCat("Bad poll ret ", ret));
   378      }
   379  
   380      ssize_t n =
   381          ReadFd(fd, static_cast<char *>(buf) + completed, count - completed);
   382      if (n < 0) {
   383        if (errno == EAGAIN) {
   384          // Linux sometimes returns EAGAIN from this read, despite the fact that
   385          // poll returned success. Let's just do what do as we are told and try
   386          // again.
   387          continue;
   388        }
   389        return PosixError(errno, "read failed");
   390      } else if (n > 0 && (pfd.revents & POLLIN) == 0) {
   391        return PosixError(EINVAL, "Poll said not readable but data was read");
   392      }
   393      completed += n;
   394      if (completed >= count) {
   395        return completed;
   396      }
   397    }
   398  
   399    if (completed) {
   400      return completed;
   401    }
   402    return PosixError(ETIMEDOUT, "Poll timed out");
   403  }
   404  
   405  TEST(PtyTrunc, Truncate) {
   406    // setsid either puts us in a new session or fails because we're already the
   407    // session leader. Either way, this ensures we're the session leader and have
   408    // no controlling terminal.
   409    ASSERT_THAT(setsid(), AnyOf(SyscallSucceeds(), SyscallFailsWithErrno(EPERM)));
   410  
   411    // Make sure we're ignoring SIGHUP, which will be sent to this process once we
   412    // disconnect the TTY.
   413    struct sigaction sa = {};
   414    sa.sa_handler = SIG_IGN;
   415    sa.sa_flags = 0;
   416    sigemptyset(&sa.sa_mask);
   417    const Cleanup cleanup =
   418        ASSERT_NO_ERRNO_AND_VALUE(ScopedSigaction(SIGHUP, sa));
   419  
   420    // Opening PTYs with O_TRUNC shouldn't cause an error, but calls to
   421    // (f)truncate should.
   422    FileDescriptor master =
   423        ASSERT_NO_ERRNO_AND_VALUE(Open(kMasterPath, O_RDWR | O_TRUNC));
   424    int n = ASSERT_NO_ERRNO_AND_VALUE(ReplicaID(master));
   425    std::string spath = absl::StrCat("/dev/pts/", n);
   426    FileDescriptor replica =
   427        ASSERT_NO_ERRNO_AND_VALUE(Open(spath, O_RDWR | O_NONBLOCK | O_TRUNC));
   428    ASSERT_THAT(ioctl(replica.get(), TIOCNOTTY), SyscallSucceeds());
   429  
   430    EXPECT_THAT(truncate(kMasterPath, 0), SyscallFailsWithErrno(EINVAL));
   431    EXPECT_THAT(truncate(spath.c_str(), 0), SyscallFailsWithErrno(EINVAL));
   432    EXPECT_THAT(ftruncate(master.get(), 0), SyscallFailsWithErrno(EINVAL));
   433    EXPECT_THAT(ftruncate(replica.get(), 0), SyscallFailsWithErrno(EINVAL));
   434  }
   435  
   436  TEST(BasicPtyTest, StatUnopenedMaster) {
   437    struct stat s;
   438    ASSERT_THAT(stat(kMasterPath, &s), SyscallSucceeds());
   439  
   440    EXPECT_EQ(s.st_rdev, makedev(TTYAUX_MAJOR, kPtmxMinor));
   441    EXPECT_EQ(s.st_size, 0);
   442    EXPECT_EQ(s.st_blocks, 0);
   443  
   444    // ptmx attached to a specific devpts mount uses block size 1024. See
   445    // fs/devpts/inode.c:devpts_fill_super.
   446    //
   447    // The global ptmx device uses the block size of the filesystem it is created
   448    // on (which is usually 4096 for disk filesystems).
   449    EXPECT_THAT(s.st_blksize, AnyOf(Eq(1024), Eq(4096)));
   450  }
   451  
   452  // Waits for count bytes to be readable from fd. Unlike poll, which can return
   453  // before all data is moved into a pty's read buffer, this function waits for
   454  // all count bytes to become readable.
   455  PosixErrorOr<int> WaitUntilReceived(int fd, int count) {
   456    int buffered = -1;
   457    absl::Duration remaining;
   458    absl::Time end = absl::Now() + kTimeout;
   459    while ((remaining = end - absl::Now()) > absl::ZeroDuration()) {
   460      if (ioctl(fd, FIONREAD, &buffered) < 0) {
   461        return PosixError(errno, "failed FIONREAD ioctl");
   462      }
   463      if (buffered >= count) {
   464        return buffered;
   465      }
   466      absl::SleepFor(absl::Milliseconds(500));
   467    }
   468    return PosixError(
   469        ETIMEDOUT,
   470        absl::StrFormat(
   471            "FIONREAD timed out, receiving only %d of %d expected bytes",
   472            buffered, count));
   473  }
   474  
   475  // Verifies that there is nothing left to read from fd.
   476  void ExpectFinished(const FileDescriptor &fd) {
   477    // Nothing more to read.
   478    char c;
   479    EXPECT_THAT(ReadFd(fd.get(), &c, 1), SyscallFailsWithErrno(EAGAIN));
   480  }
   481  
   482  // Verifies that we can read expected bytes from fd into buf.
   483  void ExpectReadable(const FileDescriptor &fd, int expected, char *buf) {
   484    size_t n = ASSERT_NO_ERRNO_AND_VALUE(
   485        PollAndReadFd(fd.get(), buf, expected, kTimeout));
   486    EXPECT_EQ(expected, n);
   487  }
   488  
   489  TEST(BasicPtyTest, OpenMasterReplica) {
   490    FileDescriptor master = ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/ptmx", O_RDWR));
   491    FileDescriptor replica = ASSERT_NO_ERRNO_AND_VALUE(OpenReplica(master));
   492  }
   493  
   494  TEST(BasicPtyTest, OpenSetsControllingTTY) {
   495    // setsid either puts us in a new session or fails because we're already the
   496    // session leader. Either way, this ensures we're the session leader.
   497    ASSERT_THAT(setsid(), AnyOf(SyscallSucceeds(), SyscallFailsWithErrno(EPERM)));
   498  
   499    // Make sure we're ignoring SIGHUP, which will be sent to this process once we
   500    // disconnect the TTY.
   501    struct sigaction sa = {};
   502    sa.sa_handler = SIG_IGN;
   503    sa.sa_flags = 0;
   504    sigemptyset(&sa.sa_mask);
   505    struct sigaction old_sa;
   506    ASSERT_THAT(sigaction(SIGHUP, &sa, &old_sa), SyscallSucceeds());
   507    auto cleanup = Cleanup([old_sa] {
   508      EXPECT_THAT(sigaction(SIGHUP, &old_sa, NULL), SyscallSucceeds());
   509    });
   510  
   511    FileDescriptor master = ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/ptmx", O_RDWR));
   512    FileDescriptor replica =
   513        ASSERT_NO_ERRNO_AND_VALUE(OpenReplica(master, O_NONBLOCK | O_RDWR));
   514  
   515    // Opening replica should make it our controlling TTY, and therefore we are
   516    // able to give it up.
   517    ASSERT_THAT(ioctl(replica.get(), TIOCNOTTY), SyscallSucceeds());
   518  }
   519  
   520  TEST(BasicPtyTest, OpenMasterDoesNotSetsControllingTTY) {
   521    // setsid either puts us in a new session or fails because we're already the
   522    // session leader. Either way, this ensures we're the session leader.
   523    ASSERT_THAT(setsid(), AnyOf(SyscallSucceeds(), SyscallFailsWithErrno(EPERM)));
   524    FileDescriptor master = ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/ptmx", O_RDWR));
   525  
   526    // Opening master does not set the controlling TTY, and therefore we are
   527    // unable to give it up.
   528    ASSERT_THAT(ioctl(master.get(), TIOCNOTTY), SyscallFailsWithErrno(ENOTTY));
   529  }
   530  
   531  TEST(BasicPtyTest, OpenNOCTTY) {
   532    // setsid either puts us in a new session or fails because we're already the
   533    // session leader. Either way, this ensures we're the session leader.
   534    ASSERT_THAT(setsid(), AnyOf(SyscallSucceeds(), SyscallFailsWithErrno(EPERM)));
   535    FileDescriptor master = ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/ptmx", O_RDWR));
   536    FileDescriptor replica = ASSERT_NO_ERRNO_AND_VALUE(
   537        OpenReplica(master, O_NOCTTY | O_NONBLOCK | O_RDWR));
   538  
   539    // Opening replica with O_NOCTTY won't make it our controlling TTY, and
   540    // therefore we are unable to give it up.
   541    ASSERT_THAT(ioctl(replica.get(), TIOCNOTTY), SyscallFailsWithErrno(ENOTTY));
   542  }
   543  
   544  // The replica entry in /dev/pts/ disappears when the master is closed, even if
   545  // the replica is still open.
   546  TEST(BasicPtyTest, ReplicaEntryGoneAfterMasterClose) {
   547    FileDescriptor master = ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/ptmx", O_RDWR));
   548    FileDescriptor replica = ASSERT_NO_ERRNO_AND_VALUE(OpenReplica(master));
   549  
   550    // Get pty index.
   551    int index = -1;
   552    ASSERT_THAT(ioctl(master.get(), TIOCGPTN, &index), SyscallSucceeds());
   553  
   554    std::string path = absl::StrCat("/dev/pts/", index);
   555  
   556    struct stat st;
   557    EXPECT_THAT(stat(path.c_str(), &st), SyscallSucceeds());
   558  
   559    master.reset();
   560  
   561    EXPECT_THAT(stat(path.c_str(), &st), SyscallFailsWithErrno(ENOENT));
   562  }
   563  
   564  TEST(BasicPtyTest, Getdents) {
   565    FileDescriptor master1 = ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/ptmx", O_RDWR));
   566    int index1 = -1;
   567    ASSERT_THAT(ioctl(master1.get(), TIOCGPTN, &index1), SyscallSucceeds());
   568    FileDescriptor replica1 = ASSERT_NO_ERRNO_AND_VALUE(OpenReplica(master1));
   569  
   570    FileDescriptor master2 = ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/ptmx", O_RDWR));
   571    int index2 = -1;
   572    ASSERT_THAT(ioctl(master2.get(), TIOCGPTN, &index2), SyscallSucceeds());
   573    FileDescriptor replica2 = ASSERT_NO_ERRNO_AND_VALUE(OpenReplica(master2));
   574  
   575    // The directory contains ptmx, index1, and index2. (Plus any additional PTYs
   576    // unrelated to this test.)
   577  
   578    std::vector<std::string> contents =
   579        ASSERT_NO_ERRNO_AND_VALUE(ListDir("/dev/pts/", true));
   580    EXPECT_THAT(contents, Contains(absl::StrCat(index1)));
   581    EXPECT_THAT(contents, Contains(absl::StrCat(index2)));
   582  
   583    master2.reset();
   584  
   585    // The directory contains ptmx and index1, but not index2 since the master is
   586    // closed. (Plus any additional PTYs unrelated to this test.)
   587  
   588    contents = ASSERT_NO_ERRNO_AND_VALUE(ListDir("/dev/pts/", true));
   589    EXPECT_THAT(contents, Contains(absl::StrCat(index1)));
   590    EXPECT_THAT(contents, Not(Contains(absl::StrCat(index2))));
   591  
   592    // N.B. devpts supports legacy "single-instance" mode and new "multi-instance"
   593    // mode. In legacy mode, devpts does not contain a "ptmx" device (the distro
   594    // must use mknod to create it somewhere, presumably /dev/ptmx).
   595    // Multi-instance mode does include a "ptmx" device tied to that mount.
   596    //
   597    // We don't check for the presence or absence of "ptmx", as distros vary in
   598    // their usage of the two modes.
   599  }
   600  
   601  TEST(BasicPtyTest, NewInstance) {
   602    SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_SYS_ADMIN)));
   603  
   604    auto const dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
   605    auto const mount = ASSERT_NO_ERRNO_AND_VALUE(
   606        Mount("devpts_test", dir.path(), "devpts", 0, "newinstance", 0));
   607    auto const dir2 = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
   608    auto const mount2 = ASSERT_NO_ERRNO_AND_VALUE(
   609        Mount("devpts_test2", dir.path(), "devpts", 0, "newinstance", 0));
   610  
   611    // Opening PTYs with O_TRUNC shouldn't cause an error, but calls to
   612    // (f)truncate should.
   613    FileDescriptor master = ASSERT_NO_ERRNO_AND_VALUE(
   614        Open(JoinPath(dir.path(), "ptmx"), O_RDWR | O_TRUNC));
   615    int n = ASSERT_NO_ERRNO_AND_VALUE(ReplicaID(master));
   616    std::string spath2 = absl::StrCat(dir2.path(), "/", n);
   617    ASSERT_THAT(open(spath2.c_str(), O_RDWR), SyscallFailsWithErrno(ENOENT));
   618    std::string spath = absl::StrCat(dir.path(), "/", n);
   619    FileDescriptor replica =
   620        ASSERT_NO_ERRNO_AND_VALUE(Open(spath.c_str(), O_RDWR | O_NOCTTY));
   621  }
   622  
   623  TEST(BasicPtyTest, SetMode) {
   624    SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_SYS_ADMIN)));
   625  
   626    auto const dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
   627    auto mount = ASSERT_NO_ERRNO_AND_VALUE(
   628        Mount("devpts_test", dir.path(), "devpts", 0,
   629              "newinstance,mode=0600,ptmxmode=0620", 0));
   630    FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(
   631        Open(JoinPath(dir.path()), O_RDONLY | O_DIRECTORY));
   632    mount.Release();
   633  
   634    struct stat st;
   635    ASSERT_THAT(fstat(fd.get(), &st), SyscallSucceeds());
   636    EXPECT_EQ(st.st_mode, 0600 | S_IFDIR);
   637    ASSERT_THAT(fstatat(fd.get(), "ptmx", &st, 0), SyscallSucceeds());
   638    EXPECT_EQ(st.st_mode, 0620 | S_IFCHR);
   639  }
   640  
   641  class PtyTest : public ::testing::Test {
   642   protected:
   643    void SetUp() override {
   644      master_ = ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/ptmx", O_RDWR | O_NONBLOCK));
   645      replica_ = ASSERT_NO_ERRNO_AND_VALUE(OpenReplica(master_));
   646    }
   647  
   648    void DisableCanonical() {
   649      struct kernel_termios t = {};
   650      EXPECT_THAT(ioctl(replica_.get(), TCGETS, &t), SyscallSucceeds());
   651      t.c_lflag &= ~ICANON;
   652      EXPECT_THAT(ioctl(replica_.get(), TCSETS, &t), SyscallSucceeds());
   653    }
   654  
   655    void EnableCanonical() {
   656      struct kernel_termios t = {};
   657      EXPECT_THAT(ioctl(replica_.get(), TCGETS, &t), SyscallSucceeds());
   658      t.c_lflag |= ICANON;
   659      EXPECT_THAT(ioctl(replica_.get(), TCSETS, &t), SyscallSucceeds());
   660    }
   661  
   662    // Writes master_input to the master file descriptor and verifies that
   663    // the replica and the echo output match what is expected.
   664    void TestCanonicalIO(const char *master_input,
   665                         const char *expected_replica_output,
   666                         const char *expected_echo_output) {
   667      ASSERT_THAT(WriteFd(master_.get(), master_input, strlen(master_input)),
   668                  SyscallSucceedsWithValue(strlen(master_input)));
   669  
   670      std::string buf(strlen(expected_replica_output), '\0');
   671      ASSERT_NO_ERRNO(
   672          WaitUntilReceived(replica_.get(), strlen(expected_replica_output)));
   673      ExpectReadable(replica_, strlen(expected_replica_output), &buf[0]);
   674      EXPECT_STREQ(buf.c_str(), expected_replica_output);
   675  
   676      std::string echo_buf(strlen(expected_echo_output), '\0');
   677      ExpectReadable(master_, strlen(expected_echo_output), &echo_buf[0]);
   678      EXPECT_STREQ(echo_buf.c_str(), expected_echo_output);
   679  
   680      ExpectFinished(master_);
   681      ExpectFinished(replica_);
   682    }
   683  
   684    // Master and replica ends of the PTY. Non-blocking.
   685    FileDescriptor master_;
   686    FileDescriptor replica_;
   687  };
   688  
   689  // NOTE(gvisor.dev/issue/9951): Regression test.
   690  TEST_F(PtyTest, ReplicaCloseNotify) {
   691    // Open a second replica.
   692    FileDescriptor replica2_ = ASSERT_NO_ERRNO_AND_VALUE(OpenReplica(master_));
   693    fd_set read_set;
   694    FD_ZERO(&read_set);
   695    FD_SET(master_.get(), &read_set);
   696    int max_fd = master_.get() + 1;
   697  
   698    // Set timeout to 0.2 seconds.
   699    struct timeval tv;
   700    tv.tv_sec = 0;
   701    tv.tv_usec = 200000;
   702  
   703    // Ensure that there are no readable events.
   704    FD_ZERO(&read_set);
   705    FD_SET(master_.get(), &read_set);
   706    EXPECT_THAT(select(max_fd, &read_set, NULL, NULL, &tv),
   707                SyscallSucceedsWithValue(0));
   708  
   709    // Close the second replica and no readable event should occur.
   710    replica2_.reset();
   711    FD_ZERO(&read_set);
   712    FD_SET(master_.get(), &read_set);
   713    EXPECT_THAT(select(max_fd, &read_set, NULL, NULL, &tv),
   714                SyscallSucceedsWithValue(0));
   715  
   716    // Close the last remaining replica and a readable event should occur.
   717    replica_.reset();
   718    FD_ZERO(&read_set);
   719    FD_SET(master_.get(), &read_set);
   720    EXPECT_THAT(select(max_fd, &read_set, NULL, NULL, &tv),
   721                SyscallSucceedsWithValue(1));
   722    EXPECT_TRUE(FD_ISSET(master_.get(), &read_set));
   723  
   724    // Check that the right events are occurring.
   725    struct pollfd pfd;
   726    pfd.fd = master_.get();
   727    pfd.events = POLLIN | POLLOUT | POLLRDHUP | POLLRDNORM | POLLWRNORM;
   728    EXPECT_THAT(poll(&pfd, 1, 1), SyscallSucceedsWithValue(1));
   729    EXPECT_EQ(POLLHUP | POLLOUT | POLLWRNORM, pfd.revents);
   730  }
   731  
   732  // Master to replica sanity test.
   733  TEST_F(PtyTest, WriteMasterToReplica) {
   734    // N.B. by default, the replica reads nothing until the master writes a
   735    // newline.
   736    constexpr char kBuf[] = "hello\n";
   737  
   738    EXPECT_THAT(WriteFd(master_.get(), kBuf, sizeof(kBuf) - 1),
   739                SyscallSucceedsWithValue(sizeof(kBuf) - 1));
   740  
   741    // Linux moves data from the master to the replica via async work scheduled
   742    // via tty_flip_buffer_push. Since it is asynchronous, the data may not be
   743    // available for reading immediately. Instead we must poll and assert that it
   744    // becomes available "soon".
   745  
   746    char buf[sizeof(kBuf)] = {};
   747    ExpectReadable(replica_, sizeof(buf) - 1, buf);
   748  
   749    EXPECT_EQ(memcmp(buf, kBuf, sizeof(kBuf)), 0);
   750  }
   751  
   752  // Replica to master sanity test.
   753  TEST_F(PtyTest, WriteReplicaToMaster) {
   754    // N.B. by default, the master reads nothing until the replica writes a
   755    // newline, and the master gets a carriage return.
   756    constexpr char kInput[] = "hello\n";
   757    constexpr char kExpected[] = "hello\r\n";
   758  
   759    EXPECT_THAT(WriteFd(replica_.get(), kInput, sizeof(kInput) - 1),
   760                SyscallSucceedsWithValue(sizeof(kInput) - 1));
   761  
   762    // Linux moves data from the master to the replica via async work scheduled
   763    // via tty_flip_buffer_push. Since it is asynchronous, the data may not be
   764    // available for reading immediately. Instead we must poll and assert that it
   765    // becomes available "soon".
   766  
   767    char buf[sizeof(kExpected)] = {};
   768    ExpectReadable(master_, sizeof(buf) - 1, buf);
   769  
   770    EXPECT_EQ(memcmp(buf, kExpected, sizeof(kExpected)), 0);
   771  }
   772  
   773  // Verifies that data enqueued into the replica is still readable by the master
   774  // after the replica is closed.
   775  TEST_F(PtyTest, WriteReplicaToMasterReadAfterReplicaClosed) {
   776    // N.B. by default, the master reads nothing until the replica writes a
   777    // newline, and the master gets a carriage return.
   778    constexpr char kInput[] = "hello\n";
   779    constexpr char kExpected[] = "hello\r\n";
   780  
   781    EXPECT_THAT(WriteFd(replica_.get(), kInput, sizeof(kInput) - 1),
   782                SyscallSucceedsWithValue(sizeof(kInput) - 1));
   783  
   784    // Close the replica.
   785    replica_.reset();
   786  
   787    char buf[sizeof(kExpected)] = {};
   788    ExpectReadable(master_, sizeof(buf) - 1, buf);
   789    EXPECT_EQ(memcmp(buf, kExpected, sizeof(kExpected)), 0);
   790  
   791    // After all data has been read, the master should return EIO.
   792    char c;
   793    EXPECT_THAT(ReadFd(master_.get(), &c, 1), SyscallFailsWithErrno(EIO));
   794  }
   795  
   796  TEST_F(PtyTest, WriteInvalidUTF8) {
   797    char c = 0xff;
   798    ASSERT_THAT(syscall(__NR_write, master_.get(), &c, sizeof(c)),
   799                SyscallSucceedsWithValue(sizeof(c)));
   800  }
   801  
   802  // Both the master and replica report the standard default termios settings.
   803  //
   804  // Note that TCGETS on the master actually redirects to the replica (see comment
   805  // on MasterTermiosUnchangable).
   806  TEST_F(PtyTest, DefaultTermios) {
   807    struct kernel_termios t = {};
   808    EXPECT_THAT(ioctl(replica_.get(), TCGETS, &t), SyscallSucceeds());
   809    EXPECT_EQ(t, DefaultTermios());
   810  
   811    EXPECT_THAT(ioctl(master_.get(), TCGETS, &t), SyscallSucceeds());
   812    EXPECT_EQ(t, DefaultTermios());
   813  }
   814  
   815  // Changing termios from the master actually affects the replica.
   816  //
   817  // TCSETS on the master actually redirects to the replica (see comment on
   818  // MasterTermiosUnchangable).
   819  TEST_F(PtyTest, TermiosAffectsReplica) {
   820    struct kernel_termios master_termios = {};
   821    EXPECT_THAT(ioctl(master_.get(), TCGETS, &master_termios), SyscallSucceeds());
   822    master_termios.c_lflag ^= ICANON;
   823    EXPECT_THAT(ioctl(master_.get(), TCSETS, &master_termios), SyscallSucceeds());
   824  
   825    struct kernel_termios replica_termios = {};
   826    EXPECT_THAT(ioctl(replica_.get(), TCGETS, &replica_termios),
   827                SyscallSucceeds());
   828    EXPECT_EQ(master_termios, replica_termios);
   829  }
   830  
   831  // The master end of the pty has termios:
   832  //
   833  // struct kernel_termios t = {
   834  //   .c_iflag = 0;
   835  //   .c_oflag = 0;
   836  //   .c_cflag = B38400 | CS8 | CREAD;
   837  //   .c_lflag = 0;
   838  //   .c_cc = /* same as DefaultTermios */
   839  // }
   840  //
   841  // (From drivers/tty/pty.c:unix98_pty_init)
   842  //
   843  // All termios control ioctls on the master actually redirect to the replica
   844  // (drivers/tty/tty_ioctl.c:tty_mode_ioctl), making it impossible to change the
   845  // master termios.
   846  //
   847  // Verify this by setting ICRNL (which rewrites input \r to \n) and verify that
   848  // it has no effect on the master.
   849  TEST_F(PtyTest, MasterTermiosUnchangable) {
   850    struct kernel_termios master_termios = {};
   851    EXPECT_THAT(ioctl(master_.get(), TCGETS, &master_termios), SyscallSucceeds());
   852    master_termios.c_lflag |= ICRNL;
   853    EXPECT_THAT(ioctl(master_.get(), TCSETS, &master_termios), SyscallSucceeds());
   854  
   855    char c = '\r';
   856    ASSERT_THAT(WriteFd(replica_.get(), &c, 1), SyscallSucceedsWithValue(1));
   857  
   858    ExpectReadable(master_, 1, &c);
   859    EXPECT_EQ(c, '\r');  // ICRNL had no effect!
   860  
   861    ExpectFinished(master_);
   862  }
   863  
   864  // ICRNL rewrites input \r to \n.
   865  TEST_F(PtyTest, TermiosICRNL) {
   866    struct kernel_termios t = DefaultTermios();
   867    t.c_iflag |= ICRNL;
   868    t.c_lflag &= ~ICANON;  // for byte-by-byte reading.
   869    ASSERT_THAT(ioctl(replica_.get(), TCSETS, &t), SyscallSucceeds());
   870  
   871    char c = '\r';
   872    ASSERT_THAT(WriteFd(master_.get(), &c, 1), SyscallSucceedsWithValue(1));
   873  
   874    ExpectReadable(replica_, 1, &c);
   875    EXPECT_EQ(c, '\n');
   876  
   877    ExpectFinished(replica_);
   878  }
   879  
   880  // ONLCR rewrites output \n to \r\n.
   881  TEST_F(PtyTest, TermiosONLCR) {
   882    struct kernel_termios t = DefaultTermios();
   883    t.c_oflag |= ONLCR;
   884    t.c_lflag &= ~ICANON;  // for byte-by-byte reading.
   885    ASSERT_THAT(ioctl(replica_.get(), TCSETS, &t), SyscallSucceeds());
   886  
   887    char c = '\n';
   888    ASSERT_THAT(WriteFd(replica_.get(), &c, 1), SyscallSucceedsWithValue(1));
   889  
   890    // Extra byte for NUL for EXPECT_STREQ.
   891    char buf[3] = {};
   892    ExpectReadable(master_, 2, buf);
   893    EXPECT_STREQ(buf, "\r\n");
   894  
   895    ExpectFinished(replica_);
   896  }
   897  
   898  // ICRNL rewrites input \r to \n.
   899  TEST_F(PtyTest, TCSETSFTermiosICRNL) {
   900    struct kernel_termios t = DefaultTermios();
   901    t.c_iflag |= ICRNL;
   902    t.c_lflag &= ~ICANON;  // for byte-by-byte reading.
   903    ASSERT_THAT(ioctl(replica_.get(), TCSETSF, &t), SyscallSucceeds());
   904  
   905    char c = '\r';
   906    ASSERT_THAT(WriteFd(master_.get(), &c, 1), SyscallSucceedsWithValue(1));
   907  
   908    ExpectReadable(replica_, 1, &c);
   909    EXPECT_EQ(c, '\n');
   910  
   911    ExpectFinished(replica_);
   912  }
   913  
   914  // ONLCR rewrites output \n to \r\n.
   915  TEST_F(PtyTest, TCSETSFTermiosONLCR) {
   916    struct kernel_termios t = DefaultTermios();
   917    t.c_oflag |= ONLCR;
   918    t.c_lflag &= ~ICANON;  // for byte-by-byte reading.
   919    ASSERT_THAT(ioctl(replica_.get(), TCSETSF, &t), SyscallSucceeds());
   920  
   921    char c = '\n';
   922    ASSERT_THAT(WriteFd(replica_.get(), &c, 1), SyscallSucceedsWithValue(1));
   923  
   924    // Extra byte for NUL for EXPECT_STREQ.
   925    char buf[3] = {};
   926    ExpectReadable(master_, 2, buf);
   927    EXPECT_STREQ(buf, "\r\n");
   928  
   929    ExpectFinished(replica_);
   930  }
   931  
   932  TEST_F(PtyTest, TermiosIGNCR) {
   933    struct kernel_termios t = DefaultTermios();
   934    t.c_iflag |= IGNCR;
   935    t.c_lflag &= ~ICANON;  // for byte-by-byte reading.
   936    ASSERT_THAT(ioctl(replica_.get(), TCSETS, &t), SyscallSucceeds());
   937  
   938    char c = '\r';
   939    ASSERT_THAT(WriteFd(master_.get(), &c, 1), SyscallSucceedsWithValue(1));
   940  
   941    // Nothing to read.
   942    ASSERT_THAT(PollAndReadFd(replica_.get(), &c, 1, kTimeoutShort),
   943                PosixErrorIs(ETIMEDOUT, ::testing::StrEq("Poll timed out")));
   944  }
   945  
   946  // Test that we can successfully poll for readable data from the replica.
   947  TEST_F(PtyTest, TermiosPollReplica) {
   948    struct kernel_termios t = DefaultTermios();
   949    t.c_iflag |= IGNCR;
   950    t.c_lflag &= ~ICANON;  // for byte-by-byte reading.
   951    ASSERT_THAT(ioctl(replica_.get(), TCSETS, &t), SyscallSucceeds());
   952  
   953    absl::Notification notify;
   954    int sfd = replica_.get();
   955    ScopedThread th([sfd, &notify]() {
   956      notify.Notify();
   957  
   958      // Poll on the reader fd with POLLIN event.
   959      struct pollfd poll_fd = {sfd, POLLIN, 0};
   960      EXPECT_THAT(
   961          RetryEINTR(poll)(&poll_fd, 1, absl::ToInt64Milliseconds(kTimeout)),
   962          SyscallSucceedsWithValue(1));
   963  
   964      // Should trigger POLLIN event.
   965      EXPECT_EQ(poll_fd.revents & POLLIN, POLLIN);
   966    });
   967  
   968    notify.WaitForNotification();
   969    // Sleep ensures that poll begins waiting before we write to the FD.
   970    absl::SleepFor(absl::Seconds(1));
   971  
   972    char s[] = "foo\n";
   973    ASSERT_THAT(WriteFd(master_.get(), s, strlen(s) + 1), SyscallSucceeds());
   974  }
   975  
   976  // Test that we can successfully poll for readable data from the master.
   977  TEST_F(PtyTest, TermiosPollMaster) {
   978    struct kernel_termios t = DefaultTermios();
   979    t.c_iflag |= IGNCR;
   980    t.c_lflag &= ~ICANON;  // for byte-by-byte reading.
   981    ASSERT_THAT(ioctl(master_.get(), TCSETS, &t), SyscallSucceeds());
   982  
   983    absl::Notification notify;
   984    int mfd = master_.get();
   985    ScopedThread th([mfd, &notify]() {
   986      notify.Notify();
   987  
   988      // Poll on the reader fd with POLLIN event.
   989      struct pollfd poll_fd = {mfd, POLLIN, 0};
   990      EXPECT_THAT(
   991          RetryEINTR(poll)(&poll_fd, 1, absl::ToInt64Milliseconds(kTimeout)),
   992          SyscallSucceedsWithValue(1));
   993  
   994      // Should trigger POLLIN event.
   995      EXPECT_EQ(poll_fd.revents & POLLIN, POLLIN);
   996    });
   997  
   998    notify.WaitForNotification();
   999    // Sleep ensures that poll begins waiting before we write to the FD.
  1000    absl::SleepFor(absl::Seconds(1));
  1001  
  1002    char s[] = "foo\n";
  1003    ASSERT_THAT(WriteFd(replica_.get(), s, strlen(s) + 1), SyscallSucceeds());
  1004  }
  1005  
  1006  TEST_F(PtyTest, TermiosINLCR) {
  1007    struct kernel_termios t = DefaultTermios();
  1008    t.c_iflag |= INLCR;
  1009    t.c_lflag &= ~ICANON;  // for byte-by-byte reading.
  1010    ASSERT_THAT(ioctl(replica_.get(), TCSETS, &t), SyscallSucceeds());
  1011  
  1012    char c = '\n';
  1013    ASSERT_THAT(WriteFd(master_.get(), &c, 1), SyscallSucceedsWithValue(1));
  1014  
  1015    ExpectReadable(replica_, 1, &c);
  1016    EXPECT_EQ(c, '\r');
  1017  
  1018    ExpectFinished(replica_);
  1019  }
  1020  
  1021  TEST_F(PtyTest, TermiosONOCR) {
  1022    struct kernel_termios t = DefaultTermios();
  1023    t.c_oflag |= ONOCR;
  1024    t.c_lflag &= ~ICANON;  // for byte-by-byte reading.
  1025    ASSERT_THAT(ioctl(replica_.get(), TCSETS, &t), SyscallSucceeds());
  1026  
  1027    // The terminal is at column 0, so there should be no CR to read.
  1028    char c = '\r';
  1029    ASSERT_THAT(WriteFd(replica_.get(), &c, 1), SyscallSucceedsWithValue(1));
  1030  
  1031    // Nothing to read.
  1032    ASSERT_THAT(PollAndReadFd(master_.get(), &c, 1, kTimeoutShort),
  1033                PosixErrorIs(ETIMEDOUT, ::testing::StrEq("Poll timed out")));
  1034  
  1035    // This time the column is greater than 0, so we should be able to read the CR
  1036    // out of the other end.
  1037    constexpr char kInput[] = "foo\r";
  1038    constexpr int kInputSize = sizeof(kInput) - 1;
  1039    ASSERT_THAT(WriteFd(replica_.get(), kInput, kInputSize),
  1040                SyscallSucceedsWithValue(kInputSize));
  1041  
  1042    char buf[kInputSize] = {};
  1043    ExpectReadable(master_, kInputSize, buf);
  1044  
  1045    EXPECT_EQ(memcmp(buf, kInput, kInputSize), 0);
  1046  
  1047    ExpectFinished(master_);
  1048  
  1049    // Terminal should be at column 0 again, so no CR can be read.
  1050    ASSERT_THAT(WriteFd(replica_.get(), &c, 1), SyscallSucceedsWithValue(1));
  1051  
  1052    // Nothing to read.
  1053    ASSERT_THAT(PollAndReadFd(master_.get(), &c, 1, kTimeoutShort),
  1054                PosixErrorIs(ETIMEDOUT, ::testing::StrEq("Poll timed out")));
  1055  }
  1056  
  1057  TEST_F(PtyTest, TermiosOCRNL) {
  1058    struct kernel_termios t = DefaultTermios();
  1059    t.c_oflag |= OCRNL;
  1060    t.c_lflag &= ~ICANON;  // for byte-by-byte reading.
  1061    ASSERT_THAT(ioctl(replica_.get(), TCSETS, &t), SyscallSucceeds());
  1062  
  1063    // The terminal is at column 0, so there should be no CR to read.
  1064    char c = '\r';
  1065    ASSERT_THAT(WriteFd(replica_.get(), &c, 1), SyscallSucceedsWithValue(1));
  1066  
  1067    ExpectReadable(master_, 1, &c);
  1068    EXPECT_EQ(c, '\n');
  1069  
  1070    ExpectFinished(master_);
  1071  }
  1072  
  1073  // Tests that VEOL is disabled when we start, and that we can set it to enable
  1074  // it.
  1075  TEST_F(PtyTest, VEOLTermination) {
  1076    // Write a few bytes ending with '\0', and confirm that we can't read.
  1077    constexpr char kInput[] = "hello";
  1078    ASSERT_THAT(WriteFd(master_.get(), kInput, sizeof(kInput)),
  1079                SyscallSucceedsWithValue(sizeof(kInput)));
  1080    char buf[sizeof(kInput)] = {};
  1081    ASSERT_THAT(PollAndReadFd(replica_.get(), buf, sizeof(kInput), kTimeoutShort),
  1082                PosixErrorIs(ETIMEDOUT, ::testing::StrEq("Poll timed out")));
  1083  
  1084    // Set the EOL character to '=' and write it.
  1085    constexpr char delim = '=';
  1086    struct kernel_termios t = DefaultTermios();
  1087    t.c_cc[VEOL] = delim;
  1088    ASSERT_THAT(ioctl(replica_.get(), TCSETS, &t), SyscallSucceeds());
  1089    ASSERT_THAT(WriteFd(master_.get(), &delim, 1), SyscallSucceedsWithValue(1));
  1090  
  1091    // Now we can read, as sending EOL caused the line to become available.
  1092    ExpectReadable(replica_, sizeof(kInput), buf);
  1093    EXPECT_EQ(memcmp(buf, kInput, sizeof(kInput)), 0);
  1094  
  1095    ExpectReadable(replica_, 1, buf);
  1096    EXPECT_EQ(buf[0], '=');
  1097  
  1098    ExpectFinished(replica_);
  1099  }
  1100  
  1101  // Tests that sending "backspace" to the master fd will be handled properly
  1102  // in canonical mode
  1103  TEST_F(PtyTest, CanonInputBackspace) {
  1104    constexpr char kInput[] = "gvisor\x7f\n";
  1105    constexpr char kExpectedOutput[] = "gviso\n";
  1106    constexpr char kEchoExpectedOutput[] = "gvisor\b \b\r\n";
  1107  
  1108    TestCanonicalIO(kInput, kExpectedOutput, kEchoExpectedOutput);
  1109  }
  1110  
  1111  // one backspace should delete the entire multibyte character when IUTF8 is set
  1112  TEST_F(PtyTest, CanonInputBackspaceMultibyteCharacterWithIUTF8) {
  1113    struct kernel_termios t = DefaultTermios();
  1114    t.c_iflag |= IUTF8;
  1115    ASSERT_THAT(ioctl(replica_.get(), TCSETS, &t), SyscallSucceeds());
  1116  
  1117    constexpr char kInput[] = "gviso\xc6\xa9\x7f\n";
  1118    constexpr char kExpectedOutput[] = "gviso\n";
  1119    constexpr char kEchoExpectedOutput[] = "gviso\xc6\xa9\b \b\r\n";
  1120  
  1121    TestCanonicalIO(kInput, kExpectedOutput, kEchoExpectedOutput);
  1122  }
  1123  
  1124  // one backspace should only delete one byte in a multibyte character
  1125  // if IUTF8 is not set
  1126  TEST_F(PtyTest, CanonInputBackspaceMultibyteCharacterWithoutIUTF8) {
  1127    constexpr char kInput[] = "gviso\xc6\xa9\x7f\n";
  1128    constexpr char kExpectedOutput[] = "gviso\xc6\n";
  1129    constexpr char kEchoExpectedOutput[] = "gviso\xc6\xa9\b \b\r\n";
  1130  
  1131    TestCanonicalIO(kInput, kExpectedOutput, kEchoExpectedOutput);
  1132  }
  1133  
  1134  // backspace should not partially delete a multibyte character when IUTF8 is set
  1135  TEST_F(PtyTest, CanonInputBackspaceMultibyteCharacterPartialWithIUTF8) {
  1136    struct kernel_termios t = DefaultTermios();
  1137    t.c_iflag |= IUTF8;
  1138    ASSERT_THAT(ioctl(replica_.get(), TCSETS, &t), SyscallSucceeds());
  1139  
  1140    constexpr char kInput[] = "\x80\x7f\n";
  1141    constexpr char kExpectedOutput[] = "\x80\n";
  1142    constexpr char kEchoExpectedOutput[] = "\x80\r\n";
  1143  
  1144    TestCanonicalIO(kInput, kExpectedOutput, kEchoExpectedOutput);
  1145  }
  1146  
  1147  // backspace can partially delete a multibyte character when IUTF8 is not set
  1148  TEST_F(PtyTest, CanonInputBackspaceMultibyteCharacterPartialWithoutIUTF8) {
  1149    constexpr char kInput[] = "\x80\x7f\n";
  1150    constexpr char kExpectedOutput[] = "\n";
  1151    constexpr char kEchoExpectedOutput[] = "\x80\b \b\r\n";
  1152  
  1153    TestCanonicalIO(kInput, kExpectedOutput, kEchoExpectedOutput);
  1154  }
  1155  
  1156  // ^W, \x17, should erase a word
  1157  TEST_F(PtyTest, CanonInputWordErase) {
  1158    constexpr char kInput[] = "hello hi\x17\n";
  1159    constexpr char kExpectedOutput[] = "hello \n";
  1160    constexpr char kEchoExpectedOutput[] = "hello hi\b \b\b \b\r\n";
  1161  
  1162    TestCanonicalIO(kInput, kExpectedOutput, kEchoExpectedOutput);
  1163  }
  1164  
  1165  // Tests that we can write more than the 4096 character limit, then a
  1166  // terminating character, then read out just the first 4095 bytes plus the
  1167  // terminator.
  1168  TEST_F(PtyTest, CanonBigWrite) {
  1169    constexpr int kWriteLen = kMaxLineSize + 4;
  1170    char input[kWriteLen];
  1171    memset(input, 'M', kWriteLen - 1);
  1172    input[kWriteLen - 1] = '\n';
  1173    ASSERT_THAT(WriteFd(master_.get(), input, kWriteLen),
  1174                SyscallSucceedsWithValue(kWriteLen));
  1175  
  1176    // We can read the line.
  1177    char buf[kMaxLineSize] = {};
  1178    ExpectReadable(replica_, kMaxLineSize, buf);
  1179  
  1180    ExpectFinished(replica_);
  1181  }
  1182  
  1183  // Tests that data written in canonical mode can be read immediately once
  1184  // switched to noncanonical mode.
  1185  TEST_F(PtyTest, SwitchCanonToNoncanon) {
  1186    // Write a few bytes without a terminating character, switch to noncanonical
  1187    // mode, and read them.
  1188    constexpr char kInput[] = "hello";
  1189    ASSERT_THAT(WriteFd(master_.get(), kInput, sizeof(kInput)),
  1190                SyscallSucceedsWithValue(sizeof(kInput)));
  1191  
  1192    // Nothing available yet.
  1193    char buf[sizeof(kInput)] = {};
  1194    ASSERT_THAT(PollAndReadFd(replica_.get(), buf, sizeof(kInput), kTimeoutShort),
  1195                PosixErrorIs(ETIMEDOUT, ::testing::StrEq("Poll timed out")));
  1196  
  1197    DisableCanonical();
  1198  
  1199    ExpectReadable(replica_, sizeof(kInput), buf);
  1200    EXPECT_STREQ(buf, kInput);
  1201  
  1202    ExpectFinished(replica_);
  1203  }
  1204  
  1205  TEST_F(PtyTest, SwitchCanonToNonCanonNewline) {
  1206    // Write a few bytes with a terminating character.
  1207    constexpr char kInput[] = "hello\n";
  1208    ASSERT_THAT(WriteFd(master_.get(), kInput, sizeof(kInput)),
  1209                SyscallSucceedsWithValue(sizeof(kInput)));
  1210  
  1211    DisableCanonical();
  1212  
  1213    // We can read the line.
  1214    char buf[sizeof(kInput)] = {};
  1215    ExpectReadable(replica_, sizeof(kInput), buf);
  1216    EXPECT_STREQ(buf, kInput);
  1217  
  1218    ExpectFinished(replica_);
  1219  }
  1220  
  1221  TEST_F(PtyTest, SwitchNoncanonToCanonNewlineBig) {
  1222    DisableCanonical();
  1223  
  1224    // Write more than the maximum line size, then write a delimiter.
  1225    constexpr int kWriteLen = 4100;
  1226    char input[kWriteLen];
  1227    memset(input, 'M', kWriteLen);
  1228    ASSERT_THAT(WriteFd(master_.get(), input, kWriteLen),
  1229                SyscallSucceedsWithValue(kWriteLen));
  1230    // Wait for the input queue to fill.
  1231    ASSERT_NO_ERRNO(WaitUntilReceived(replica_.get(), kMaxLineSize - 1));
  1232    constexpr char delim = '\n';
  1233    ASSERT_THAT(WriteFd(master_.get(), &delim, 1), SyscallSucceedsWithValue(1));
  1234  
  1235    EnableCanonical();
  1236  
  1237    // We can read the line.
  1238    char buf[kMaxLineSize] = {};
  1239    ExpectReadable(replica_, kMaxLineSize - 1, buf);
  1240  
  1241    // We can also read the remaining characters.
  1242    ExpectReadable(replica_, 6, buf);
  1243  
  1244    ExpectFinished(replica_);
  1245  }
  1246  
  1247  TEST_F(PtyTest, SwitchNoncanonToCanonNoNewline) {
  1248    DisableCanonical();
  1249  
  1250    // Write a few bytes without a terminating character.
  1251    // mode, and read them.
  1252    constexpr char kInput[] = "hello";
  1253    ASSERT_THAT(WriteFd(master_.get(), kInput, sizeof(kInput) - 1),
  1254                SyscallSucceedsWithValue(sizeof(kInput) - 1));
  1255  
  1256    ASSERT_NO_ERRNO(WaitUntilReceived(replica_.get(), sizeof(kInput) - 1));
  1257    EnableCanonical();
  1258  
  1259    // We can read the line.
  1260    char buf[sizeof(kInput)] = {};
  1261    ExpectReadable(replica_, sizeof(kInput) - 1, buf);
  1262    EXPECT_STREQ(buf, kInput);
  1263  
  1264    ExpectFinished(replica_);
  1265  }
  1266  
  1267  TEST_F(PtyTest, SwitchNoncanonToCanonNoNewlineBig) {
  1268    DisableCanonical();
  1269  
  1270    // Write a few bytes without a terminating character.
  1271    // mode, and read them.
  1272    constexpr int kWriteLen = 4100;
  1273    char input[kWriteLen];
  1274    memset(input, 'M', kWriteLen);
  1275    ASSERT_THAT(WriteFd(master_.get(), input, kWriteLen),
  1276                SyscallSucceedsWithValue(kWriteLen));
  1277  
  1278    ASSERT_NO_ERRNO(WaitUntilReceived(replica_.get(), kMaxLineSize - 1));
  1279    EnableCanonical();
  1280  
  1281    // We can read the line.
  1282    char buf[kMaxLineSize] = {};
  1283    ExpectReadable(replica_, kMaxLineSize - 1, buf);
  1284  
  1285    ExpectFinished(replica_);
  1286  }
  1287  
  1288  // If the canonical input buffer is empty, and we switch to non-canonical
  1289  // mode, the input buffer should not be readable.
  1290  TEST_F(PtyTest, SwitchCanonToNoncanonEmptyInput) {
  1291    constexpr char kInput[] = "";
  1292    ASSERT_THAT(WriteFd(master_.get(), kInput, sizeof(kInput)),
  1293                SyscallSucceedsWithValue(sizeof(kInput)));
  1294  
  1295    DisableCanonical();
  1296  
  1297    // Nothing available yet.
  1298    char buf[2] = {};
  1299    ASSERT_THAT(PollAndReadFd(replica_.get(), buf, 2, kTimeoutShort),
  1300                PosixErrorIs(ETIMEDOUT, ::testing::StrEq("Poll timed out")));
  1301  
  1302    ExpectFinished(replica_);
  1303  }
  1304  
  1305  // Tests that we can write over the 4095 noncanonical limit, then read out
  1306  // everything.
  1307  TEST_F(PtyTest, NoncanonBigWrite) {
  1308    DisableCanonical();
  1309  
  1310    // Write well over the 4095 internal buffer limit.
  1311    constexpr char kInput = 'M';
  1312    constexpr int kInputSize = kMaxLineSize * 2;
  1313    for (int i = 0; i < kInputSize; i++) {
  1314      // This makes too many syscalls for save/restore.
  1315      const DisableSave ds;
  1316      ASSERT_THAT(WriteFd(master_.get(), &kInput, sizeof(kInput)),
  1317                  SyscallSucceedsWithValue(sizeof(kInput)));
  1318    }
  1319  
  1320    // We should be able to read out everything. Sleep a bit so that Linux has a
  1321    // chance to move data from the master to the replica.
  1322    ASSERT_NO_ERRNO(WaitUntilReceived(replica_.get(), kMaxLineSize - 1));
  1323    for (int i = 0; i < kInputSize; i++) {
  1324      // This makes too many syscalls for save/restore.
  1325      const DisableSave ds;
  1326      char c;
  1327      ExpectReadable(replica_, 1, &c);
  1328      ASSERT_EQ(c, kInput);
  1329    }
  1330  
  1331    ExpectFinished(replica_);
  1332  }
  1333  
  1334  // ICANON doesn't make input available until a line delimiter is typed.
  1335  //
  1336  // Test newline.
  1337  TEST_F(PtyTest, TermiosICANONNewline) {
  1338    char input[3] = {'a', 'b', 'c'};
  1339    ASSERT_THAT(WriteFd(master_.get(), input, sizeof(input)),
  1340                SyscallSucceedsWithValue(sizeof(input)));
  1341  
  1342    // Extra bytes for newline (written later) and NUL for EXPECT_STREQ.
  1343    char buf[5] = {};
  1344  
  1345    // Nothing available yet.
  1346    ASSERT_THAT(PollAndReadFd(replica_.get(), buf, sizeof(input), kTimeoutShort),
  1347                PosixErrorIs(ETIMEDOUT, ::testing::StrEq("Poll timed out")));
  1348  
  1349    char delim = '\n';
  1350    ASSERT_THAT(WriteFd(master_.get(), &delim, 1), SyscallSucceedsWithValue(1));
  1351  
  1352    // Now it is available.
  1353    ASSERT_NO_ERRNO(WaitUntilReceived(replica_.get(), sizeof(input) + 1));
  1354    ExpectReadable(replica_, sizeof(input) + 1, buf);
  1355    EXPECT_STREQ(buf, "abc\n");
  1356  
  1357    ExpectFinished(replica_);
  1358  }
  1359  
  1360  // ICANON doesn't make input available until a line delimiter is typed.
  1361  //
  1362  // Test EOF (^D).
  1363  TEST_F(PtyTest, TermiosICANONEOF) {
  1364    char input[3] = {'a', 'b', 'c'};
  1365    ASSERT_THAT(WriteFd(master_.get(), input, sizeof(input)),
  1366                SyscallSucceedsWithValue(sizeof(input)));
  1367  
  1368    // Extra byte for NUL for EXPECT_STREQ.
  1369    char buf[4] = {};
  1370  
  1371    // Nothing available yet.
  1372    ASSERT_THAT(PollAndReadFd(replica_.get(), buf, sizeof(input), kTimeoutShort),
  1373                PosixErrorIs(ETIMEDOUT, ::testing::StrEq("Poll timed out")));
  1374    char delim = ControlCharacter('D');
  1375    ASSERT_THAT(WriteFd(master_.get(), &delim, 1), SyscallSucceedsWithValue(1));
  1376  
  1377    // Now it is available. Note that ^D is not included.
  1378    ExpectReadable(replica_, sizeof(input), buf);
  1379    EXPECT_STREQ(buf, "abc");
  1380  
  1381    // New Linux kernels can return zero.
  1382    EXPECT_THAT(
  1383        ReadFd(replica_.get(), buf, 1),
  1384        AnyOf(SyscallSucceedsWithValue(0), SyscallFailsWithErrno(EAGAIN)));
  1385  }
  1386  
  1387  // ICANON limits us to 4096 bytes including a terminating character. Anything
  1388  // after and 4095th character is discarded (although still processed for
  1389  // signals and echoing).
  1390  TEST_F(PtyTest, CanonDiscard) {
  1391    constexpr char kInput = 'M';
  1392    constexpr int kInputSize = 4100;
  1393    constexpr int kIter = 3;
  1394  
  1395    // A few times write more than the 4096 character maximum, then a newline.
  1396    constexpr char delim = '\n';
  1397    for (int i = 0; i < kIter; i++) {
  1398      // This makes too many syscalls for save/restore.
  1399      const DisableSave ds;
  1400      for (int i = 0; i < kInputSize; i++) {
  1401        ASSERT_THAT(WriteFd(master_.get(), &kInput, sizeof(kInput)),
  1402                    SyscallSucceedsWithValue(sizeof(kInput)));
  1403      }
  1404      ASSERT_THAT(WriteFd(master_.get(), &delim, 1), SyscallSucceedsWithValue(1));
  1405    }
  1406  
  1407    // There should be multiple truncated lines available to read.
  1408    for (int i = 0; i < kIter; i++) {
  1409      char buf[kInputSize] = {};
  1410      ExpectReadable(replica_, kMaxLineSize, buf);
  1411      EXPECT_EQ(buf[kMaxLineSize - 1], delim);
  1412      EXPECT_EQ(buf[kMaxLineSize - 2], kInput);
  1413    }
  1414  
  1415    ExpectFinished(replica_);
  1416  }
  1417  
  1418  TEST_F(PtyTest, CanonMultiline) {
  1419    constexpr char kInput1[] = "GO\n";
  1420    constexpr char kInput2[] = "BLUE\n";
  1421  
  1422    // Write both lines.
  1423    ASSERT_THAT(WriteFd(master_.get(), kInput1, sizeof(kInput1) - 1),
  1424                SyscallSucceedsWithValue(sizeof(kInput1) - 1));
  1425    ASSERT_THAT(WriteFd(master_.get(), kInput2, sizeof(kInput2) - 1),
  1426                SyscallSucceedsWithValue(sizeof(kInput2) - 1));
  1427  
  1428    // Get the first line.
  1429    char line1[8] = {};
  1430    ExpectReadable(replica_, sizeof(kInput1) - 1, line1);
  1431    EXPECT_STREQ(line1, kInput1);
  1432  
  1433    // Get the second line.
  1434    char line2[8] = {};
  1435    ExpectReadable(replica_, sizeof(kInput2) - 1, line2);
  1436    EXPECT_STREQ(line2, kInput2);
  1437  
  1438    ExpectFinished(replica_);
  1439  }
  1440  
  1441  TEST_F(PtyTest, SwitchNoncanonToCanonMultiline) {
  1442    DisableCanonical();
  1443  
  1444    constexpr char kInput1[] = "GO\n";
  1445    constexpr char kInput2[] = "BLUE\n";
  1446    constexpr char kExpected[] = "GO\nBLUE\n";
  1447  
  1448    // Write both lines.
  1449    ASSERT_THAT(WriteFd(master_.get(), kInput1, sizeof(kInput1) - 1),
  1450                SyscallSucceedsWithValue(sizeof(kInput1) - 1));
  1451    ASSERT_THAT(WriteFd(master_.get(), kInput2, sizeof(kInput2) - 1),
  1452                SyscallSucceedsWithValue(sizeof(kInput2) - 1));
  1453  
  1454    ASSERT_NO_ERRNO(
  1455        WaitUntilReceived(replica_.get(), sizeof(kInput1) + sizeof(kInput2) - 2));
  1456    EnableCanonical();
  1457  
  1458    // Get all together as one line.
  1459    char line[9] = {};
  1460    ExpectReadable(replica_, 8, line);
  1461    EXPECT_STREQ(line, kExpected);
  1462  
  1463    ExpectFinished(replica_);
  1464  }
  1465  
  1466  TEST_F(PtyTest, SwitchTwiceMultiline) {
  1467    std::string kInputs[] = {"GO\n", "BLUE\n", "!"};
  1468    std::string kExpected = "GO\nBLUE\n!";
  1469  
  1470    // Write each line.
  1471    for (const std::string &input : kInputs) {
  1472      ASSERT_THAT(WriteFd(master_.get(), input.c_str(), input.size()),
  1473                  SyscallSucceedsWithValue(input.size()));
  1474    }
  1475  
  1476    DisableCanonical();
  1477    // All written characters have to make it into the input queue before
  1478    // canonical mode is re-enabled. If the final '!' character hasn't been
  1479    // enqueued before canonical mode is re-enabled, it won't be readable.
  1480    ASSERT_NO_ERRNO(WaitUntilReceived(replica_.get(), kExpected.size()));
  1481    EnableCanonical();
  1482  
  1483    // Get all together as one line.
  1484    char line[10] = {};
  1485    ExpectReadable(replica_, 9, line);
  1486    EXPECT_STREQ(line, kExpected.c_str());
  1487  
  1488    ExpectFinished(replica_);
  1489  }
  1490  
  1491  TEST_F(PtyTest, QueueSize) {
  1492    // Write the line.
  1493    constexpr char kInput1[] = "GO\n";
  1494    ASSERT_THAT(WriteFd(master_.get(), kInput1, sizeof(kInput1) - 1),
  1495                SyscallSucceedsWithValue(sizeof(kInput1) - 1));
  1496    ASSERT_NO_ERRNO(WaitUntilReceived(replica_.get(), sizeof(kInput1) - 1));
  1497  
  1498    // Ensure that writing more (beyond what is readable) does not impact the
  1499    // readable size.
  1500    char input[kMaxLineSize];
  1501    memset(input, 'M', kMaxLineSize);
  1502    ASSERT_THAT(WriteFd(master_.get(), input, kMaxLineSize),
  1503                SyscallSucceedsWithValue(kMaxLineSize));
  1504    int inputBufSize = ASSERT_NO_ERRNO_AND_VALUE(
  1505        WaitUntilReceived(replica_.get(), sizeof(kInput1) - 1));
  1506    EXPECT_EQ(inputBufSize, sizeof(kInput1) - 1);
  1507  }
  1508  
  1509  TEST_F(PtyTest, PartialBadBuffer) {
  1510    // Allocate 2 pages.
  1511    void *addr = mmap(nullptr, 2 * kPageSize, PROT_READ | PROT_WRITE,
  1512                      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  1513    ASSERT_NE(addr, MAP_FAILED);
  1514    char *buf = reinterpret_cast<char *>(addr);
  1515  
  1516    // Guard the 2nd page for our read to run into.
  1517    ASSERT_THAT(
  1518        mprotect(reinterpret_cast<void *>(buf + kPageSize), kPageSize, PROT_NONE),
  1519        SyscallSucceeds());
  1520  
  1521    // Leave only one free byte in the buffer.
  1522    char *bad_buffer = buf + kPageSize - 1;
  1523  
  1524    // Write to the master.
  1525    constexpr char kBuf[] = "hello\n";
  1526    constexpr size_t size = sizeof(kBuf) - 1;
  1527    EXPECT_THAT(WriteFd(master_.get(), kBuf, size),
  1528                SyscallSucceedsWithValue(size));
  1529  
  1530    // Read from the replica into bad_buffer.
  1531    ASSERT_NO_ERRNO(WaitUntilReceived(replica_.get(), size));
  1532    // Before Linux 3b830a9c this returned EFAULT, but after that commit it
  1533    // returns EAGAIN.
  1534    EXPECT_THAT(
  1535        ReadFd(replica_.get(), bad_buffer, size),
  1536        AnyOf(SyscallFailsWithErrno(EFAULT), SyscallFailsWithErrno(EAGAIN)));
  1537  
  1538    EXPECT_THAT(munmap(addr, 2 * kPageSize), SyscallSucceeds()) << addr;
  1539  }
  1540  
  1541  // Test that writing nothing to the PTY replica's output queue does not return
  1542  // an error.
  1543  TEST_F(PtyTest, ReplicaWriteNothingCanonical) {
  1544    constexpr char kInput[] = "";
  1545    EXPECT_THAT(WriteFd(replica_.get(), kInput, strlen(kInput)),
  1546                SyscallSucceedsWithValue(strlen(kInput)));
  1547  
  1548    ExpectFinished(master_);
  1549  }
  1550  
  1551  TEST_F(PtyTest, ReplicaWriteNothingNonCanonical) {
  1552    DisableCanonical();
  1553  
  1554    constexpr char kInput[] = "";
  1555    EXPECT_THAT(WriteFd(replica_.get(), kInput, strlen(kInput)),
  1556                SyscallSucceedsWithValue(strlen(kInput)));
  1557  
  1558    ExpectFinished(master_);
  1559  }
  1560  
  1561  TEST_F(PtyTest, SimpleEcho) {
  1562    constexpr char kInput[] = "Mr. Eko";
  1563    EXPECT_THAT(WriteFd(master_.get(), kInput, strlen(kInput)),
  1564                SyscallSucceedsWithValue(strlen(kInput)));
  1565  
  1566    char buf[100] = {};
  1567    ExpectReadable(master_, strlen(kInput), buf);
  1568  
  1569    EXPECT_STREQ(buf, kInput);
  1570    ExpectFinished(master_);
  1571  }
  1572  
  1573  TEST_F(PtyTest, GetWindowSize) {
  1574    struct winsize ws;
  1575    ASSERT_THAT(ioctl(replica_.get(), TIOCGWINSZ, &ws), SyscallSucceeds());
  1576    EXPECT_EQ(ws.ws_row, 0);
  1577    EXPECT_EQ(ws.ws_col, 0);
  1578  }
  1579  
  1580  TEST_F(PtyTest, SetReplicaWindowSize) {
  1581    constexpr uint16_t kRows = 343;
  1582    constexpr uint16_t kCols = 2401;
  1583    struct winsize ws = {.ws_row = kRows, .ws_col = kCols};
  1584    ASSERT_THAT(ioctl(replica_.get(), TIOCSWINSZ, &ws), SyscallSucceeds());
  1585  
  1586    struct winsize retrieved_ws = {};
  1587    ASSERT_THAT(ioctl(master_.get(), TIOCGWINSZ, &retrieved_ws),
  1588                SyscallSucceeds());
  1589    EXPECT_EQ(retrieved_ws.ws_row, kRows);
  1590    EXPECT_EQ(retrieved_ws.ws_col, kCols);
  1591  }
  1592  
  1593  TEST_F(PtyTest, SetMasterWindowSize) {
  1594    constexpr uint16_t kRows = 343;
  1595    constexpr uint16_t kCols = 2401;
  1596    struct winsize ws = {.ws_row = kRows, .ws_col = kCols};
  1597    ASSERT_THAT(ioctl(master_.get(), TIOCSWINSZ, &ws), SyscallSucceeds());
  1598  
  1599    struct winsize retrieved_ws = {};
  1600    ASSERT_THAT(ioctl(replica_.get(), TIOCGWINSZ, &retrieved_ws),
  1601                SyscallSucceeds());
  1602    EXPECT_EQ(retrieved_ws.ws_row, kRows);
  1603    EXPECT_EQ(retrieved_ws.ws_col, kCols);
  1604  }
  1605  
  1606  class JobControlTest : public ::testing::Test {
  1607   protected:
  1608    void SetUp() override {
  1609      master_ = ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/ptmx", O_RDWR | O_NONBLOCK));
  1610      replica_ = ASSERT_NO_ERRNO_AND_VALUE(OpenReplica(master_));
  1611  
  1612      // Make this a session leader, which also drops the controlling terminal.
  1613      // In the gVisor test environment, this test will be run as the session
  1614      // leader already (as the sentry init process).
  1615      if (!IsRunningOnGvisor()) {
  1616        // Ignore failure because setsid(2) fails if the process is already the
  1617        // session leader.
  1618        setsid();
  1619        ioctl(replica_.get(), TIOCNOTTY);
  1620      }
  1621    }
  1622  
  1623    PosixError RunInChild(SubprocessCallback childFunc) {
  1624      pid_t child = fork();
  1625      if (!child) {
  1626        childFunc();
  1627        _exit(0);
  1628      }
  1629      int wstatus;
  1630      if (waitpid(child, &wstatus, 0) != child) {
  1631        return PosixError(
  1632            errno, absl::StrCat("child failed with wait status: ", wstatus));
  1633      }
  1634      return PosixError(wstatus, "process returned");
  1635    }
  1636  
  1637    // Master and replica ends of the PTY. Non-blocking.
  1638    FileDescriptor master_;
  1639    FileDescriptor replica_;
  1640  };
  1641  
  1642  TEST_F(JobControlTest, SetTTYMaster) {
  1643    auto res = RunInChild([=]() {
  1644      TEST_PCHECK(setsid() >= 0);
  1645      TEST_PCHECK(!ioctl(master_.get(), TIOCSCTTY, 0));
  1646    });
  1647    ASSERT_NO_ERRNO(res);
  1648  }
  1649  
  1650  TEST_F(JobControlTest, SetTTY) {
  1651    auto res = RunInChild([=]() {
  1652      TEST_PCHECK(setsid() >= 0);
  1653      TEST_PCHECK(ioctl(replica_.get(), TIOCSCTTY, 0) >= 0);
  1654      // The second attempt setting the same terminal has to be no-op.
  1655      TEST_PCHECK(ioctl(replica_.get(), TIOCSCTTY, 0) >= 0);
  1656    });
  1657    ASSERT_NO_ERRNO(res);
  1658  }
  1659  
  1660  TEST_F(JobControlTest, SetTTYNonLeader) {
  1661    // Fork a process that won't be the session leader.
  1662    auto res =
  1663        RunInChild([=]() { TEST_PCHECK(ioctl(replica_.get(), TIOCSCTTY, 0)); });
  1664    ASSERT_NO_ERRNO(res);
  1665  }
  1666  
  1667  TEST_F(JobControlTest, SetTTYBadArg) {
  1668    SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_SYS_ADMIN)));
  1669    auto res = RunInChild([=]() {
  1670      TEST_PCHECK(setsid() >= 0);
  1671      TEST_PCHECK(!ioctl(replica_.get(), TIOCSCTTY, 1));
  1672    });
  1673    ASSERT_NO_ERRNO(res);
  1674  }
  1675  
  1676  TEST_F(JobControlTest, SetTTYDifferentSession) {
  1677    SKIP_IF(ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_SYS_ADMIN)));
  1678  
  1679    auto res = RunInChild([=]() {
  1680      TEST_PCHECK(setsid() >= 0);
  1681      TEST_PCHECK(!ioctl(replica_.get(), TIOCSCTTY, 1));
  1682  
  1683      // Fork, join a new session, and try to steal the parent's controlling
  1684      // terminal, which should fail.
  1685      pid_t grandchild = fork();
  1686      if (!grandchild) {
  1687        TEST_PCHECK(setsid() >= 0);
  1688        // We shouldn't be able to steal the terminal.
  1689        TEST_PCHECK(ioctl(replica_.get(), TIOCSCTTY, 1));
  1690        _exit(0);
  1691      }
  1692  
  1693      int gcwstatus;
  1694      TEST_PCHECK(waitpid(grandchild, &gcwstatus, 0) == grandchild);
  1695      TEST_PCHECK(gcwstatus == 0);
  1696    });
  1697    ASSERT_NO_ERRNO(res);
  1698  }
  1699  
  1700  TEST_F(JobControlTest, ReleaseTTY) {
  1701    ASSERT_THAT(ioctl(replica_.get(), TIOCSCTTY, 0), SyscallSucceeds());
  1702  
  1703    // Make sure we're ignoring SIGHUP, which will be sent to this process once we
  1704    // disconnect the TTY.
  1705    struct sigaction sa = {};
  1706    sa.sa_handler = SIG_IGN;
  1707    sa.sa_flags = 0;
  1708    sigemptyset(&sa.sa_mask);
  1709    struct sigaction old_sa;
  1710    EXPECT_THAT(sigaction(SIGHUP, &sa, &old_sa), SyscallSucceeds());
  1711    EXPECT_THAT(ioctl(replica_.get(), TIOCNOTTY), SyscallSucceeds());
  1712    EXPECT_THAT(sigaction(SIGHUP, &old_sa, NULL), SyscallSucceeds());
  1713  }
  1714  
  1715  TEST_F(JobControlTest, ReleaseUnsetTTY) {
  1716    ASSERT_THAT(ioctl(replica_.get(), TIOCNOTTY), SyscallFailsWithErrno(ENOTTY));
  1717  }
  1718  
  1719  TEST_F(JobControlTest, ReleaseWrongTTY) {
  1720    auto res = RunInChild([=]() {
  1721      TEST_PCHECK(setsid() >= 0);
  1722      TEST_PCHECK(!ioctl(replica_.get(), TIOCSCTTY, 0));
  1723      TEST_PCHECK(ioctl(master_.get(), TIOCNOTTY) < 0 && errno == ENOTTY);
  1724    });
  1725    ASSERT_NO_ERRNO(res);
  1726  }
  1727  
  1728  TEST_F(JobControlTest, ReleaseTTYNonLeader) {
  1729    auto ret = RunInChild([=]() {
  1730      TEST_PCHECK(setsid() >= 0);
  1731      TEST_PCHECK(!ioctl(replica_.get(), TIOCSCTTY, 0));
  1732  
  1733      pid_t grandchild = fork();
  1734      if (!grandchild) {
  1735        TEST_PCHECK(!ioctl(replica_.get(), TIOCNOTTY));
  1736        _exit(0);
  1737      }
  1738  
  1739      int wstatus;
  1740      TEST_PCHECK(waitpid(grandchild, &wstatus, 0) == grandchild);
  1741      TEST_PCHECK(wstatus == 0);
  1742    });
  1743    ASSERT_NO_ERRNO(ret);
  1744  }
  1745  
  1746  TEST_F(JobControlTest, ReleaseTTYDifferentSession) {
  1747    auto ret = RunInChild([=]() {
  1748      TEST_PCHECK(setsid() >= 0);
  1749  
  1750      TEST_PCHECK(!ioctl(replica_.get(), TIOCSCTTY, 0));
  1751  
  1752      pid_t grandchild = fork();
  1753      if (!grandchild) {
  1754        // Join a new session, then try to disconnect.
  1755        TEST_PCHECK(setsid() >= 0);
  1756        TEST_PCHECK(ioctl(replica_.get(), TIOCNOTTY));
  1757        _exit(0);
  1758      }
  1759  
  1760      int wstatus;
  1761      TEST_PCHECK(waitpid(grandchild, &wstatus, 0) == grandchild);
  1762      TEST_PCHECK(wstatus == 0);
  1763    });
  1764    ASSERT_NO_ERRNO(ret);
  1765  }
  1766  
  1767  // Used by the child process spawned in ReleaseTTYSignals to track received
  1768  // signals.
  1769  static int received;
  1770  
  1771  void sig_handler(int signum) { received |= signum; }
  1772  
  1773  // When the session leader releases its controlling terminal, the foreground
  1774  // process group gets SIGHUP, then SIGCONT. This test:
  1775  // - Spawns 2 threads
  1776  // - Has thread 1 return 0 if it gets both SIGHUP and SIGCONT
  1777  // - Has thread 2 leave the foreground process group, and return non-zero if it
  1778  //   receives any signals.
  1779  // - Has the parent thread release its controlling terminal
  1780  // - Checks that thread 1 got both signals
  1781  // - Checks that thread 2 didn't get any signals.
  1782  TEST_F(JobControlTest, ReleaseTTYSignals) {
  1783    ASSERT_THAT(ioctl(replica_.get(), TIOCSCTTY, 0), SyscallSucceeds());
  1784  
  1785    received = 0;
  1786    struct sigaction sa = {};
  1787    sa.sa_handler = sig_handler;
  1788    sa.sa_flags = 0;
  1789    sigemptyset(&sa.sa_mask);
  1790    sigaddset(&sa.sa_mask, SIGHUP);
  1791    sigaddset(&sa.sa_mask, SIGCONT);
  1792    sigprocmask(SIG_BLOCK, &sa.sa_mask, NULL);
  1793  
  1794    pid_t same_pgrp_child = fork();
  1795    if (!same_pgrp_child) {
  1796      // The child will wait for SIGHUP and SIGCONT, then return 0. It begins with
  1797      // SIGHUP and SIGCONT blocked. We install signal handlers for those signals,
  1798      // then use sigsuspend to wait for those specific signals.
  1799      TEST_PCHECK(!sigaction(SIGHUP, &sa, NULL));
  1800      TEST_PCHECK(!sigaction(SIGCONT, &sa, NULL));
  1801      sigset_t mask;
  1802      sigfillset(&mask);
  1803      sigdelset(&mask, SIGHUP);
  1804      sigdelset(&mask, SIGCONT);
  1805      while (received != (SIGHUP | SIGCONT)) {
  1806        sigsuspend(&mask);
  1807      }
  1808      _exit(0);
  1809    }
  1810  
  1811    // We don't want to block these anymore.
  1812    sigprocmask(SIG_UNBLOCK, &sa.sa_mask, NULL);
  1813  
  1814    // This child will return non-zero if either SIGHUP or SIGCONT are received.
  1815    pid_t diff_pgrp_child = fork();
  1816    if (!diff_pgrp_child) {
  1817      TEST_PCHECK(!setpgid(0, 0));
  1818      TEST_PCHECK(pause());
  1819      _exit(1);
  1820    }
  1821  
  1822    EXPECT_THAT(setpgid(diff_pgrp_child, diff_pgrp_child), SyscallSucceeds());
  1823  
  1824    // Make sure we're ignoring SIGHUP, which will be sent to this process once we
  1825    // disconnect the TTY.
  1826    struct sigaction sighup_sa = {};
  1827    sighup_sa.sa_handler = SIG_IGN;
  1828    sighup_sa.sa_flags = 0;
  1829    sigemptyset(&sighup_sa.sa_mask);
  1830    struct sigaction old_sa;
  1831    EXPECT_THAT(sigaction(SIGHUP, &sighup_sa, &old_sa), SyscallSucceeds());
  1832  
  1833    // Release the controlling terminal, sending SIGHUP and SIGCONT to all other
  1834    // processes in this process group.
  1835    EXPECT_THAT(ioctl(replica_.get(), TIOCNOTTY), SyscallSucceeds());
  1836  
  1837    EXPECT_THAT(sigaction(SIGHUP, &old_sa, NULL), SyscallSucceeds());
  1838  
  1839    // The child in the same process group will get signaled.
  1840    int wstatus;
  1841    EXPECT_THAT(waitpid(same_pgrp_child, &wstatus, 0),
  1842                SyscallSucceedsWithValue(same_pgrp_child));
  1843    EXPECT_EQ(wstatus, 0);
  1844  
  1845    // The other child will not get signaled.
  1846    EXPECT_THAT(waitpid(diff_pgrp_child, &wstatus, WNOHANG),
  1847                SyscallSucceedsWithValue(0));
  1848    EXPECT_THAT(kill(diff_pgrp_child, SIGKILL), SyscallSucceeds());
  1849  }
  1850  
  1851  // Used by the child process spawned in
  1852  // ControllingProcessPersistsAfterChildExists to track received signals.
  1853  static int received2;
  1854  
  1855  void sig_handler2(int signum) { received2 |= signum; }
  1856  
  1857  // NOTE(gvisor.dev/issue/9898): Regression test. Tests that a TTY's controlling
  1858  // process is not cleared when a non-controlling process exits.
  1859  TEST_F(JobControlTest, ControllingProcessPersistsAfterChildExists) {
  1860    // Set the controlling process for the PTY.
  1861    ASSERT_THAT(ioctl(replica_.get(), TIOCSCTTY, 0), SyscallSucceeds());
  1862  
  1863    // Fork a child, which does nothing and exits. We expect that this process
  1864    // is still the controlling process, so is capable of receiving signals.
  1865    ASSERT_NO_ERRNO(RunInChild([=]() {}));
  1866  
  1867    // Install handler for SIGINT.
  1868    received2 = 0;
  1869    struct sigaction sa = {};
  1870    sa.sa_handler = sig_handler2;
  1871    sa.sa_flags = 0;
  1872    sigemptyset(&sa.sa_mask);
  1873    sigaddset(&sa.sa_mask, SIGINT);
  1874    ASSERT_THAT(sigaction(SIGINT, &sa, NULL), SyscallSucceeds());
  1875  
  1876    // Send ^C.
  1877    constexpr char kInput = ControlCharacter('C');
  1878    ASSERT_THAT(WriteFd(master_.get(), &kInput, 1), SyscallSucceedsWithValue(1));
  1879  
  1880    // Ensure we got the signal. Wait at most for kTimeout.
  1881    absl::Time end = absl::Now() + kTimeout;
  1882    while (received2 != SIGINT) {
  1883      absl::SleepFor(absl::Seconds(1));
  1884      if (end < absl::Now()) {
  1885        FAIL() << "Timed out waiting for SIGINT signal.";
  1886        break;
  1887      }
  1888    }
  1889  
  1890    // Make sure we're ignoring SIGHUP, which will be sent to this process once we
  1891    // disconnect the TTY.
  1892    struct sigaction sighup_sa = {};
  1893    sighup_sa.sa_handler = SIG_IGN;
  1894    sighup_sa.sa_flags = 0;
  1895    sigemptyset(&sighup_sa.sa_mask);
  1896    struct sigaction old_sa;
  1897    EXPECT_THAT(sigaction(SIGHUP, &sighup_sa, &old_sa), SyscallSucceeds());
  1898  
  1899    // Release the controlling terminal and restore the old SIGHUP handler.
  1900    EXPECT_THAT(ioctl(replica_.get(), TIOCNOTTY), SyscallSucceeds());
  1901    EXPECT_THAT(sigaction(SIGHUP, &old_sa, NULL), SyscallSucceeds());
  1902  }
  1903  
  1904  TEST_F(JobControlTest, GetForegroundProcessGroup) {
  1905    auto res = RunInChild([=]() {
  1906      pid_t pid, foreground_pgid;
  1907      TEST_PCHECK(setsid() >= 0);
  1908      TEST_PCHECK(!ioctl(replica_.get(), TIOCSCTTY, 1));
  1909      TEST_PCHECK(!ioctl(replica_.get(), TIOCGPGRP, &foreground_pgid));
  1910      TEST_PCHECK((pid = getpid()) >= 0);
  1911      TEST_PCHECK(pid == foreground_pgid);
  1912    });
  1913    ASSERT_NO_ERRNO(res);
  1914  }
  1915  
  1916  TEST_F(JobControlTest, GetForegroundProcessGroupNonControlling) {
  1917    // At this point there's no controlling terminal, so TIOCGPGRP should fail.
  1918    pid_t foreground_pgid;
  1919    ASSERT_THAT(ioctl(replica_.get(), TIOCGPGRP, &foreground_pgid),
  1920                SyscallFailsWithErrno(ENOTTY));
  1921  }
  1922  
  1923  // This test:
  1924  // - sets itself as the foreground process group
  1925  // - creates a child process in a new process group
  1926  // - sets that child as the foreground process group
  1927  // - kills its child and sets itself as the foreground process group.
  1928  TEST_F(JobControlTest, SetForegroundProcessGroup) {
  1929    auto res = RunInChild([=]() {
  1930      TEST_PCHECK(setsid() >= 0);
  1931      TEST_PCHECK(!ioctl(replica_.get(), TIOCSCTTY, 0));
  1932  
  1933      // Ignore SIGTTOU so that we don't stop ourself when calling tcsetpgrp.
  1934      struct sigaction sa = {};
  1935      sa.sa_handler = SIG_IGN;
  1936      sa.sa_flags = 0;
  1937      sigemptyset(&sa.sa_mask);
  1938      sigaction(SIGTTOU, &sa, NULL);
  1939  
  1940      // Set ourself as the foreground process group.
  1941      TEST_PCHECK(!tcsetpgrp(replica_.get(), getpgid(0)));
  1942  
  1943      // Create a new process that just waits to be signaled.
  1944      pid_t grandchild = fork();
  1945      if (!grandchild) {
  1946        TEST_PCHECK(!pause());
  1947        // We should never reach this.
  1948        _exit(1);
  1949      }
  1950  
  1951      // Make the child its own process group, then make it the controlling
  1952      // process group of the terminal.
  1953      TEST_PCHECK(!setpgid(grandchild, grandchild));
  1954      TEST_PCHECK(!tcsetpgrp(replica_.get(), grandchild));
  1955  
  1956      // Sanity check - we're still the controlling session.
  1957      TEST_PCHECK(getsid(0) == getsid(grandchild));
  1958  
  1959      // Signal the child, wait for it to exit, then retake the terminal.
  1960      TEST_PCHECK(!kill(grandchild, SIGTERM));
  1961      int wstatus;
  1962      TEST_PCHECK(waitpid(grandchild, &wstatus, 0) == grandchild);
  1963      TEST_PCHECK(WIFSIGNALED(wstatus));
  1964      TEST_PCHECK(WTERMSIG(wstatus) == SIGTERM);
  1965  
  1966      // Set ourself as the foreground process.
  1967      pid_t pgid;
  1968      TEST_PCHECK((pgid = getpgid(0)) >= 0);
  1969      TEST_PCHECK(!tcsetpgrp(replica_.get(), pgid));
  1970    });
  1971    ASSERT_NO_ERRNO(res);
  1972  }
  1973  
  1974  // This test verifies if a SIGTTOU signal is sent to the calling process's group
  1975  // when tcsetpgrp is called by a background process
  1976  TEST_F(JobControlTest, SetForegroundProcessGroupSIGTTOUBackground) {
  1977    auto res = RunInChild([=]() {
  1978      TEST_PCHECK(setsid() >= 0);
  1979      TEST_PCHECK(!ioctl(replica_.get(), TIOCSCTTY, 0));
  1980      pid_t grandchild = fork();
  1981      if (!grandchild) {
  1982        // Assign a different pgid to the child so it will result as
  1983        // a background process.
  1984        TEST_PCHECK(!setpgid(grandchild, getpid()));
  1985        TEST_PCHECK(!tcsetpgrp(replica_.get(), getpgid(0)));
  1986        // We should never reach this.
  1987        _exit(1);
  1988      }
  1989      int wstatus;
  1990      TEST_PCHECK(waitpid(grandchild, &wstatus, WSTOPPED) == grandchild);
  1991      TEST_PCHECK(WSTOPSIG(wstatus) == SIGTTOU);
  1992  
  1993      // The child's `tcsetpgrp` got signalled and so should not have
  1994      // taken effect. Verify that.
  1995      TEST_PCHECK(tcgetpgrp(replica_.get()) == getpid());
  1996      EXPECT_THAT(kill(grandchild, SIGKILL), SyscallSucceeds());
  1997    });
  1998    ASSERT_NO_ERRNO(res);
  1999  }
  2000  
  2001  // This test verifies that a SIGTTOU signal is not delivered to
  2002  // a background process which calls tcsetpgrp and is ignoring SIGTTOU
  2003  TEST_F(JobControlTest, SetForegroundProcessGroupSIGTTOUIgnored) {
  2004    auto res = RunInChild([=]() {
  2005      TEST_PCHECK(setsid() >= 0);
  2006      TEST_PCHECK(!ioctl(replica_.get(), TIOCSCTTY, 0));
  2007      pid_t grandchild = fork();
  2008      if (!grandchild) {
  2009        // Ignore SIGTTOU so the child in background won't
  2010        // be stopped when it will call tcsetpgrp
  2011        struct sigaction sa = {};
  2012        sa.sa_handler = SIG_IGN;
  2013        sa.sa_flags = 0;
  2014        sigemptyset(&sa.sa_mask);
  2015        sigaction(SIGTTOU, &sa, NULL);
  2016        // Assign a different pgid to the child so it will result as
  2017        // a background process.
  2018        TEST_PCHECK(!setpgid(grandchild, getpid()));
  2019        TEST_PCHECK(!tcsetpgrp(replica_.get(), getpgid(0)));
  2020        _exit(0);
  2021      }
  2022      int wstatus;
  2023      TEST_PCHECK(waitpid(grandchild, &wstatus, WSTOPPED) == grandchild);
  2024      TEST_PCHECK(WSTOPSIG(wstatus) != SIGTTOU);
  2025      TEST_PCHECK(WIFEXITED(wstatus));
  2026    });
  2027    ASSERT_NO_ERRNO(res);
  2028  }
  2029  
  2030  // This test verifies that a SIGTTOU signal is not delivered to
  2031  // a background process which calls tcsetpgrp and is blocking SIGTTOU
  2032  TEST_F(JobControlTest, SetForegroundProcessGroupSIGTTOUBlocked) {
  2033    auto res = RunInChild([=]() {
  2034      TEST_PCHECK(setsid() >= 0);
  2035      TEST_PCHECK(!ioctl(replica_.get(), TIOCSCTTY, 0));
  2036      pid_t grandchild = fork();
  2037      if (!grandchild) {
  2038        // Block SIGTTOU so the child in background won't
  2039        // be stopped when it will call tcsetpgrp
  2040        sigset_t signal_set;
  2041        sigemptyset(&signal_set);
  2042        sigaddset(&signal_set, SIGTTOU);
  2043        // Block SIGTTIN as well, to make sure that the kernel isn't
  2044        // checking for "blocked == [SIGTTOU]" (see issue 7941 for
  2045        // context).
  2046        sigaddset(&signal_set, SIGTTIN);
  2047        sigprocmask(SIG_BLOCK, &signal_set, NULL);
  2048        // Assign a different pgid to the child so it will result as
  2049        // a background process.
  2050        TEST_PCHECK(!setpgid(grandchild, getpid()));
  2051        TEST_PCHECK(!tcsetpgrp(replica_.get(), getpgid(0)));
  2052        // Unmask the signals to make sure we still don't get
  2053        // signaled. That would happen if `tcsetpgrp` enqueued the
  2054        // signal through the mask -- we would not yet have received it,
  2055        // because of the mask.
  2056        sigprocmask(SIG_UNBLOCK, &signal_set, NULL);
  2057        _exit(0);
  2058      }
  2059      int wstatus;
  2060      TEST_PCHECK(waitpid(grandchild, &wstatus, WSTOPPED) == grandchild);
  2061      TEST_PCHECK(WSTOPSIG(wstatus) != SIGTTOU);
  2062    });
  2063    ASSERT_NO_ERRNO(res);
  2064  }
  2065  
  2066  TEST_F(JobControlTest, SetForegroundProcessGroupWrongTTY) {
  2067    pid_t pid = getpid();
  2068    ASSERT_THAT(ioctl(replica_.get(), TIOCSPGRP, &pid),
  2069                SyscallFailsWithErrno(ENOTTY));
  2070  }
  2071  
  2072  TEST_F(JobControlTest, SetForegroundProcessGroupNegPgid) {
  2073    auto ret = RunInChild([=]() {
  2074      TEST_PCHECK(setsid() >= 0);
  2075      TEST_PCHECK(!ioctl(replica_.get(), TIOCSCTTY, 0));
  2076  
  2077      pid_t pid = -1;
  2078      TEST_PCHECK(ioctl(replica_.get(), TIOCSPGRP, &pid) && errno == EINVAL);
  2079    });
  2080    ASSERT_NO_ERRNO(ret);
  2081  }
  2082  
  2083  TEST_F(JobControlTest, SetForegroundProcessGroupEmptyProcessGroup) {
  2084    auto res = RunInChild([=]() {
  2085      TEST_PCHECK(setsid() >= 0);
  2086      TEST_PCHECK(!ioctl(replica_.get(), TIOCSCTTY, 0));
  2087  
  2088      // Create a new process, put it in a new process group, make that group the
  2089      // foreground process group, then have the process wait.
  2090      pid_t grandchild = fork();
  2091      if (!grandchild) {
  2092        TEST_PCHECK(!setpgid(0, 0));
  2093        _exit(0);
  2094      }
  2095  
  2096      // Wait for the child to exit.
  2097      int wstatus;
  2098      TEST_PCHECK(waitpid(grandchild, &wstatus, 0) == grandchild);
  2099      // The child's process group doesn't exist anymore - this should fail.
  2100      TEST_PCHECK(ioctl(replica_.get(), TIOCSPGRP, &grandchild) != 0 &&
  2101                  errno == ESRCH);
  2102    });
  2103    ASSERT_NO_ERRNO(res);
  2104  }
  2105  
  2106  TEST_F(JobControlTest, SetForegroundProcessGroupDifferentSession) {
  2107    auto ret = RunInChild([=]() {
  2108      TEST_PCHECK(setsid() >= 0);
  2109      TEST_PCHECK(!ioctl(replica_.get(), TIOCSCTTY, 0));
  2110  
  2111      int sync_setsid[2];
  2112      int sync_exit[2];
  2113      TEST_PCHECK(pipe(sync_setsid) >= 0);
  2114      TEST_PCHECK(pipe(sync_exit) >= 0);
  2115  
  2116      // Create a new process and put it in a new session.
  2117      pid_t grandchild = fork();
  2118      if (!grandchild) {
  2119        TEST_PCHECK(setsid() >= 0);
  2120        // Tell the parent we're in a new session.
  2121        char c = 'c';
  2122        TEST_PCHECK(WriteFd(sync_setsid[1], &c, 1) == 1);
  2123        TEST_PCHECK(ReadFd(sync_exit[0], &c, 1) == 1);
  2124        _exit(0);
  2125      }
  2126  
  2127      // Wait for the child to tell us it's in a new session.
  2128      char c = 'c';
  2129      TEST_PCHECK(ReadFd(sync_setsid[0], &c, 1) == 1);
  2130  
  2131      // Child is in a new session, so we can't make it the foregroup process
  2132      // group.
  2133      TEST_PCHECK(ioctl(replica_.get(), TIOCSPGRP, &grandchild) &&
  2134                  errno == EPERM);
  2135  
  2136      TEST_PCHECK(WriteFd(sync_exit[1], &c, 1) == 1);
  2137  
  2138      int wstatus;
  2139      TEST_PCHECK(waitpid(grandchild, &wstatus, 0) == grandchild);
  2140      TEST_PCHECK(WIFEXITED(wstatus));
  2141      TEST_PCHECK(!WEXITSTATUS(wstatus));
  2142    });
  2143    ASSERT_NO_ERRNO(ret);
  2144  }
  2145  
  2146  TEST_F(JobControlTest, SetGetSession) {
  2147    auto res = RunInChild([=]() {
  2148      pid_t sid = setsid();
  2149      TEST_PCHECK(sid >= 0);
  2150      TEST_PCHECK(getsid(0) == sid);
  2151      TEST_PCHECK(getpid() == sid);
  2152    });
  2153    ASSERT_NO_ERRNO(res);
  2154  }
  2155  
  2156  // Verify that we don't hang when creating a new session from an orphaned
  2157  // process group (b/139968068). Calling setsid() creates an orphaned process
  2158  // group, as process groups that contain the session's leading process are
  2159  // orphans.
  2160  //
  2161  // We create 2 sessions in this test. The init process in gVisor is considered
  2162  // not to be an orphan (see sessions.go), so we have to create a session from
  2163  // which to create a session. The latter session is being created from an
  2164  // orphaned process group.
  2165  TEST_F(JobControlTest, OrphanRegression) {
  2166    pid_t session_2_leader = fork();
  2167    if (!session_2_leader) {
  2168      TEST_PCHECK(setsid() >= 0);
  2169  
  2170      pid_t session_3_leader = fork();
  2171      if (!session_3_leader) {
  2172        TEST_PCHECK(setsid() >= 0);
  2173  
  2174        _exit(0);
  2175      }
  2176  
  2177      int wstatus;
  2178      TEST_PCHECK(waitpid(session_3_leader, &wstatus, 0) == session_3_leader);
  2179      TEST_PCHECK(wstatus == 0);
  2180  
  2181      _exit(0);
  2182    }
  2183  
  2184    int wstatus;
  2185    ASSERT_THAT(waitpid(session_2_leader, &wstatus, 0),
  2186                SyscallSucceedsWithValue(session_2_leader));
  2187    ASSERT_EQ(wstatus, 0);
  2188  }
  2189  
  2190  // Test setting a controlling tty, then exiting, then re-using the same tty in a
  2191  // different process.
  2192  //
  2193  // Regression test for https://github.com/google/gvisor/issues/9642.
  2194  TEST_F(JobControlTest, ReuseControllingTTYAfterExit) {
  2195    auto res = RunInChild([=]() {
  2196      TEST_PCHECK(setsid() >= 0);
  2197      TEST_PCHECK(ioctl(replica_.get(), TIOCSCTTY, 0) >= 0);
  2198    });
  2199    ASSERT_NO_ERRNO(res);
  2200  
  2201    auto res2 = RunInChild([=]() {
  2202      TEST_PCHECK(setsid() >= 0);
  2203      TEST_PCHECK(ioctl(replica_.get(), TIOCSCTTY, 0) >= 0);
  2204    });
  2205    ASSERT_NO_ERRNO(res2);
  2206  }
  2207  
  2208  }  // namespace
  2209  }  // namespace testing
  2210  }  // namespace gvisor