github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/test/util/pty_util.cc (about)

     1  // Copyright 2019 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 "test/util/pty_util.h"
    16  
    17  #include <sys/ioctl.h>
    18  #include <termios.h>
    19  
    20  #include "test/util/file_descriptor.h"
    21  #include "test/util/posix_error.h"
    22  
    23  namespace gvisor {
    24  namespace testing {
    25  
    26  PosixErrorOr<FileDescriptor> OpenReplica(const FileDescriptor& master) {
    27    return OpenReplica(master, O_NONBLOCK | O_RDWR | O_NOCTTY);
    28  }
    29  
    30  PosixErrorOr<FileDescriptor> OpenReplica(const FileDescriptor& master,
    31                                           int flags) {
    32    PosixErrorOr<int> n = ReplicaID(master);
    33    if (!n.ok()) {
    34      return PosixErrorOr<FileDescriptor>(n.error());
    35    }
    36    return Open(absl::StrCat("/dev/pts/", n.ValueOrDie()), flags);
    37  }
    38  
    39  PosixErrorOr<int> ReplicaID(const FileDescriptor& master) {
    40    // Get pty index.
    41    int n;
    42    int ret = ioctl(master.get(), TIOCGPTN, &n);
    43    if (ret < 0) {
    44      return PosixError(errno, "ioctl(TIOCGPTN) failed");
    45    }
    46  
    47    // Unlock pts.
    48    int unlock = 0;
    49    ret = ioctl(master.get(), TIOCSPTLCK, &unlock);
    50    if (ret < 0) {
    51      return PosixError(errno, "ioctl(TIOSPTLCK) failed");
    52    }
    53  
    54    return n;
    55  }
    56  
    57  }  // namespace testing
    58  }  // namespace gvisor