gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/syscalls/linux/fcntl.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 <signal.h>
    17  #include <sys/epoll.h>
    18  #include <sys/mman.h>
    19  #include <sys/signalfd.h>
    20  #include <sys/types.h>
    21  #include <syscall.h>
    22  #include <unistd.h>
    23  
    24  #include <atomic>
    25  #include <cerrno>
    26  #include <deque>
    27  #include <iostream>
    28  #include <list>
    29  #include <string>
    30  #include <vector>
    31  
    32  #include "gmock/gmock.h"
    33  #include "gtest/gtest.h"
    34  #include "absl/base/macros.h"
    35  #include "absl/base/port.h"
    36  #include "absl/flags/flag.h"
    37  #include "absl/memory/memory.h"
    38  #include "absl/strings/str_cat.h"
    39  #include "absl/time/clock.h"
    40  #include "absl/time/time.h"
    41  #include "test/util/capability_util.h"
    42  #include "test/util/cleanup.h"
    43  #include "test/util/eventfd_util.h"
    44  #include "test/util/file_descriptor.h"
    45  #include "test/util/fs_util.h"
    46  #include "test/util/memory_util.h"
    47  #include "test/util/multiprocess_util.h"
    48  #include "test/util/posix_error.h"
    49  #include "test/util/save_util.h"
    50  #include "test/util/signal_util.h"
    51  #include "test/util/socket_util.h"
    52  #include "test/util/temp_path.h"
    53  #include "test/util/test_util.h"
    54  #include "test/util/thread_util.h"
    55  #include "test/util/timer_util.h"
    56  
    57  ABSL_FLAG(std::string, child_set_lock_on, "",
    58            "Contains the path to try to set a file lock on.");
    59  ABSL_FLAG(bool, child_set_lock_write, false,
    60            "Whether to set a writable lock (otherwise readable)");
    61  ABSL_FLAG(bool, blocking, false,
    62            "Whether to set a blocking lock (otherwise non-blocking).");
    63  ABSL_FLAG(bool, retry_eintr, false,
    64            "Whether to retry in the subprocess on EINTR.");
    65  ABSL_FLAG(uint64_t, child_set_lock_start, 0, "The value of struct flock start");
    66  ABSL_FLAG(uint64_t, child_set_lock_len, 0, "The value of struct flock len");
    67  ABSL_FLAG(int32_t, socket_fd, -1,
    68            "A socket to use for communicating more state back "
    69            "to the parent.");
    70  
    71  namespace gvisor {
    72  namespace testing {
    73  
    74  std::function<void(int, siginfo_t*, void*)> setsig_signal_handle;
    75  void setsig_signal_handler(int signum, siginfo_t* siginfo, void* ucontext) {
    76    setsig_signal_handle(signum, siginfo, ucontext);
    77  }
    78  
    79  class FcntlLockTest : public ::testing::Test {
    80   public:
    81    void SetUp() override {
    82      // Let's make a socket pair.
    83      ASSERT_THAT(socketpair(AF_UNIX, SOCK_STREAM, 0, fds_), SyscallSucceeds());
    84    }
    85  
    86    void TearDown() override {
    87      EXPECT_THAT(close(fds_[0]), SyscallSucceeds());
    88      EXPECT_THAT(close(fds_[1]), SyscallSucceeds());
    89    }
    90  
    91    int64_t GetSubprocessFcntlTimeInUsec() {
    92      int64_t ret = 0;
    93      EXPECT_THAT(ReadFd(fds_[0], reinterpret_cast<void*>(&ret), sizeof(ret)),
    94                  SyscallSucceedsWithValue(sizeof(ret)));
    95      return ret;
    96    }
    97  
    98    // The first fd will remain with the process creating the subprocess
    99    // and the second will go to the subprocess.
   100    int fds_[2] = {};
   101  };
   102  
   103  struct SignalDelivery {
   104    int num;
   105    siginfo_t info;
   106  };
   107  
   108  class FcntlSignalTest : public ::testing::Test {
   109   public:
   110    void SetUp() override {
   111      int pipe_fds[2];
   112      ASSERT_THAT(pipe2(pipe_fds, O_NONBLOCK), SyscallSucceeds());
   113      pipe_read_fd_ = pipe_fds[0];
   114      pipe_write_fd_ = pipe_fds[1];
   115    }
   116  
   117    PosixErrorOr<Cleanup> RegisterSignalHandler(int signum) {
   118      struct sigaction handler;
   119      handler.sa_sigaction = setsig_signal_handler;
   120      setsig_signal_handle = [&](int signum, siginfo_t* siginfo,
   121                                 void* unused_ucontext) {
   122        SignalDelivery sig;
   123        sig.num = signum;
   124        sig.info = *siginfo;
   125        signals_received_.push_back(sig);
   126        num_signals_received_++;
   127      };
   128      sigemptyset(&handler.sa_mask);
   129      handler.sa_flags = SA_SIGINFO;
   130      return ScopedSigaction(signum, handler);
   131    }
   132  
   133    void FlushAndCloseFD(int fd) {
   134      char buf;
   135      int read_bytes;
   136      do {
   137        read_bytes = read(fd, &buf, 1);
   138      } while (read_bytes > 0);
   139      // read() can also fail with EWOULDBLOCK since the pipe is open in
   140      // non-blocking mode. This is not an error.
   141      EXPECT_TRUE(read_bytes == 0 || (read_bytes == -1 && errno == EWOULDBLOCK));
   142      EXPECT_THAT(close(fd), SyscallSucceeds());
   143    }
   144  
   145    void DupReadFD() {
   146      ASSERT_THAT(pipe_read_fd_dup_ = dup(pipe_read_fd_), SyscallSucceeds());
   147      max_expected_signals++;
   148    }
   149  
   150    void RegisterFD(int fd, int signum) {
   151      ASSERT_THAT(fcntl(fd, F_SETOWN, getpid()), SyscallSucceeds());
   152      ASSERT_THAT(fcntl(fd, F_SETSIG, signum), SyscallSucceeds());
   153      int old_flags;
   154      ASSERT_THAT(old_flags = fcntl(fd, F_GETFL), SyscallSucceeds());
   155      ASSERT_THAT(fcntl(fd, F_SETFL, old_flags | O_ASYNC), SyscallSucceeds());
   156    }
   157  
   158    void GenerateIOEvent() {
   159      ASSERT_THAT(write(pipe_write_fd_, "test", 4), SyscallSucceedsWithValue(4));
   160    }
   161  
   162    void WaitForSignalDelivery(absl::Duration timeout) {
   163      absl::Time wait_start = absl::Now();
   164      while (num_signals_received_ < max_expected_signals &&
   165             absl::Now() - wait_start < timeout) {
   166        absl::SleepFor(absl::Milliseconds(10));
   167      }
   168    }
   169  
   170    int pipe_read_fd_ = -1;
   171    int pipe_read_fd_dup_ = -1;
   172    int pipe_write_fd_ = -1;
   173    int max_expected_signals = 1;
   174    std::deque<SignalDelivery> signals_received_;
   175    std::atomic<int> num_signals_received_ = 0;
   176  };
   177  
   178  namespace {
   179  
   180  PosixErrorOr<Cleanup> SubprocessLock(std::string const& path, bool for_write,
   181                                       bool blocking, bool retry_eintr,
   182                                       int* socket_pair, off_t start,
   183                                       off_t length, pid_t* child) {
   184    std::vector<std::string> args = {
   185        "/proc/self/exe",
   186        "--child_set_lock_on",
   187        path,
   188        "--child_set_lock_start",
   189        absl::StrCat(start),
   190        "--child_set_lock_len",
   191        absl::StrCat(length),
   192        "--socket_fd",
   193        absl::StrCat(socket_pair ? socket_pair[1] : -1)};
   194  
   195    if (for_write) {
   196      args.push_back("--child_set_lock_write");
   197    }
   198  
   199    if (blocking) {
   200      args.push_back("--blocking");
   201    }
   202  
   203    if (retry_eintr) {
   204      args.push_back("--retry_eintr");
   205    }
   206  
   207    int execve_errno = 0;
   208    ASSIGN_OR_RETURN_ERRNO(
   209        auto cleanup,
   210        ForkAndExec("/proc/self/exe", ExecveArray(args.begin(), args.end()), {},
   211                    nullptr, child, &execve_errno));
   212  
   213    if (execve_errno != 0) {
   214      return PosixError(execve_errno, "execve");
   215    }
   216  
   217    if (socket_pair) {
   218      // Wait for when a chill will start.
   219      char c;
   220      EXPECT_THAT(ReadFd(socket_pair[0], reinterpret_cast<void*>(&c), sizeof(c)),
   221                  SyscallSucceedsWithValue(sizeof(c)));
   222    }
   223    return std::move(cleanup);
   224  }
   225  
   226  TEST(FcntlTest, FcntlDupWithOpath) {
   227    auto f = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
   228    FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(f.path(), O_PATH));
   229  
   230    int new_fd;
   231    // Dup the descriptor and make sure it's the same file.
   232    EXPECT_THAT(new_fd = fcntl(fd.get(), F_DUPFD, 0), SyscallSucceeds());
   233  
   234    FileDescriptor nfd = FileDescriptor(new_fd);
   235    ASSERT_NE(fd.get(), nfd.get());
   236    ASSERT_NO_ERRNO(CheckSameFile(fd, nfd));
   237    EXPECT_THAT(fcntl(nfd.get(), F_GETFL), SyscallSucceedsWithValue(O_PATH));
   238  }
   239  
   240  TEST(FcntlTest, SetFileStatusFlagWithOpath) {
   241    TempPath path = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
   242    FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(path.path(), O_PATH));
   243  
   244    EXPECT_THAT(fcntl(fd.get(), F_SETFL, 0), SyscallFailsWithErrno(EBADF));
   245  }
   246  
   247  TEST(FcntlTest, BadFcntlsWithOpath) {
   248    TempPath path = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
   249    FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(path.path(), O_PATH));
   250  
   251    EXPECT_THAT(fcntl(fd.get(), F_SETOWN, 0), SyscallFailsWithErrno(EBADF));
   252    EXPECT_THAT(fcntl(fd.get(), F_GETOWN, 0), SyscallFailsWithErrno(EBADF));
   253  
   254    EXPECT_THAT(fcntl(fd.get(), F_SETOWN_EX, 0), SyscallFailsWithErrno(EBADF));
   255    EXPECT_THAT(fcntl(fd.get(), F_GETOWN_EX, 0), SyscallFailsWithErrno(EBADF));
   256  }
   257  
   258  TEST(FcntlTest, SetCloExecBadFD) {
   259    // Open an eventfd file descriptor with FD_CLOEXEC descriptor flag not set.
   260    FileDescriptor f = ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, 0));
   261    auto fd = f.get();
   262    f.reset();
   263    ASSERT_THAT(fcntl(fd, F_GETFD), SyscallFailsWithErrno(EBADF));
   264    ASSERT_THAT(fcntl(fd, F_SETFD, FD_CLOEXEC), SyscallFailsWithErrno(EBADF));
   265  }
   266  
   267  TEST(FcntlTest, SetCloExec) {
   268    // Open an eventfd file descriptor with FD_CLOEXEC descriptor flag not set.
   269    FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, 0));
   270    ASSERT_THAT(fcntl(fd.get(), F_GETFD), SyscallSucceedsWithValue(0));
   271  
   272    // Set the FD_CLOEXEC flag.
   273    ASSERT_THAT(fcntl(fd.get(), F_SETFD, FD_CLOEXEC), SyscallSucceeds());
   274    ASSERT_THAT(fcntl(fd.get(), F_GETFD), SyscallSucceedsWithValue(FD_CLOEXEC));
   275  }
   276  
   277  TEST(FcntlTest, SetCloExecWithOpath) {
   278    // Open a file descriptor with FD_CLOEXEC descriptor flag not set.
   279    TempPath path = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
   280    FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(path.path(), O_PATH));
   281    ASSERT_THAT(fcntl(fd.get(), F_GETFD), SyscallSucceedsWithValue(0));
   282  
   283    // Set the FD_CLOEXEC flag.
   284    ASSERT_THAT(fcntl(fd.get(), F_SETFD, FD_CLOEXEC), SyscallSucceeds());
   285    ASSERT_THAT(fcntl(fd.get(), F_GETFD), SyscallSucceedsWithValue(FD_CLOEXEC));
   286  }
   287  
   288  TEST(FcntlTest, DupFDCloExecWithOpath) {
   289    // Open a file descriptor with FD_CLOEXEC descriptor flag not set.
   290    TempPath path = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
   291    FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(path.path(), O_PATH));
   292    int nfd;
   293    ASSERT_THAT(nfd = fcntl(fd.get(), F_DUPFD_CLOEXEC, 0), SyscallSucceeds());
   294    FileDescriptor dup_fd(nfd);
   295  
   296    // Check for the FD_CLOEXEC flag.
   297    ASSERT_THAT(fcntl(dup_fd.get(), F_GETFD),
   298                SyscallSucceedsWithValue(FD_CLOEXEC));
   299  }
   300  
   301  TEST(FcntlTest, ClearCloExec) {
   302    // Open an eventfd file descriptor with FD_CLOEXEC descriptor flag set.
   303    FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, EFD_CLOEXEC));
   304    ASSERT_THAT(fcntl(fd.get(), F_GETFD), SyscallSucceedsWithValue(FD_CLOEXEC));
   305  
   306    // Clear the FD_CLOEXEC flag.
   307    ASSERT_THAT(fcntl(fd.get(), F_SETFD, 0), SyscallSucceeds());
   308    ASSERT_THAT(fcntl(fd.get(), F_GETFD), SyscallSucceedsWithValue(0));
   309  }
   310  
   311  TEST(FcntlTest, IndependentDescriptorFlags) {
   312    // Open an eventfd file descriptor with FD_CLOEXEC descriptor flag not set.
   313    FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(NewEventFD(0, 0));
   314    ASSERT_THAT(fcntl(fd.get(), F_GETFD), SyscallSucceedsWithValue(0));
   315  
   316    // Duplicate the descriptor. Ensure that it also doesn't have FD_CLOEXEC.
   317    FileDescriptor newfd = ASSERT_NO_ERRNO_AND_VALUE(fd.Dup());
   318    ASSERT_THAT(fcntl(newfd.get(), F_GETFD), SyscallSucceedsWithValue(0));
   319  
   320    // Set FD_CLOEXEC on the first FD.
   321    ASSERT_THAT(fcntl(fd.get(), F_SETFD, FD_CLOEXEC), SyscallSucceeds());
   322    ASSERT_THAT(fcntl(fd.get(), F_GETFD), SyscallSucceedsWithValue(FD_CLOEXEC));
   323  
   324    // Ensure that the second FD is unaffected by the change on the first.
   325    ASSERT_THAT(fcntl(newfd.get(), F_GETFD), SyscallSucceedsWithValue(0));
   326  }
   327  
   328  // All file description flags passed to open appear in F_GETFL.
   329  TEST(FcntlTest, GetAllFlags) {
   330    TempPath path = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
   331    int flags = O_RDWR | O_DIRECT | O_SYNC | O_NONBLOCK | O_APPEND;
   332    FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(path.path(), flags));
   333  
   334    // Linux forces O_LARGEFILE on all 64-bit kernels and gVisor's is 64-bit.
   335    int expected = flags | kOLargeFile;
   336  
   337    int rflags;
   338    EXPECT_THAT(rflags = fcntl(fd.get(), F_GETFL), SyscallSucceeds());
   339    EXPECT_EQ(rflags, expected);
   340  }
   341  
   342  // When O_PATH is specified in flags, flag bits other than O_CLOEXEC,
   343  // O_DIRECTORY, and O_NOFOLLOW are ignored.
   344  TEST(FcntlTest, GetOpathFlag) {
   345    TempPath path = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
   346    int flags = O_RDWR | O_DIRECT | O_SYNC | O_NONBLOCK | O_APPEND | O_PATH |
   347                O_NOFOLLOW | O_DIRECTORY;
   348    FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(path.path(), flags));
   349  
   350    int expected = O_PATH | O_NOFOLLOW | O_DIRECTORY;
   351  
   352    int rflags;
   353    EXPECT_THAT(rflags = fcntl(fd.get(), F_GETFL), SyscallSucceeds());
   354    EXPECT_EQ(rflags, expected);
   355  }
   356  
   357  TEST(FcntlTest, SetFlags) {
   358    TempPath path = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
   359    FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(path.path(), 0));
   360  
   361    int const flags = O_RDWR | O_DIRECT | O_SYNC | O_NONBLOCK | O_APPEND;
   362    EXPECT_THAT(fcntl(fd.get(), F_SETFL, flags), SyscallSucceeds());
   363  
   364    // Can't set O_RDWR or O_SYNC.
   365    // Linux forces O_LARGEFILE on all 64-bit kernels and gVisor's is 64-bit.
   366    int expected = O_DIRECT | O_NONBLOCK | O_APPEND | kOLargeFile;
   367  
   368    int rflags;
   369    EXPECT_THAT(rflags = fcntl(fd.get(), F_GETFL), SyscallSucceeds());
   370    EXPECT_EQ(rflags, expected);
   371  }
   372  
   373  void TestLock(int fd, short lock_type = F_RDLCK) {  // NOLINT, type in flock
   374    struct flock fl;
   375    fl.l_type = lock_type;
   376    fl.l_whence = SEEK_SET;
   377    fl.l_start = 0;
   378    // len 0 locks all bytes despite how large the file grows.
   379    fl.l_len = 0;
   380    EXPECT_THAT(fcntl(fd, F_SETLK, &fl), SyscallSucceeds());
   381  }
   382  
   383  void TestLockBadFD(int fd,
   384                     short lock_type = F_RDLCK) {  // NOLINT, type in flock
   385    struct flock fl;
   386    fl.l_type = lock_type;
   387    fl.l_whence = SEEK_SET;
   388    fl.l_start = 0;
   389    // len 0 locks all bytes despite how large the file grows.
   390    fl.l_len = 0;
   391    EXPECT_THAT(fcntl(fd, F_SETLK, &fl), SyscallFailsWithErrno(EBADF));
   392  }
   393  
   394  TEST_F(FcntlLockTest, SetLockBadFd) { TestLockBadFD(-1); }
   395  
   396  TEST_F(FcntlLockTest, SetLockDir) {
   397    auto dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
   398    auto fd = ASSERT_NO_ERRNO_AND_VALUE(Open(dir.path(), O_RDONLY, 0000));
   399    TestLock(fd.get());
   400  }
   401  
   402  TEST_F(FcntlLockTest, SetLockSymlink) {
   403    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
   404    auto symlink = ASSERT_NO_ERRNO_AND_VALUE(
   405        TempPath::CreateSymlinkTo(GetAbsoluteTestTmpdir(), file.path()));
   406  
   407    auto fd =
   408        ASSERT_NO_ERRNO_AND_VALUE(Open(symlink.path(), O_RDONLY | O_PATH, 0000));
   409    TestLockBadFD(fd.get());
   410  }
   411  
   412  TEST_F(FcntlLockTest, SetLockProc) {
   413    auto fd =
   414        ASSERT_NO_ERRNO_AND_VALUE(Open("/proc/self/status", O_RDONLY, 0000));
   415    TestLock(fd.get());
   416  }
   417  
   418  TEST_F(FcntlLockTest, SetLockPipe) {
   419    int fds[2];
   420    ASSERT_THAT(pipe(fds), SyscallSucceeds());
   421  
   422    TestLock(fds[0]);
   423    TestLockBadFD(fds[0], F_WRLCK);
   424  
   425    TestLock(fds[1], F_WRLCK);
   426    TestLockBadFD(fds[1]);
   427  
   428    EXPECT_THAT(close(fds[0]), SyscallSucceeds());
   429    EXPECT_THAT(close(fds[1]), SyscallSucceeds());
   430  }
   431  
   432  TEST_F(FcntlLockTest, SetLockSocket) {
   433    int sock = socket(AF_UNIX, SOCK_STREAM, 0);
   434    ASSERT_THAT(sock, SyscallSucceeds());
   435  
   436    struct sockaddr_un addr =
   437        ASSERT_NO_ERRNO_AND_VALUE(UniqueUnixAddr(true /* abstract */, AF_UNIX));
   438    ASSERT_THAT(
   439        bind(sock, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)),
   440        SyscallSucceeds());
   441  
   442    TestLock(sock);
   443    EXPECT_THAT(close(sock), SyscallSucceeds());
   444  }
   445  
   446  TEST_F(FcntlLockTest, SetLockBadOpenFlagsWrite) {
   447    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
   448    FileDescriptor fd =
   449        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDONLY, 0666));
   450  
   451    struct flock fl0;
   452    fl0.l_type = F_WRLCK;
   453    fl0.l_whence = SEEK_SET;
   454    fl0.l_start = 0;
   455    fl0.l_len = 0;  // Lock all file
   456  
   457    // Expect that setting a write lock using a read only file descriptor
   458    // won't work.
   459    EXPECT_THAT(fcntl(fd.get(), F_SETLK, &fl0), SyscallFailsWithErrno(EBADF));
   460  }
   461  
   462  TEST_F(FcntlLockTest, SetLockBadOpenFlagsRead) {
   463    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
   464    FileDescriptor fd =
   465        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_WRONLY, 0666));
   466  
   467    struct flock fl1;
   468    fl1.l_type = F_RDLCK;
   469    fl1.l_whence = SEEK_SET;
   470    fl1.l_start = 0;
   471    // Same as SetLockBadFd.
   472    fl1.l_len = 0;
   473  
   474    EXPECT_THAT(fcntl(fd.get(), F_SETLK, &fl1), SyscallFailsWithErrno(EBADF));
   475  }
   476  
   477  TEST_F(FcntlLockTest, SetLockWithOpath) {
   478    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
   479    FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_PATH));
   480  
   481    struct flock fl0;
   482    fl0.l_type = F_WRLCK;
   483    fl0.l_whence = SEEK_SET;
   484    fl0.l_start = 0;
   485    fl0.l_len = 0;  // Lock all file
   486  
   487    // Expect that setting a write lock using a Opath file descriptor
   488    // won't work.
   489    EXPECT_THAT(fcntl(fd.get(), F_SETLK, &fl0), SyscallFailsWithErrno(EBADF));
   490  }
   491  
   492  TEST_F(FcntlLockTest, SetLockUnlockOnNothing) {
   493    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
   494    FileDescriptor fd =
   495        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
   496  
   497    struct flock fl;
   498    fl.l_type = F_UNLCK;
   499    fl.l_whence = SEEK_SET;
   500    fl.l_start = 0;
   501    // Same as SetLockBadFd.
   502    fl.l_len = 0;
   503  
   504    EXPECT_THAT(fcntl(fd.get(), F_SETLK, &fl), SyscallSucceeds());
   505  }
   506  
   507  TEST_F(FcntlLockTest, SetWriteLockSingleProc) {
   508    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
   509    FileDescriptor fd0 =
   510        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
   511  
   512    struct flock fl;
   513    fl.l_type = F_WRLCK;
   514    fl.l_whence = SEEK_SET;
   515    fl.l_start = 0;
   516    // Same as SetLockBadFd.
   517    fl.l_len = 0;
   518  
   519    EXPECT_THAT(fcntl(fd0.get(), F_SETLK, &fl), SyscallSucceeds());
   520    // Expect to be able to take the same lock on the same fd no problem.
   521    EXPECT_THAT(fcntl(fd0.get(), F_SETLK, &fl), SyscallSucceeds());
   522  
   523    FileDescriptor fd1 =
   524        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
   525  
   526    // Expect to be able to take the same lock from a different fd but for
   527    // the same process.
   528    EXPECT_THAT(fcntl(fd1.get(), F_SETLK, &fl), SyscallSucceeds());
   529  }
   530  
   531  TEST_F(FcntlLockTest, SetReadLockMultiProc) {
   532    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
   533    FileDescriptor fd =
   534        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
   535  
   536    struct flock fl;
   537    fl.l_type = F_RDLCK;
   538    fl.l_whence = SEEK_SET;
   539    fl.l_start = 0;
   540    // Same as SetLockBadFd.
   541    fl.l_len = 0;
   542    EXPECT_THAT(fcntl(fd.get(), F_SETLK, &fl), SyscallSucceeds());
   543  
   544    // spawn a child process to take a read lock on the same file.
   545    pid_t child_pid = 0;
   546    auto cleanup = ASSERT_NO_ERRNO_AND_VALUE(SubprocessLock(
   547        file.path(), false /* write lock */, false /* nonblocking */,
   548        false /* no eintr retry */, nullptr /* no socket fd */, fl.l_start,
   549        fl.l_len, &child_pid));
   550  
   551    int status = 0;
   552    ASSERT_THAT(RetryEINTR(waitpid)(child_pid, &status, 0), SyscallSucceeds());
   553    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
   554        << "Exited with code: " << status;
   555  }
   556  
   557  TEST_F(FcntlLockTest, SetReadThenWriteLockMultiProc) {
   558    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
   559    FileDescriptor fd =
   560        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
   561  
   562    struct flock fl;
   563    fl.l_type = F_RDLCK;
   564    fl.l_whence = SEEK_SET;
   565    fl.l_start = 0;
   566    // Same as SetLockBadFd.
   567    fl.l_len = 0;
   568    EXPECT_THAT(fcntl(fd.get(), F_SETLK, &fl), SyscallSucceeds());
   569  
   570    // Assert that another process trying to lock on the same file will fail
   571    // with EAGAIN.  It's important that we keep the fd above open so that
   572    // that the other process will contend with the lock.
   573    pid_t child_pid = 0;
   574    auto cleanup = ASSERT_NO_ERRNO_AND_VALUE(SubprocessLock(
   575        file.path(), true /* write lock */, false /* nonblocking */,
   576        false /* no eintr retry */, nullptr /* no socket fd */, fl.l_start,
   577        fl.l_len, &child_pid));
   578  
   579    int status = 0;
   580    ASSERT_THAT(RetryEINTR(waitpid)(child_pid, &status, 0), SyscallSucceeds());
   581    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == EAGAIN)
   582        << "Exited with code: " << status;
   583  
   584    // Close the fd: we want to test that another process can acquire the
   585    // lock after this point.
   586    fd.reset();
   587    // Assert that another process can now acquire the lock.
   588  
   589    child_pid = 0;
   590    auto cleanup2 = ASSERT_NO_ERRNO_AND_VALUE(SubprocessLock(
   591        file.path(), true /* write lock */, false /* nonblocking */,
   592        false /* no eintr retry */, nullptr /* no socket fd */, fl.l_start,
   593        fl.l_len, &child_pid));
   594    ASSERT_THAT(RetryEINTR(waitpid)(child_pid, &status, 0), SyscallSucceeds());
   595    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
   596        << "Exited with code: " << status;
   597  }
   598  
   599  TEST_F(FcntlLockTest, SetWriteThenReadLockMultiProc) {
   600    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
   601  
   602    FileDescriptor fd =
   603        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
   604    // Same as SetReadThenWriteLockMultiProc.
   605  
   606    struct flock fl;
   607    fl.l_type = F_WRLCK;
   608    fl.l_whence = SEEK_SET;
   609    fl.l_start = 0;
   610    // Same as SetLockBadFd.
   611    fl.l_len = 0;
   612  
   613    // Same as SetReadThenWriteLockMultiProc.
   614    EXPECT_THAT(fcntl(fd.get(), F_SETLK, &fl), SyscallSucceeds());
   615  
   616    // Same as SetReadThenWriteLockMultiProc.
   617    pid_t child_pid = 0;
   618    auto cleanup = ASSERT_NO_ERRNO_AND_VALUE(SubprocessLock(
   619        file.path(), false /* write lock */, false /* nonblocking */,
   620        false /* no eintr retry */, nullptr /* no socket fd */, fl.l_start,
   621        fl.l_len, &child_pid));
   622  
   623    int status = 0;
   624    ASSERT_THAT(RetryEINTR(waitpid)(child_pid, &status, 0), SyscallSucceeds());
   625    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == EAGAIN)
   626        << "Exited with code: " << status;
   627  
   628    // Same as SetReadThenWriteLockMultiProc.
   629    fd.reset();  // Close the fd.
   630  
   631    // Same as SetReadThenWriteLockMultiProc.
   632    child_pid = 0;
   633    auto cleanup2 = ASSERT_NO_ERRNO_AND_VALUE(SubprocessLock(
   634        file.path(), false /* write lock */, false /* nonblocking */,
   635        false /* no eintr retry */, nullptr /* no socket fd */, fl.l_start,
   636        fl.l_len, &child_pid));
   637    ASSERT_THAT(RetryEINTR(waitpid)(child_pid, &status, 0), SyscallSucceeds());
   638    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
   639        << "Exited with code: " << status;
   640  }
   641  
   642  TEST_F(FcntlLockTest, SetWriteLockMultiProc) {
   643    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
   644    FileDescriptor fd =
   645        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
   646    // Same as SetReadThenWriteLockMultiProc.
   647  
   648    struct flock fl;
   649    fl.l_type = F_WRLCK;
   650    fl.l_whence = SEEK_SET;
   651    fl.l_start = 0;
   652    // Same as SetLockBadFd.
   653    fl.l_len = 0;
   654  
   655    // Same as SetReadWriteLockMultiProc.
   656    EXPECT_THAT(fcntl(fd.get(), F_SETLK, &fl), SyscallSucceeds());
   657  
   658    // Same as SetReadWriteLockMultiProc.
   659    pid_t child_pid = 0;
   660    auto cleanup = ASSERT_NO_ERRNO_AND_VALUE(SubprocessLock(
   661        file.path(), true /* write lock */, false /* nonblocking */,
   662        false /* no eintr retry */, nullptr /* no socket fd */, fl.l_start,
   663        fl.l_len, &child_pid));
   664    int status = 0;
   665    ASSERT_THAT(RetryEINTR(waitpid)(child_pid, &status, 0), SyscallSucceeds());
   666    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == EAGAIN)
   667        << "Exited with code: " << status;
   668  
   669    fd.reset();  // Close the FD.
   670    // Same as SetReadWriteLockMultiProc.
   671    child_pid = 0;
   672    auto cleanup2 = ASSERT_NO_ERRNO_AND_VALUE(SubprocessLock(
   673        file.path(), true /* write lock */, false /* nonblocking */,
   674        false /* no eintr retry */, nullptr /* no socket fd */, fl.l_start,
   675        fl.l_len, &child_pid));
   676    ASSERT_THAT(RetryEINTR(waitpid)(child_pid, &status, 0), SyscallSucceeds());
   677    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
   678        << "Exited with code: " << status;
   679  }
   680  
   681  TEST_F(FcntlLockTest, SetLockIsRegional) {
   682    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
   683    FileDescriptor fd =
   684        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
   685  
   686    struct flock fl;
   687    fl.l_type = F_WRLCK;
   688    fl.l_whence = SEEK_SET;
   689    fl.l_start = 0;
   690    fl.l_len = 4096;
   691  
   692    // Same as SetReadWriteLockMultiProc.
   693    EXPECT_THAT(fcntl(fd.get(), F_SETLK, &fl), SyscallSucceeds());
   694  
   695    // Same as SetReadWriteLockMultiProc.
   696    pid_t child_pid = 0;
   697    auto cleanup = ASSERT_NO_ERRNO_AND_VALUE(
   698        SubprocessLock(file.path(), true /* write lock */,
   699                       false /* nonblocking */, false /* no eintr retry */,
   700                       nullptr /* no socket fd */, fl.l_len, 0, &child_pid));
   701    int status = 0;
   702    ASSERT_THAT(RetryEINTR(waitpid)(child_pid, &status, 0), SyscallSucceeds());
   703    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
   704        << "Exited with code: " << status;
   705  }
   706  
   707  TEST_F(FcntlLockTest, SetLockUpgradeDowngrade) {
   708    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
   709    FileDescriptor fd =
   710        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
   711  
   712    struct flock fl;
   713    fl.l_type = F_RDLCK;
   714    fl.l_whence = SEEK_SET;
   715    fl.l_start = 0;
   716    // Same as SetLockBadFd.
   717    fl.l_len = 0;
   718  
   719    // Same as SetReadWriteLockMultiProc.
   720    EXPECT_THAT(fcntl(fd.get(), F_SETLK, &fl), SyscallSucceeds());
   721  
   722    // Upgrade to a write lock.  This will prevent anyone else from taking
   723    // the lock.
   724    fl.l_type = F_WRLCK;
   725    EXPECT_THAT(fcntl(fd.get(), F_SETLK, &fl), SyscallSucceeds());
   726  
   727    // Same as SetReadWriteLockMultiProc.,
   728    pid_t child_pid = 0;
   729    auto cleanup = ASSERT_NO_ERRNO_AND_VALUE(SubprocessLock(
   730        file.path(), false /* write lock */, false /* nonblocking */,
   731        false /* no eintr retry */, nullptr /* no socket fd */, fl.l_start,
   732        fl.l_len, &child_pid));
   733  
   734    int status = 0;
   735    ASSERT_THAT(RetryEINTR(waitpid)(child_pid, &status, 0), SyscallSucceeds());
   736    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == EAGAIN)
   737        << "Exited with code: " << status;
   738  
   739    // Downgrade back to a read lock.
   740    fl.l_type = F_RDLCK;
   741    EXPECT_THAT(fcntl(fd.get(), F_SETLK, &fl), SyscallSucceeds());
   742  
   743    // Do the same stint as before, but this time it should succeed.
   744    child_pid = 0;
   745    auto cleanup2 = ASSERT_NO_ERRNO_AND_VALUE(SubprocessLock(
   746        file.path(), false /* write lock */, false /* nonblocking */,
   747        false /* no eintr retry */, nullptr /* no socket fd */, fl.l_start,
   748        fl.l_len, &child_pid));
   749  
   750    ASSERT_THAT(RetryEINTR(waitpid)(child_pid, &status, 0), SyscallSucceeds());
   751    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
   752        << "Exited with code: " << status;
   753  }
   754  
   755  TEST_F(FcntlLockTest, SetLockDroppedOnClose) {
   756    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
   757    FileDescriptor fd =
   758        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
   759  
   760    // While somewhat surprising, obtaining another fd to the same file and
   761    // then closing it in this process drops *all* locks.
   762    FileDescriptor other_fd =
   763        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
   764    // Same as SetReadThenWriteLockMultiProc.
   765  
   766    struct flock fl;
   767    fl.l_type = F_WRLCK;
   768    fl.l_whence = SEEK_SET;
   769    fl.l_start = 0;
   770    // Same as SetLockBadFd.
   771    fl.l_len = 0;
   772  
   773    // Same as SetReadWriteLockMultiProc.
   774    EXPECT_THAT(fcntl(fd.get(), F_SETLK, &fl), SyscallSucceeds());
   775  
   776    other_fd.reset();  // Close.
   777  
   778    // Expect to be able to get the lock, given that the close above dropped it.
   779    pid_t child_pid = 0;
   780    auto cleanup = ASSERT_NO_ERRNO_AND_VALUE(SubprocessLock(
   781        file.path(), true /* write lock */, false /* nonblocking */,
   782        false /* no eintr retry */, nullptr /* no socket fd */, fl.l_start,
   783        fl.l_len, &child_pid));
   784  
   785    int status = 0;
   786    ASSERT_THAT(RetryEINTR(waitpid)(child_pid, &status, 0), SyscallSucceeds());
   787    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
   788        << "Exited with code: " << status;
   789  }
   790  
   791  TEST_F(FcntlLockTest, SetLockUnlock) {
   792    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
   793    FileDescriptor fd =
   794        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
   795  
   796    // Setup two regional locks with different permissions.
   797    struct flock fl0;
   798    fl0.l_type = F_WRLCK;
   799    fl0.l_whence = SEEK_SET;
   800    fl0.l_start = 0;
   801    fl0.l_len = 4096;
   802  
   803    struct flock fl1;
   804    fl1.l_type = F_RDLCK;
   805    fl1.l_whence = SEEK_SET;
   806    fl1.l_start = 4096;
   807    // Same as SetLockBadFd.
   808    fl1.l_len = 0;
   809  
   810    // Set both region locks.
   811    EXPECT_THAT(fcntl(fd.get(), F_SETLK, &fl0), SyscallSucceeds());
   812    EXPECT_THAT(fcntl(fd.get(), F_SETLK, &fl1), SyscallSucceeds());
   813  
   814    // Another process should fail to take a read lock on the entire file
   815    // due to the regional write lock.
   816    pid_t child_pid = 0;
   817    auto cleanup = ASSERT_NO_ERRNO_AND_VALUE(
   818        SubprocessLock(file.path(), false /* write lock */,
   819                       false /* nonblocking */, false /* no eintr retry */,
   820                       nullptr /* no socket fd */, 0, 0, &child_pid));
   821  
   822    int status = 0;
   823    ASSERT_THAT(RetryEINTR(waitpid)(child_pid, &status, 0), SyscallSucceeds());
   824    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == EAGAIN)
   825        << "Exited with code: " << status;
   826  
   827    // Then only unlock the writable one.  This should ensure that other
   828    // processes can take any read lock that it wants.
   829    fl0.l_type = F_UNLCK;
   830    EXPECT_THAT(fcntl(fd.get(), F_SETLK, &fl0), SyscallSucceeds());
   831  
   832    // Another process should now succeed to get a read lock on the entire file.
   833    child_pid = 0;
   834    auto cleanup2 = ASSERT_NO_ERRNO_AND_VALUE(
   835        SubprocessLock(file.path(), false /* write lock */,
   836                       false /* nonblocking */, false /* no eintr retry */,
   837                       nullptr /* no socket fd */, 0, 0, &child_pid));
   838    ASSERT_THAT(RetryEINTR(waitpid)(child_pid, &status, 0), SyscallSucceeds());
   839    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
   840        << "Exited with code: " << status;
   841  }
   842  
   843  TEST_F(FcntlLockTest, SetLockAcrossRename) {
   844    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
   845    FileDescriptor fd =
   846        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
   847  
   848    // Setup two regional locks with different permissions.
   849    struct flock fl;
   850    fl.l_type = F_WRLCK;
   851    fl.l_whence = SEEK_SET;
   852    fl.l_start = 0;
   853    // Same as SetLockBadFd.
   854    fl.l_len = 0;
   855  
   856    // Set the region lock.
   857    EXPECT_THAT(fcntl(fd.get(), F_SETLK, &fl), SyscallSucceeds());
   858  
   859    // Rename the file to someplace nearby.
   860    std::string const newpath = NewTempAbsPath();
   861    EXPECT_THAT(rename(file.path().c_str(), newpath.c_str()), SyscallSucceeds());
   862  
   863    // Another process should fail to take a read lock on the renamed file
   864    // since we still have an open handle to the inode.
   865    pid_t child_pid = 0;
   866    auto cleanup = ASSERT_NO_ERRNO_AND_VALUE(
   867        SubprocessLock(newpath, false /* write lock */, false /* nonblocking */,
   868                       false /* no eintr retry */, nullptr /* no socket fd */,
   869                       fl.l_start, fl.l_len, &child_pid));
   870  
   871    int status = 0;
   872    ASSERT_THAT(RetryEINTR(waitpid)(child_pid, &status, 0), SyscallSucceeds());
   873    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == EAGAIN)
   874        << "Exited with code: " << status;
   875  }
   876  
   877  // NOTE: The blocking tests below aren't perfect. It's hard to assert exactly
   878  // what the kernel did while handling a syscall. These tests are timing based
   879  // because there really isn't any other reasonable way to assert that correct
   880  // blocking behavior happened.
   881  
   882  // This test will verify that blocking works as expected when another process
   883  // holds a write lock when obtaining a write lock. This test will hold the lock
   884  // for some amount of time and then wait for the second process to send over the
   885  // socket_fd the amount of time it was blocked for before the lock succeeded.
   886  TEST_F(FcntlLockTest, SetWriteLockThenBlockingWriteLock) {
   887    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
   888    FileDescriptor fd =
   889        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
   890  
   891    struct flock fl;
   892    fl.l_type = F_WRLCK;
   893    fl.l_whence = SEEK_SET;
   894    fl.l_start = 0;
   895    fl.l_len = 0;
   896  
   897    // Take the write lock.
   898    ASSERT_THAT(fcntl(fd.get(), F_SETLKW, &fl), SyscallSucceeds());
   899  
   900    // Attempt to take the read lock in a sub process. This will immediately block
   901    // so we will release our lock after some amount of time and then assert the
   902    // amount of time the other process was blocked for.
   903    pid_t child_pid = 0;
   904    auto cleanup = ASSERT_NO_ERRNO_AND_VALUE(SubprocessLock(
   905        file.path(), true /* write lock */, true /* Blocking Lock */,
   906        true /* Retry on EINTR */, fds_ /* Socket fd for timing information */,
   907        fl.l_start, fl.l_len, &child_pid));
   908  
   909    // We will wait kHoldLockForSec before we release our lock allowing the
   910    // subprocess to obtain it.
   911    constexpr absl::Duration kHoldLockFor = absl::Seconds(5);
   912    const int64_t kMinBlockTimeUsec = absl::ToInt64Microseconds(absl::Seconds(1));
   913  
   914    absl::SleepFor(kHoldLockFor);
   915  
   916    // Unlock our write lock.
   917    fl.l_type = F_UNLCK;
   918    ASSERT_THAT(fcntl(fd.get(), F_SETLKW, &fl), SyscallSucceeds());
   919  
   920    // Read the blocked time from the subprocess socket.
   921    int64_t subprocess_blocked_time_usec = GetSubprocessFcntlTimeInUsec();
   922  
   923    // We must have been waiting at least kMinBlockTime.
   924    EXPECT_GT(subprocess_blocked_time_usec, kMinBlockTimeUsec);
   925  
   926    // The FCNTL write lock must always succeed as it will simply block until it
   927    // can obtain the lock.
   928    int status = 0;
   929    ASSERT_THAT(RetryEINTR(waitpid)(child_pid, &status, 0), SyscallSucceeds());
   930    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
   931        << "Exited with code: " << status;
   932  }
   933  
   934  // This test will verify that blocking works as expected when another process
   935  // holds a read lock when obtaining a write lock. This test will hold the lock
   936  // for some amount of time and then wait for the second process to send over the
   937  // socket_fd the amount of time it was blocked for before the lock succeeded.
   938  TEST_F(FcntlLockTest, SetReadLockThenBlockingWriteLock) {
   939    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
   940    FileDescriptor fd =
   941        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
   942  
   943    struct flock fl;
   944    fl.l_type = F_RDLCK;
   945    fl.l_whence = SEEK_SET;
   946    fl.l_start = 0;
   947    fl.l_len = 0;
   948  
   949    // Take the write lock.
   950    ASSERT_THAT(fcntl(fd.get(), F_SETLKW, &fl), SyscallSucceeds());
   951  
   952    // Attempt to take the read lock in a sub process. This will immediately block
   953    // so we will release our lock after some amount of time and then assert the
   954    // amount of time the other process was blocked for.
   955    pid_t child_pid = 0;
   956    auto cleanup = ASSERT_NO_ERRNO_AND_VALUE(SubprocessLock(
   957        file.path(), true /* write lock */, true /* Blocking Lock */,
   958        true /* Retry on EINTR */, fds_ /* Socket fd for timing information */,
   959        fl.l_start, fl.l_len, &child_pid));
   960  
   961    // We will wait kHoldLockForSec before we release our lock allowing the
   962    // subprocess to obtain it.
   963    constexpr absl::Duration kHoldLockFor = absl::Seconds(5);
   964  
   965    const int64_t kMinBlockTimeUsec = absl::ToInt64Microseconds(absl::Seconds(1));
   966  
   967    absl::SleepFor(kHoldLockFor);
   968  
   969    // Unlock our READ lock.
   970    fl.l_type = F_UNLCK;
   971    ASSERT_THAT(fcntl(fd.get(), F_SETLKW, &fl), SyscallSucceeds());
   972  
   973    // Read the blocked time from the subprocess socket.
   974    int64_t subprocess_blocked_time_usec = GetSubprocessFcntlTimeInUsec();
   975  
   976    // We must have been waiting at least kMinBlockTime.
   977    EXPECT_GT(subprocess_blocked_time_usec, kMinBlockTimeUsec);
   978  
   979    // The FCNTL write lock must always succeed as it will simply block until it
   980    // can obtain the lock.
   981    int status = 0;
   982    ASSERT_THAT(RetryEINTR(waitpid)(child_pid, &status, 0), SyscallSucceeds());
   983    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
   984        << "Exited with code: " << status;
   985  }
   986  
   987  // This test will veirfy that blocking works as expected when another process
   988  // holds a write lock when obtaining a read lock. This test will hold the lock
   989  // for some amount of time and then wait for the second process to send over the
   990  // socket_fd the amount of time it was blocked for before the lock succeeded.
   991  TEST_F(FcntlLockTest, SetWriteLockThenBlockingReadLock) {
   992    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
   993    FileDescriptor fd =
   994        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
   995  
   996    struct flock fl;
   997    fl.l_type = F_WRLCK;
   998    fl.l_whence = SEEK_SET;
   999    fl.l_start = 0;
  1000    fl.l_len = 0;
  1001  
  1002    // Take the write lock.
  1003    ASSERT_THAT(fcntl(fd.get(), F_SETLKW, &fl), SyscallSucceeds());
  1004  
  1005    // Attempt to take the read lock in a sub process. This will immediately block
  1006    // so we will release our lock after some amount of time and then assert the
  1007    // amount of time the other process was blocked for.
  1008    pid_t child_pid = 0;
  1009    auto cleanup = ASSERT_NO_ERRNO_AND_VALUE(SubprocessLock(
  1010        file.path(), false /* read lock */, true /* Blocking Lock */,
  1011        true /* Retry on EINTR */, fds_ /* Socket fd for timing information */,
  1012        fl.l_start, fl.l_len, &child_pid));
  1013  
  1014    // We will wait kHoldLockForSec before we release our lock allowing the
  1015    // subprocess to obtain it.
  1016    constexpr absl::Duration kHoldLockFor = absl::Seconds(5);
  1017  
  1018    const int64_t kMinBlockTimeUsec = absl::ToInt64Microseconds(absl::Seconds(1));
  1019  
  1020    absl::SleepFor(kHoldLockFor);
  1021  
  1022    // Unlock our write lock.
  1023    fl.l_type = F_UNLCK;
  1024    ASSERT_THAT(fcntl(fd.get(), F_SETLKW, &fl), SyscallSucceeds());
  1025  
  1026    // Read the blocked time from the subprocess socket.
  1027    int64_t subprocess_blocked_time_usec = GetSubprocessFcntlTimeInUsec();
  1028  
  1029    // We must have been waiting at least kMinBlockTime.
  1030    EXPECT_GT(subprocess_blocked_time_usec, kMinBlockTimeUsec);
  1031  
  1032    // The FCNTL read lock must always succeed as it will simply block until it
  1033    // can obtain the lock.
  1034    int status = 0;
  1035    ASSERT_THAT(RetryEINTR(waitpid)(child_pid, &status, 0), SyscallSucceeds());
  1036    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
  1037        << "Exited with code: " << status;
  1038  }
  1039  
  1040  // This test will verify that when one process only holds a read lock that
  1041  // another will not block while obtaining a read lock when F_SETLKW is used.
  1042  TEST_F(FcntlLockTest, SetReadLockThenBlockingReadLock) {
  1043    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
  1044    FileDescriptor fd =
  1045        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
  1046  
  1047    struct flock fl;
  1048    fl.l_type = F_RDLCK;
  1049    fl.l_whence = SEEK_SET;
  1050    fl.l_start = 0;
  1051    fl.l_len = 0;
  1052  
  1053    // Take the READ lock.
  1054    ASSERT_THAT(fcntl(fd.get(), F_SETLKW, &fl), SyscallSucceeds());
  1055  
  1056    // Attempt to take the read lock in a sub process. Since multiple processes
  1057    // can hold a read lock this should immediately return without blocking
  1058    // even though we used F_SETLKW in the subprocess.
  1059    pid_t child_pid = 0;
  1060    auto sp = ASSERT_NO_ERRNO_AND_VALUE(SubprocessLock(
  1061        file.path(), false /* read lock */, true /* Blocking Lock */,
  1062        true /* Retry on EINTR */, nullptr /* No fd, should not block */,
  1063        fl.l_start, fl.l_len, &child_pid));
  1064  
  1065    // We never release the lock and the subprocess should still obtain it without
  1066    // blocking for any period of time.
  1067    int status = 0;
  1068    ASSERT_THAT(RetryEINTR(waitpid)(child_pid, &status, 0), SyscallSucceeds());
  1069    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0)
  1070        << "Exited with code: " << status;
  1071  }
  1072  
  1073  TEST(FcntlTest, GetO_ASYNC) {
  1074    FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(
  1075        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1076  
  1077    int flag_fl = -1;
  1078    ASSERT_THAT(flag_fl = fcntl(s.get(), F_GETFL), SyscallSucceeds());
  1079    EXPECT_EQ(flag_fl & O_ASYNC, 0);
  1080  
  1081    int flag_fd = -1;
  1082    ASSERT_THAT(flag_fd = fcntl(s.get(), F_GETFD), SyscallSucceeds());
  1083    EXPECT_EQ(flag_fd & O_ASYNC, 0);
  1084  }
  1085  
  1086  TEST(FcntlTest, SetFlO_ASYNC) {
  1087    FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(
  1088        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1089  
  1090    int before_fl = -1;
  1091    ASSERT_THAT(before_fl = fcntl(s.get(), F_GETFL), SyscallSucceeds());
  1092  
  1093    int before_fd = -1;
  1094    ASSERT_THAT(before_fd = fcntl(s.get(), F_GETFD), SyscallSucceeds());
  1095  
  1096    ASSERT_THAT(fcntl(s.get(), F_SETFL, before_fl | O_ASYNC), SyscallSucceeds());
  1097  
  1098    int after_fl = -1;
  1099    ASSERT_THAT(after_fl = fcntl(s.get(), F_GETFL), SyscallSucceeds());
  1100    EXPECT_EQ(after_fl, before_fl | O_ASYNC);
  1101  
  1102    int after_fd = -1;
  1103    ASSERT_THAT(after_fd = fcntl(s.get(), F_GETFD), SyscallSucceeds());
  1104    EXPECT_EQ(after_fd, before_fd);
  1105  }
  1106  
  1107  TEST(FcntlTest, SetFdO_ASYNC) {
  1108    FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(
  1109        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1110  
  1111    int before_fl = -1;
  1112    ASSERT_THAT(before_fl = fcntl(s.get(), F_GETFL), SyscallSucceeds());
  1113  
  1114    int before_fd = -1;
  1115    ASSERT_THAT(before_fd = fcntl(s.get(), F_GETFD), SyscallSucceeds());
  1116  
  1117    ASSERT_THAT(fcntl(s.get(), F_SETFD, before_fd | O_ASYNC), SyscallSucceeds());
  1118  
  1119    int after_fl = -1;
  1120    ASSERT_THAT(after_fl = fcntl(s.get(), F_GETFL), SyscallSucceeds());
  1121    EXPECT_EQ(after_fl, before_fl);
  1122  
  1123    int after_fd = -1;
  1124    ASSERT_THAT(after_fd = fcntl(s.get(), F_GETFD), SyscallSucceeds());
  1125    EXPECT_EQ(after_fd, before_fd);
  1126  }
  1127  
  1128  TEST(FcntlTest, DupAfterO_ASYNC) {
  1129    FileDescriptor s1 = ASSERT_NO_ERRNO_AND_VALUE(
  1130        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1131  
  1132    int before = -1;
  1133    ASSERT_THAT(before = fcntl(s1.get(), F_GETFL), SyscallSucceeds());
  1134  
  1135    ASSERT_THAT(fcntl(s1.get(), F_SETFL, before | O_ASYNC), SyscallSucceeds());
  1136  
  1137    FileDescriptor fd2 = ASSERT_NO_ERRNO_AND_VALUE(s1.Dup());
  1138  
  1139    int after = -1;
  1140    ASSERT_THAT(after = fcntl(fd2.get(), F_GETFL), SyscallSucceeds());
  1141    EXPECT_EQ(after & O_ASYNC, O_ASYNC);
  1142  }
  1143  
  1144  TEST(FcntlTest, GetOwnNone) {
  1145    FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(
  1146        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1147  
  1148    // Use the raw syscall because the glibc wrapper may convert F_{GET,SET}OWN
  1149    // into F_{GET,SET}OWN_EX.
  1150    EXPECT_THAT(syscall(__NR_fcntl, s.get(), F_GETOWN),
  1151                SyscallSucceedsWithValue(0));
  1152  }
  1153  
  1154  TEST(FcntlTest, GetOwnExNone) {
  1155    FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(
  1156        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1157  
  1158    f_owner_ex owner = {};
  1159    EXPECT_THAT(syscall(__NR_fcntl, s.get(), F_GETOWN_EX, &owner),
  1160                SyscallSucceedsWithValue(0));
  1161  }
  1162  
  1163  TEST(FcntlTest, SetOwnInvalidPid) {
  1164    FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(
  1165        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1166  
  1167    EXPECT_THAT(syscall(__NR_fcntl, s.get(), F_SETOWN, 12345678),
  1168                SyscallFailsWithErrno(ESRCH));
  1169  }
  1170  
  1171  TEST(FcntlTest, SetOwnInvalidPgrp) {
  1172    FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(
  1173        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1174  
  1175    EXPECT_THAT(syscall(__NR_fcntl, s.get(), F_SETOWN, -12345678),
  1176                SyscallFailsWithErrno(ESRCH));
  1177  }
  1178  
  1179  TEST(FcntlTest, SetOwnPid) {
  1180    FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(
  1181        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1182  
  1183    pid_t pid;
  1184    EXPECT_THAT(pid = getpid(), SyscallSucceeds());
  1185  
  1186    ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_SETOWN, pid),
  1187                SyscallSucceedsWithValue(0));
  1188  
  1189    EXPECT_THAT(syscall(__NR_fcntl, s.get(), F_GETOWN),
  1190                SyscallSucceedsWithValue(pid));
  1191  }
  1192  
  1193  TEST(FcntlTest, SetOwnPgrp) {
  1194    FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(
  1195        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1196  
  1197    pid_t pgid;
  1198    EXPECT_THAT(pgid = getpgrp(), SyscallSucceeds());
  1199  
  1200    ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_SETOWN, -pgid),
  1201                SyscallSucceedsWithValue(0));
  1202  
  1203    // Verify with F_GETOWN_EX; using F_GETOWN on Linux may incorrectly treat the
  1204    // negative return value as an error, converting the return value to -1 and
  1205    // setting errno accordingly.
  1206    f_owner_ex got_owner = {};
  1207    ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_GETOWN_EX, &got_owner),
  1208                SyscallSucceedsWithValue(0));
  1209    EXPECT_EQ(got_owner.type, F_OWNER_PGRP);
  1210    EXPECT_EQ(got_owner.pid, pgid);
  1211  }
  1212  
  1213  TEST(FcntlTest, SetOwnUnset) {
  1214    FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(
  1215        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1216  
  1217    // Set and unset pid.
  1218    pid_t pid;
  1219    EXPECT_THAT(pid = getpid(), SyscallSucceeds());
  1220    ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_SETOWN, pid),
  1221                SyscallSucceedsWithValue(0));
  1222    ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_SETOWN, 0),
  1223                SyscallSucceedsWithValue(0));
  1224  
  1225    EXPECT_THAT(syscall(__NR_fcntl, s.get(), F_GETOWN),
  1226                SyscallSucceedsWithValue(0));
  1227  
  1228    // Set and unset pgid.
  1229    pid_t pgid;
  1230    EXPECT_THAT(pgid = getpgrp(), SyscallSucceeds());
  1231    ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_SETOWN, -pgid),
  1232                SyscallSucceedsWithValue(0));
  1233    ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_SETOWN, 0),
  1234                SyscallSucceedsWithValue(0));
  1235  
  1236    EXPECT_THAT(syscall(__NR_fcntl, s.get(), F_GETOWN),
  1237                SyscallSucceedsWithValue(0));
  1238  }
  1239  
  1240  // F_SETOWN flips the sign of negative values, an operation that is guarded
  1241  // against overflow.
  1242  TEST(FcntlTest, SetOwnOverflow) {
  1243    FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(
  1244        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1245  
  1246    EXPECT_THAT(syscall(__NR_fcntl, s.get(), F_SETOWN, INT_MIN),
  1247                SyscallFailsWithErrno(EINVAL));
  1248  }
  1249  
  1250  TEST(FcntlTest, SetOwnExInvalidType) {
  1251    FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(
  1252        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1253  
  1254    f_owner_ex owner = {};
  1255    owner.type = static_cast<decltype(owner.type)>(-1);
  1256    EXPECT_THAT(syscall(__NR_fcntl, s.get(), F_SETOWN_EX, &owner),
  1257                SyscallFailsWithErrno(EINVAL));
  1258  }
  1259  
  1260  TEST(FcntlTest, SetOwnExInvalidTid) {
  1261    FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(
  1262        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1263  
  1264    f_owner_ex owner = {};
  1265    owner.type = F_OWNER_TID;
  1266    owner.pid = -1;
  1267  
  1268    EXPECT_THAT(syscall(__NR_fcntl, s.get(), F_SETOWN_EX, &owner),
  1269                SyscallFailsWithErrno(ESRCH));
  1270  }
  1271  
  1272  TEST(FcntlTest, SetOwnExInvalidPid) {
  1273    FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(
  1274        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1275  
  1276    f_owner_ex owner = {};
  1277    owner.type = F_OWNER_PID;
  1278    owner.pid = -1;
  1279  
  1280    EXPECT_THAT(syscall(__NR_fcntl, s.get(), F_SETOWN_EX, &owner),
  1281                SyscallFailsWithErrno(ESRCH));
  1282  }
  1283  
  1284  TEST(FcntlTest, SetOwnExInvalidPgrp) {
  1285    FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(
  1286        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1287  
  1288    f_owner_ex owner = {};
  1289    owner.type = F_OWNER_PGRP;
  1290    owner.pid = -1;
  1291  
  1292    EXPECT_THAT(syscall(__NR_fcntl, s.get(), F_SETOWN_EX, &owner),
  1293                SyscallFailsWithErrno(ESRCH));
  1294  }
  1295  
  1296  TEST(FcntlTest, SetOwnExTid) {
  1297    FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(
  1298        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1299  
  1300    f_owner_ex owner = {};
  1301    owner.type = F_OWNER_TID;
  1302    EXPECT_THAT(owner.pid = syscall(__NR_gettid), SyscallSucceeds());
  1303  
  1304    ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_SETOWN_EX, &owner),
  1305                SyscallSucceedsWithValue(0));
  1306  
  1307    EXPECT_THAT(syscall(__NR_fcntl, s.get(), F_GETOWN),
  1308                SyscallSucceedsWithValue(owner.pid));
  1309  }
  1310  
  1311  TEST(FcntlTest, SetOwnExPid) {
  1312    FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(
  1313        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1314  
  1315    f_owner_ex owner = {};
  1316    owner.type = F_OWNER_PID;
  1317    EXPECT_THAT(owner.pid = getpid(), SyscallSucceeds());
  1318  
  1319    ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_SETOWN_EX, &owner),
  1320                SyscallSucceedsWithValue(0));
  1321  
  1322    EXPECT_THAT(syscall(__NR_fcntl, s.get(), F_GETOWN),
  1323                SyscallSucceedsWithValue(owner.pid));
  1324  }
  1325  
  1326  TEST(FcntlTest, SetOwnExPgrp) {
  1327    FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(
  1328        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1329  
  1330    f_owner_ex set_owner = {};
  1331    set_owner.type = F_OWNER_PGRP;
  1332    EXPECT_THAT(set_owner.pid = getpgrp(), SyscallSucceeds());
  1333  
  1334    ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_SETOWN_EX, &set_owner),
  1335                SyscallSucceedsWithValue(0));
  1336  
  1337    // Verify with F_GETOWN_EX; using F_GETOWN on Linux may incorrectly treat the
  1338    // negative return value as an error, converting the return value to -1 and
  1339    // setting errno accordingly.
  1340    f_owner_ex got_owner = {};
  1341    ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_GETOWN_EX, &got_owner),
  1342                SyscallSucceedsWithValue(0));
  1343    EXPECT_EQ(got_owner.type, set_owner.type);
  1344    EXPECT_EQ(got_owner.pid, set_owner.pid);
  1345  }
  1346  
  1347  TEST(FcntlTest, SetOwnExUnset) {
  1348    FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(
  1349        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1350  
  1351    // Set and unset pid.
  1352    f_owner_ex owner = {};
  1353    owner.type = F_OWNER_PID;
  1354    EXPECT_THAT(owner.pid = getpid(), SyscallSucceeds());
  1355    ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_SETOWN_EX, &owner),
  1356                SyscallSucceedsWithValue(0));
  1357    owner.pid = 0;
  1358    ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_SETOWN_EX, &owner),
  1359                SyscallSucceedsWithValue(0));
  1360  
  1361    EXPECT_THAT(syscall(__NR_fcntl, s.get(), F_GETOWN),
  1362                SyscallSucceedsWithValue(0));
  1363  
  1364    // Set and unset pgid.
  1365    owner.type = F_OWNER_PGRP;
  1366    EXPECT_THAT(owner.pid = getpgrp(), SyscallSucceeds());
  1367    ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_SETOWN_EX, &owner),
  1368                SyscallSucceedsWithValue(0));
  1369    owner.pid = 0;
  1370    ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_SETOWN_EX, &owner),
  1371                SyscallSucceedsWithValue(0));
  1372  
  1373    EXPECT_THAT(syscall(__NR_fcntl, s.get(), F_GETOWN),
  1374                SyscallSucceedsWithValue(0));
  1375  }
  1376  
  1377  TEST(FcntlTest, GetOwnExTid) {
  1378    FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(
  1379        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1380  
  1381    f_owner_ex set_owner = {};
  1382    set_owner.type = F_OWNER_TID;
  1383    EXPECT_THAT(set_owner.pid = syscall(__NR_gettid), SyscallSucceeds());
  1384  
  1385    ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_SETOWN_EX, &set_owner),
  1386                SyscallSucceedsWithValue(0));
  1387  
  1388    f_owner_ex got_owner = {};
  1389    ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_GETOWN_EX, &got_owner),
  1390                SyscallSucceedsWithValue(0));
  1391    EXPECT_EQ(got_owner.type, set_owner.type);
  1392    EXPECT_EQ(got_owner.pid, set_owner.pid);
  1393  }
  1394  
  1395  TEST(FcntlTest, GetOwnExPid) {
  1396    FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(
  1397        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1398  
  1399    f_owner_ex set_owner = {};
  1400    set_owner.type = F_OWNER_PID;
  1401    EXPECT_THAT(set_owner.pid = getpid(), SyscallSucceeds());
  1402  
  1403    ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_SETOWN_EX, &set_owner),
  1404                SyscallSucceedsWithValue(0));
  1405  
  1406    f_owner_ex got_owner = {};
  1407    ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_GETOWN_EX, &got_owner),
  1408                SyscallSucceedsWithValue(0));
  1409    EXPECT_EQ(got_owner.type, set_owner.type);
  1410    EXPECT_EQ(got_owner.pid, set_owner.pid);
  1411  }
  1412  
  1413  TEST(FcntlTest, GetOwnExPgrp) {
  1414    FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(
  1415        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1416  
  1417    f_owner_ex set_owner = {};
  1418    set_owner.type = F_OWNER_PGRP;
  1419    EXPECT_THAT(set_owner.pid = getpgrp(), SyscallSucceeds());
  1420  
  1421    ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_SETOWN_EX, &set_owner),
  1422                SyscallSucceedsWithValue(0));
  1423  
  1424    f_owner_ex got_owner = {};
  1425    ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_GETOWN_EX, &got_owner),
  1426                SyscallSucceedsWithValue(0));
  1427    EXPECT_EQ(got_owner.type, set_owner.type);
  1428    EXPECT_EQ(got_owner.pid, set_owner.pid);
  1429  }
  1430  
  1431  TEST(FcntlTest, SetSig) {
  1432    FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(
  1433        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1434  
  1435    ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_SETSIG, SIGUSR1),
  1436                SyscallSucceedsWithValue(0));
  1437    EXPECT_THAT(syscall(__NR_fcntl, s.get(), F_GETSIG),
  1438                SyscallSucceedsWithValue(SIGUSR1));
  1439  }
  1440  
  1441  TEST(FcntlTest, SetSigDefaultsToZero) {
  1442    FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(
  1443        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1444  
  1445    // Defaults to returning the zero value, indicating default behavior (SIGIO).
  1446    EXPECT_THAT(syscall(__NR_fcntl, s.get(), F_GETSIG),
  1447                SyscallSucceedsWithValue(0));
  1448  }
  1449  
  1450  TEST(FcntlTest, SetSigToDefault) {
  1451    FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(
  1452        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1453  
  1454    ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_SETSIG, SIGIO),
  1455                SyscallSucceedsWithValue(0));
  1456    ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_GETSIG),
  1457                SyscallSucceedsWithValue(SIGIO));
  1458  
  1459    // Can be reset to the default behavior.
  1460    ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_SETSIG, 0),
  1461                SyscallSucceedsWithValue(0));
  1462    EXPECT_THAT(syscall(__NR_fcntl, s.get(), F_GETSIG),
  1463                SyscallSucceedsWithValue(0));
  1464  }
  1465  
  1466  TEST(FcntlTest, SetSigInvalid) {
  1467    FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(
  1468        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1469  
  1470    ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_SETSIG, SIGRTMAX + 1),
  1471                SyscallFailsWithErrno(EINVAL));
  1472    EXPECT_THAT(syscall(__NR_fcntl, s.get(), F_GETSIG),
  1473                SyscallSucceedsWithValue(0));
  1474  }
  1475  
  1476  TEST(FcntlTest, SetSigInvalidDoesNotResetPreviousChoice) {
  1477    FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(
  1478        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1479  
  1480    ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_SETSIG, SIGUSR1),
  1481                SyscallSucceedsWithValue(0));
  1482    ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_SETSIG, SIGRTMAX + 1),
  1483                SyscallFailsWithErrno(EINVAL));
  1484    EXPECT_THAT(syscall(__NR_fcntl, s.get(), F_GETSIG),
  1485                SyscallSucceedsWithValue(SIGUSR1));
  1486  }
  1487  
  1488  TEST_F(FcntlSignalTest, SetSigDefault) {
  1489    const auto signal_cleanup =
  1490        ASSERT_NO_ERRNO_AND_VALUE(RegisterSignalHandler(SIGIO));
  1491    RegisterFD(pipe_read_fd_, 0);  // Zero = default behavior
  1492    GenerateIOEvent();
  1493    WaitForSignalDelivery(absl::Seconds(1));
  1494    ASSERT_EQ(num_signals_received_, 1);
  1495    SignalDelivery sig = signals_received_.front();
  1496    signals_received_.pop_front();
  1497    EXPECT_EQ(sig.num, SIGIO);
  1498    EXPECT_EQ(sig.info.si_signo, SIGIO);
  1499    // siginfo contents is undefined in this case.
  1500  }
  1501  
  1502  TEST_F(FcntlSignalTest, SignalFD) {
  1503    // Create the signalfd.
  1504    sigset_t mask;
  1505    sigemptyset(&mask);
  1506    sigaddset(&mask, SIGIO);
  1507    FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(NewSignalFD(&mask, 0));
  1508    const auto signal_cleanup =
  1509        ASSERT_NO_ERRNO_AND_VALUE(RegisterSignalHandler(SIGIO));
  1510    RegisterFD(fd.get(), 0);
  1511    int tid = syscall(SYS_gettid);
  1512    syscall(SYS_tkill, tid, SIGIO);
  1513  }
  1514  
  1515  TEST_F(FcntlSignalTest, SignalFDSetSigAfterASYNC) {
  1516    // Create the signalfd.
  1517    sigset_t mask;
  1518    sigemptyset(&mask);
  1519    sigaddset(&mask, SIGIO);
  1520    FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(NewSignalFD(&mask, 0));
  1521  
  1522    const auto signal_cleanup =
  1523        ASSERT_NO_ERRNO_AND_VALUE(RegisterSignalHandler(SIGIO));
  1524    ASSERT_THAT(fcntl(fd.get(), F_SETOWN, getpid()), SyscallSucceeds());
  1525    int old_flags;
  1526    ASSERT_THAT(old_flags = fcntl(fd.get(), F_GETFL), SyscallSucceeds());
  1527    ASSERT_THAT(fcntl(fd.get(), F_SETFL, old_flags | O_ASYNC), SyscallSucceeds());
  1528    ASSERT_THAT(fcntl(fd.get(), F_SETSIG, 0), SyscallSucceeds());
  1529  
  1530    int tid = syscall(SYS_gettid);
  1531    syscall(SYS_tkill, tid, SIGIO);
  1532  }
  1533  
  1534  TEST_F(FcntlSignalTest, SetSigCustom) {
  1535    const auto signal_cleanup =
  1536        ASSERT_NO_ERRNO_AND_VALUE(RegisterSignalHandler(SIGUSR1));
  1537    RegisterFD(pipe_read_fd_, SIGUSR1);
  1538    GenerateIOEvent();
  1539    WaitForSignalDelivery(absl::Seconds(1));
  1540    ASSERT_EQ(num_signals_received_, 1);
  1541    SignalDelivery sig = signals_received_.front();
  1542    signals_received_.pop_front();
  1543    EXPECT_EQ(sig.num, SIGUSR1);
  1544    EXPECT_EQ(sig.info.si_signo, SIGUSR1);
  1545    EXPECT_EQ(sig.info.si_fd, pipe_read_fd_);
  1546    EXPECT_EQ(sig.info.si_band, EPOLLIN | EPOLLRDNORM);
  1547  }
  1548  
  1549  TEST_F(FcntlSignalTest, SetSigUnregisterStillGetsSigio) {
  1550    const auto sigio_cleanup =
  1551        ASSERT_NO_ERRNO_AND_VALUE(RegisterSignalHandler(SIGIO));
  1552    const auto sigusr1_cleanup =
  1553        ASSERT_NO_ERRNO_AND_VALUE(RegisterSignalHandler(SIGUSR1));
  1554    RegisterFD(pipe_read_fd_, SIGUSR1);
  1555    RegisterFD(pipe_read_fd_, 0);
  1556    GenerateIOEvent();
  1557    WaitForSignalDelivery(absl::Seconds(1));
  1558    ASSERT_EQ(num_signals_received_, 1);
  1559    SignalDelivery sig = signals_received_.front();
  1560    signals_received_.pop_front();
  1561    EXPECT_EQ(sig.num, SIGIO);
  1562    // siginfo contents is undefined in this case.
  1563  }
  1564  
  1565  TEST_F(FcntlSignalTest, SetSigWithSigioStillGetsSiginfo) {
  1566    const auto signal_cleanup =
  1567        ASSERT_NO_ERRNO_AND_VALUE(RegisterSignalHandler(SIGIO));
  1568    RegisterFD(pipe_read_fd_, SIGIO);
  1569    GenerateIOEvent();
  1570    WaitForSignalDelivery(absl::Seconds(1));
  1571    ASSERT_EQ(num_signals_received_, 1);
  1572    SignalDelivery sig = signals_received_.front();
  1573    EXPECT_EQ(sig.num, SIGIO);
  1574    EXPECT_EQ(sig.info.si_signo, SIGIO);
  1575    EXPECT_EQ(sig.info.si_fd, pipe_read_fd_);
  1576    EXPECT_EQ(sig.info.si_band, EPOLLIN | EPOLLRDNORM);
  1577  }
  1578  
  1579  TEST_F(FcntlSignalTest, SetSigDupThenCloseOld) {
  1580    const auto sigusr1_cleanup =
  1581        ASSERT_NO_ERRNO_AND_VALUE(RegisterSignalHandler(SIGUSR1));
  1582    RegisterFD(pipe_read_fd_, SIGUSR1);
  1583    DupReadFD();
  1584    FlushAndCloseFD(pipe_read_fd_);
  1585    GenerateIOEvent();
  1586    WaitForSignalDelivery(absl::Seconds(1));
  1587    ASSERT_EQ(num_signals_received_, 1);
  1588    SignalDelivery sig = signals_received_.front();
  1589    // We get a signal with the **old** FD (even though it is closed).
  1590    EXPECT_EQ(sig.num, SIGUSR1);
  1591    EXPECT_EQ(sig.info.si_signo, SIGUSR1);
  1592    EXPECT_EQ(sig.info.si_fd, pipe_read_fd_);
  1593    EXPECT_EQ(sig.info.si_band, EPOLLIN | EPOLLRDNORM);
  1594  }
  1595  
  1596  TEST_F(FcntlSignalTest, SetSigDupThenCloseNew) {
  1597    const auto sigusr1_cleanup =
  1598        ASSERT_NO_ERRNO_AND_VALUE(RegisterSignalHandler(SIGUSR1));
  1599    RegisterFD(pipe_read_fd_, SIGUSR1);
  1600    DupReadFD();
  1601    FlushAndCloseFD(pipe_read_fd_dup_);
  1602    GenerateIOEvent();
  1603    WaitForSignalDelivery(absl::Seconds(1));
  1604    ASSERT_EQ(num_signals_received_, 1);
  1605    SignalDelivery sig = signals_received_.front();
  1606    // We get a signal with the old FD.
  1607    EXPECT_EQ(sig.num, SIGUSR1);
  1608    EXPECT_EQ(sig.info.si_signo, SIGUSR1);
  1609    EXPECT_EQ(sig.info.si_fd, pipe_read_fd_);
  1610    EXPECT_EQ(sig.info.si_band, EPOLLIN | EPOLLRDNORM);
  1611  }
  1612  
  1613  TEST_F(FcntlSignalTest, SetSigDupOldRegistered) {
  1614    const auto sigusr1_cleanup =
  1615        ASSERT_NO_ERRNO_AND_VALUE(RegisterSignalHandler(SIGUSR1));
  1616    RegisterFD(pipe_read_fd_, SIGUSR1);
  1617    DupReadFD();
  1618    GenerateIOEvent();
  1619    WaitForSignalDelivery(absl::Seconds(1));
  1620    ASSERT_EQ(num_signals_received_, 1);
  1621    SignalDelivery sig = signals_received_.front();
  1622    // We get a signal with the old FD.
  1623    EXPECT_EQ(sig.num, SIGUSR1);
  1624    EXPECT_EQ(sig.info.si_signo, SIGUSR1);
  1625    EXPECT_EQ(sig.info.si_fd, pipe_read_fd_);
  1626    EXPECT_EQ(sig.info.si_band, EPOLLIN | EPOLLRDNORM);
  1627  }
  1628  
  1629  TEST_F(FcntlSignalTest, SetSigDupNewRegistered) {
  1630    const auto sigusr2_cleanup =
  1631        ASSERT_NO_ERRNO_AND_VALUE(RegisterSignalHandler(SIGUSR2));
  1632    DupReadFD();
  1633    RegisterFD(pipe_read_fd_dup_, SIGUSR2);
  1634    GenerateIOEvent();
  1635    WaitForSignalDelivery(absl::Seconds(1));
  1636    ASSERT_EQ(num_signals_received_, 1);
  1637    SignalDelivery sig = signals_received_.front();
  1638    // We get a signal with the new FD.
  1639    EXPECT_EQ(sig.num, SIGUSR2);
  1640    EXPECT_EQ(sig.info.si_signo, SIGUSR2);
  1641    EXPECT_EQ(sig.info.si_fd, pipe_read_fd_dup_);
  1642    EXPECT_EQ(sig.info.si_band, EPOLLIN | EPOLLRDNORM);
  1643  }
  1644  
  1645  TEST_F(FcntlSignalTest, SetSigDupBothRegistered) {
  1646    const auto sigusr1_cleanup =
  1647        ASSERT_NO_ERRNO_AND_VALUE(RegisterSignalHandler(SIGUSR1));
  1648    const auto sigusr2_cleanup =
  1649        ASSERT_NO_ERRNO_AND_VALUE(RegisterSignalHandler(SIGUSR2));
  1650    RegisterFD(pipe_read_fd_, SIGUSR1);
  1651    DupReadFD();
  1652    RegisterFD(pipe_read_fd_dup_, SIGUSR2);
  1653    GenerateIOEvent();
  1654    WaitForSignalDelivery(absl::Seconds(1));
  1655    ASSERT_EQ(num_signals_received_, 1);
  1656    SignalDelivery sig = signals_received_.front();
  1657    // We get a signal with the **new** signal number, but the **old** FD.
  1658    EXPECT_EQ(sig.num, SIGUSR2);
  1659    EXPECT_EQ(sig.info.si_signo, SIGUSR2);
  1660    EXPECT_EQ(sig.info.si_fd, pipe_read_fd_);
  1661    EXPECT_EQ(sig.info.si_band, EPOLLIN | EPOLLRDNORM);
  1662  }
  1663  
  1664  TEST_F(FcntlSignalTest, SetSigDupBothRegisteredAfterDup) {
  1665    const auto sigusr1_cleanup =
  1666        ASSERT_NO_ERRNO_AND_VALUE(RegisterSignalHandler(SIGUSR1));
  1667    const auto sigusr2_cleanup =
  1668        ASSERT_NO_ERRNO_AND_VALUE(RegisterSignalHandler(SIGUSR2));
  1669    DupReadFD();
  1670    RegisterFD(pipe_read_fd_, SIGUSR1);
  1671    RegisterFD(pipe_read_fd_dup_, SIGUSR2);
  1672    GenerateIOEvent();
  1673    WaitForSignalDelivery(absl::Seconds(1));
  1674    ASSERT_EQ(num_signals_received_, 1);
  1675    SignalDelivery sig = signals_received_.front();
  1676    // We get a signal with the **new** signal number, but the **old** FD.
  1677    EXPECT_EQ(sig.num, SIGUSR2);
  1678    EXPECT_EQ(sig.info.si_signo, SIGUSR2);
  1679    EXPECT_EQ(sig.info.si_fd, pipe_read_fd_);
  1680    EXPECT_EQ(sig.info.si_band, EPOLLIN | EPOLLRDNORM);
  1681  }
  1682  
  1683  TEST_F(FcntlSignalTest, SetSigDupUnregisterOld) {
  1684    const auto sigio_cleanup =
  1685        ASSERT_NO_ERRNO_AND_VALUE(RegisterSignalHandler(SIGIO));
  1686    const auto sigusr1_cleanup =
  1687        ASSERT_NO_ERRNO_AND_VALUE(RegisterSignalHandler(SIGUSR1));
  1688    const auto sigusr2_cleanup =
  1689        ASSERT_NO_ERRNO_AND_VALUE(RegisterSignalHandler(SIGUSR2));
  1690    RegisterFD(pipe_read_fd_, SIGUSR1);
  1691    DupReadFD();
  1692    RegisterFD(pipe_read_fd_dup_, SIGUSR2);
  1693    RegisterFD(pipe_read_fd_, 0);  // Should go back to SIGIO behavior.
  1694    GenerateIOEvent();
  1695    WaitForSignalDelivery(absl::Seconds(1));
  1696    ASSERT_EQ(num_signals_received_, 1);
  1697    SignalDelivery sig = signals_received_.front();
  1698    // We get a signal with SIGIO.
  1699    EXPECT_EQ(sig.num, SIGIO);
  1700    // siginfo is undefined in this case.
  1701  }
  1702  
  1703  TEST_F(FcntlSignalTest, SetSigDupUnregisterNew) {
  1704    const auto sigio_cleanup =
  1705        ASSERT_NO_ERRNO_AND_VALUE(RegisterSignalHandler(SIGIO));
  1706    const auto sigusr1_cleanup =
  1707        ASSERT_NO_ERRNO_AND_VALUE(RegisterSignalHandler(SIGUSR1));
  1708    const auto sigusr2_cleanup =
  1709        ASSERT_NO_ERRNO_AND_VALUE(RegisterSignalHandler(SIGUSR2));
  1710    RegisterFD(pipe_read_fd_, SIGUSR1);
  1711    DupReadFD();
  1712    RegisterFD(pipe_read_fd_dup_, SIGUSR2);
  1713    RegisterFD(pipe_read_fd_dup_, 0);  // Should go back to SIGIO behavior.
  1714    GenerateIOEvent();
  1715    WaitForSignalDelivery(absl::Seconds(1));
  1716    ASSERT_EQ(num_signals_received_, 1);
  1717    SignalDelivery sig = signals_received_.front();
  1718    // We get a signal with SIGIO.
  1719    EXPECT_EQ(sig.num, SIGIO);
  1720    // siginfo is undefined in this case.
  1721  }
  1722  
  1723  // Make sure that making multiple concurrent changes to async signal generation
  1724  // does not cause any race issues.
  1725  TEST(FcntlTest, SetFlSetOwnSetSigDoNotRace) {
  1726    FileDescriptor s = ASSERT_NO_ERRNO_AND_VALUE(
  1727        Socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0));
  1728  
  1729    pid_t pid;
  1730    EXPECT_THAT(pid = getpid(), SyscallSucceeds());
  1731  
  1732    constexpr absl::Duration runtime = absl::Milliseconds(300);
  1733    auto set_async = [&s, &runtime] {
  1734      for (auto start = absl::Now(); absl::Now() - start < runtime;) {
  1735        ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_SETFL, O_ASYNC),
  1736                    SyscallSucceeds());
  1737        sched_yield();
  1738      }
  1739    };
  1740    auto reset_async = [&s, &runtime] {
  1741      for (auto start = absl::Now(); absl::Now() - start < runtime;) {
  1742        ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_SETFL, 0), SyscallSucceeds());
  1743        sched_yield();
  1744      }
  1745    };
  1746    auto set_own = [&s, &pid, &runtime] {
  1747      for (auto start = absl::Now(); absl::Now() - start < runtime;) {
  1748        ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_SETOWN, pid),
  1749                    SyscallSucceeds());
  1750        sched_yield();
  1751      }
  1752    };
  1753    auto set_sig = [&s, &runtime] {
  1754      for (auto start = absl::Now(); absl::Now() - start < runtime;) {
  1755        ASSERT_THAT(syscall(__NR_fcntl, s.get(), F_SETSIG, SIGUSR1),
  1756                    SyscallSucceeds());
  1757        sched_yield();
  1758      }
  1759    };
  1760  
  1761    std::list<ScopedThread> threads;
  1762    for (int i = 0; i < 10; i++) {
  1763      threads.emplace_back(set_async);
  1764      threads.emplace_back(reset_async);
  1765      threads.emplace_back(set_own);
  1766      threads.emplace_back(set_sig);
  1767    }
  1768  }
  1769  
  1770  TEST_F(FcntlLockTest, GetLockOnNothing) {
  1771    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
  1772    FileDescriptor fd =
  1773        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
  1774  
  1775    struct flock fl;
  1776    fl.l_type = F_RDLCK;
  1777    fl.l_whence = SEEK_SET;
  1778    fl.l_start = 0;
  1779    fl.l_len = 40;
  1780    ASSERT_THAT(fcntl(fd.get(), F_GETLK, &fl), SyscallSucceeds());
  1781    ASSERT_TRUE(fl.l_type == F_UNLCK);
  1782  }
  1783  
  1784  TEST_F(FcntlLockTest, GetLockOnLockSameProcess) {
  1785    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
  1786    FileDescriptor fd =
  1787        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
  1788  
  1789    struct flock fl;
  1790    fl.l_type = F_RDLCK;
  1791    fl.l_whence = SEEK_SET;
  1792    fl.l_start = 0;
  1793    fl.l_len = 40;
  1794    ASSERT_THAT(fcntl(fd.get(), F_SETLK, &fl), SyscallSucceeds());
  1795    ASSERT_THAT(fcntl(fd.get(), F_GETLK, &fl), SyscallSucceeds());
  1796    ASSERT_TRUE(fl.l_type == F_UNLCK);
  1797  
  1798    fl.l_type = F_WRLCK;
  1799    ASSERT_THAT(fcntl(fd.get(), F_SETLK, &fl), SyscallSucceeds());
  1800    ASSERT_THAT(fcntl(fd.get(), F_GETLK, &fl), SyscallSucceeds());
  1801    ASSERT_TRUE(fl.l_type == F_UNLCK);
  1802  }
  1803  
  1804  TEST_F(FcntlLockTest, GetReadLockOnReadLock) {
  1805    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
  1806    FileDescriptor fd =
  1807        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
  1808  
  1809    struct flock fl;
  1810    fl.l_type = F_RDLCK;
  1811    fl.l_whence = SEEK_SET;
  1812    fl.l_start = 0;
  1813    fl.l_len = 40;
  1814    ASSERT_THAT(fcntl(fd.get(), F_SETLK, &fl), SyscallSucceeds());
  1815  
  1816    pid_t child_pid = fork();
  1817    if (child_pid == 0) {
  1818      TEST_CHECK(fcntl(fd.get(), F_GETLK, &fl) >= 0);
  1819      TEST_CHECK(fl.l_type == F_UNLCK);
  1820      _exit(0);
  1821    }
  1822    int status;
  1823    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1824                SyscallSucceedsWithValue(child_pid));
  1825    ASSERT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0);
  1826  }
  1827  
  1828  TEST_F(FcntlLockTest, GetReadLockOnWriteLock) {
  1829    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
  1830    FileDescriptor fd =
  1831        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
  1832  
  1833    struct flock fl;
  1834    fl.l_type = F_WRLCK;
  1835    fl.l_whence = SEEK_SET;
  1836    fl.l_start = 0;
  1837    fl.l_len = 40;
  1838    ASSERT_THAT(fcntl(fd.get(), F_SETLK, &fl), SyscallSucceeds());
  1839  
  1840    fl.l_type = F_RDLCK;
  1841    pid_t child_pid = fork();
  1842    if (child_pid == 0) {
  1843      TEST_CHECK(fcntl(fd.get(), F_GETLK, &fl) >= 0);
  1844      TEST_CHECK(fl.l_type == F_WRLCK);
  1845      TEST_CHECK(fl.l_pid == getppid());
  1846      _exit(0);
  1847    }
  1848  
  1849    int status;
  1850    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1851                SyscallSucceedsWithValue(child_pid));
  1852    ASSERT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0);
  1853  }
  1854  
  1855  TEST_F(FcntlLockTest, GetWriteLockOnReadLock) {
  1856    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
  1857    FileDescriptor fd =
  1858        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
  1859  
  1860    struct flock fl;
  1861    fl.l_type = F_RDLCK;
  1862    fl.l_whence = SEEK_SET;
  1863    fl.l_start = 0;
  1864    fl.l_len = 40;
  1865    ASSERT_THAT(fcntl(fd.get(), F_SETLK, &fl), SyscallSucceeds());
  1866  
  1867    fl.l_type = F_WRLCK;
  1868    pid_t child_pid = fork();
  1869    if (child_pid == 0) {
  1870      TEST_CHECK(fcntl(fd.get(), F_GETLK, &fl) >= 0);
  1871      TEST_CHECK(fl.l_type == F_RDLCK);
  1872      TEST_CHECK(fl.l_pid == getppid());
  1873      _exit(0);
  1874    }
  1875  
  1876    int status;
  1877    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1878                SyscallSucceedsWithValue(child_pid));
  1879    ASSERT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0);
  1880  }
  1881  
  1882  TEST_F(FcntlLockTest, GetWriteLockOnWriteLock) {
  1883    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
  1884    FileDescriptor fd =
  1885        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
  1886  
  1887    struct flock fl;
  1888    fl.l_type = F_WRLCK;
  1889    fl.l_whence = SEEK_SET;
  1890    fl.l_start = 0;
  1891    fl.l_len = 40;
  1892    ASSERT_THAT(fcntl(fd.get(), F_SETLK, &fl), SyscallSucceeds());
  1893  
  1894    pid_t child_pid = fork();
  1895    if (child_pid == 0) {
  1896      TEST_CHECK(fcntl(fd.get(), F_GETLK, &fl) >= 0);
  1897      TEST_CHECK(fl.l_type == F_WRLCK);
  1898      TEST_CHECK(fl.l_pid == getppid());
  1899      _exit(0);
  1900    }
  1901  
  1902    int status;
  1903    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1904                SyscallSucceedsWithValue(child_pid));
  1905    ASSERT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0);
  1906  }
  1907  
  1908  // Tests that the pid returned from F_GETLK is relative to the caller's PID
  1909  // namespace.
  1910  TEST_F(FcntlLockTest, GetLockRespectsPIDNamespace) {
  1911    SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_SYS_ADMIN)));
  1912    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
  1913    std::string filename = file.path();
  1914    const FileDescriptor fd =
  1915        ASSERT_NO_ERRNO_AND_VALUE(Open(filename, O_RDWR, 0666));
  1916  
  1917    // Lock in the parent process.
  1918    struct flock fl;
  1919    fl.l_type = F_WRLCK;
  1920    fl.l_whence = SEEK_SET;
  1921    fl.l_start = 0;
  1922    fl.l_len = 40;
  1923    ASSERT_THAT(fcntl(fd.get(), F_SETLK, &fl), SyscallSucceeds());
  1924  
  1925    auto child_getlk = [](void* filename) {
  1926      int fd = open((char*)filename, O_RDWR, 0666);
  1927      TEST_CHECK(fd >= 0);
  1928  
  1929      struct flock fl;
  1930      fl.l_type = F_WRLCK;
  1931      fl.l_whence = SEEK_SET;
  1932      fl.l_start = 0;
  1933      fl.l_len = 40;
  1934      TEST_CHECK(fcntl(fd, F_GETLK, &fl) >= 0);
  1935      TEST_CHECK(fl.l_type == F_WRLCK);
  1936      // Parent PID should be 0 in the child PID namespace.
  1937      TEST_CHECK(fl.l_pid == 0);
  1938      close(fd);
  1939      return 0;
  1940    };
  1941  
  1942    // Set up child process in a new PID namespace.
  1943    constexpr int kStackSize = 4096;
  1944    Mapping stack = ASSERT_NO_ERRNO_AND_VALUE(
  1945        Mmap(nullptr, kStackSize, PROT_READ | PROT_WRITE,
  1946             MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0));
  1947    pid_t child_pid;
  1948    ASSERT_THAT(
  1949        child_pid = clone(child_getlk, (char*)stack.ptr() + stack.len(),
  1950                          CLONE_NEWPID | SIGCHLD, (void*)filename.c_str()),
  1951        SyscallSucceeds());
  1952  
  1953    int status;
  1954    ASSERT_THAT(waitpid(child_pid, &status, 0),
  1955                SyscallSucceedsWithValue(child_pid));
  1956    ASSERT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == 0);
  1957  }
  1958  
  1959  TEST_F(FcntlLockTest, TestOFDBasicLock) {
  1960    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
  1961    FileDescriptor fd1 =
  1962        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
  1963  
  1964    struct flock fl = {
  1965        .l_type = F_WRLCK,
  1966        .l_whence = SEEK_SET,
  1967        .l_start = 0,
  1968        .l_len = 0,
  1969        .l_pid = 0,
  1970    };
  1971    ASSERT_THAT(fcntl(fd1.get(), F_OFD_SETLK, &fl), SyscallSucceeds());
  1972  
  1973    FileDescriptor fd2 =
  1974        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
  1975    // Locking from a different file descriptor should fail.
  1976    ASSERT_THAT(fcntl(fd2.get(), F_OFD_SETLK, &fl),
  1977                SyscallFailsWithErrno(EAGAIN));
  1978  
  1979    fl.l_type = F_UNLCK;
  1980    ASSERT_THAT(fcntl(fd1.get(), F_OFD_SETLK, &fl), SyscallSucceeds());
  1981  
  1982    fl.l_type = F_WRLCK;
  1983    ASSERT_THAT(fcntl(fd2.get(), F_OFD_SETLK, &fl), SyscallSucceeds());
  1984  }
  1985  
  1986  TEST_F(FcntlLockTest, TestOFDLockNonZeroPidFails) {
  1987    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
  1988    FileDescriptor fd1 =
  1989        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
  1990  
  1991    struct flock fl = {
  1992        .l_type = F_WRLCK,
  1993        .l_whence = SEEK_SET,
  1994        .l_start = 0,
  1995        .l_len = 0,
  1996        .l_pid = 1,
  1997    };
  1998    ASSERT_THAT(fcntl(fd1.get(), F_OFD_SETLK, &fl),
  1999                SyscallFailsWithErrno(EINVAL));
  2000  }
  2001  
  2002  TEST_F(FcntlLockTest, TestOFDNoUnlockOnClose) {
  2003    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
  2004    struct flock fl = {
  2005        .l_type = F_RDLCK,
  2006        .l_whence = SEEK_SET,
  2007        .l_start = 0,
  2008        .l_len = 0,
  2009        .l_pid = 0,
  2010    };
  2011    FileDescriptor fd1 =
  2012        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
  2013    FileDescriptor fd2 =
  2014        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
  2015  
  2016    ASSERT_THAT(fcntl(fd1.get(), F_OFD_SETLK, &fl), SyscallSucceeds());
  2017    ASSERT_THAT(fcntl(fd2.get(), F_OFD_SETLK, &fl), SyscallSucceeds());
  2018  
  2019    FileDescriptor fd3 =
  2020        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
  2021  
  2022    // Close should not release all locks, just the one associated with the closed
  2023    // file descriptor.
  2024    ASSERT_THAT(close(fd1.release()), SyscallSucceeds());
  2025    fl.l_type = F_WRLCK;
  2026    ASSERT_THAT(fcntl(fd3.get(), F_OFD_GETLK, &fl), SyscallSucceeds());
  2027    ASSERT_EQ(fl.l_type, F_RDLCK);
  2028  }
  2029  
  2030  TEST_F(FcntlLockTest, TestOFDUnlocksOnLastClose) {
  2031    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
  2032    struct flock fl = {
  2033        .l_type = F_RDLCK,
  2034        .l_whence = SEEK_SET,
  2035        .l_start = 0,
  2036        .l_len = 0,
  2037        .l_pid = 0,
  2038    };
  2039    FileDescriptor fd1 =
  2040        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
  2041    FileDescriptor fd2 =
  2042        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
  2043  
  2044    ASSERT_THAT(fcntl(fd1.get(), F_OFD_SETLK, &fl), SyscallSucceeds());
  2045    ASSERT_THAT(fcntl(fd2.get(), F_OFD_SETLK, &fl), SyscallSucceeds());
  2046    ASSERT_THAT(close(fd1.release()), SyscallSucceeds());
  2047    ASSERT_THAT(close(fd2.release()), SyscallSucceeds());
  2048  
  2049    FileDescriptor fd3 =
  2050        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
  2051    fl.l_type = F_WRLCK;
  2052    ASSERT_THAT(fcntl(fd3.get(), F_OFD_GETLK, &fl), SyscallSucceeds());
  2053    ASSERT_EQ(fl.l_type, F_UNLCK);
  2054  }
  2055  
  2056  TEST_F(FcntlLockTest, TestOFDInheritsLockAfterDup) {
  2057    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
  2058    struct flock fl = {
  2059        .l_type = F_WRLCK,
  2060        .l_whence = SEEK_SET,
  2061        .l_start = 0,
  2062        .l_len = 0,
  2063        .l_pid = 0,
  2064    };
  2065    FileDescriptor fd1 =
  2066        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
  2067    ASSERT_THAT(fcntl(fd1.get(), F_OFD_SETLK, &fl), SyscallSucceeds());
  2068    FileDescriptor duped = ASSERT_NO_ERRNO_AND_VALUE(fd1.Dup());
  2069    ASSERT_THAT(close(fd1.release()), SyscallSucceeds());
  2070  
  2071    FileDescriptor fd2 =
  2072        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
  2073    ASSERT_THAT(fcntl(fd2.get(), F_OFD_SETLK, &fl),
  2074                SyscallFailsWithErrno(EAGAIN));
  2075  }
  2076  
  2077  TEST_F(FcntlLockTest, TestOFDLocksHoldAfterExec) {
  2078    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
  2079    FileDescriptor fd =
  2080        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
  2081  
  2082    // Setup two regional locks with different permissions.
  2083    struct flock fl0;
  2084    fl0.l_type = F_WRLCK;
  2085    fl0.l_whence = SEEK_SET;
  2086    fl0.l_start = 0;
  2087    fl0.l_len = 4096;
  2088    fl0.l_pid = 0;
  2089  
  2090    struct flock fl1;
  2091    fl1.l_type = F_RDLCK;
  2092    fl1.l_whence = SEEK_SET;
  2093    fl1.l_start = 4096;
  2094    // Same as SetLockBadFd.
  2095    fl1.l_len = 0;
  2096    fl1.l_pid = 0;
  2097  
  2098    // Set both region locks.
  2099    EXPECT_THAT(fcntl(fd.get(), F_OFD_SETLK, &fl0), SyscallSucceeds());
  2100    EXPECT_THAT(fcntl(fd.get(), F_OFD_SETLK, &fl1), SyscallSucceeds());
  2101  
  2102    // Another process should fail to take a read lock on the entire file
  2103    // due to the regional write lock.
  2104    pid_t child_pid = 0;
  2105    auto cleanup = ASSERT_NO_ERRNO_AND_VALUE(
  2106        SubprocessLock(file.path(), false /* write lock */,
  2107                       false /* nonblocking */, false /* no eintr retry */,
  2108                       nullptr /* no socket fd */, 0, 0, &child_pid));
  2109  
  2110    int status = 0;
  2111    ASSERT_THAT(RetryEINTR(waitpid)(child_pid, &status, 0), SyscallSucceeds());
  2112    EXPECT_TRUE(WIFEXITED(status) && WEXITSTATUS(status) == EAGAIN)
  2113        << "Exited with code: " << status;
  2114  }
  2115  
  2116  TEST_F(FcntlLockTest, TestOFDGetLkReturnsNegPID) {
  2117    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
  2118    struct flock fl = {
  2119        .l_type = F_WRLCK,
  2120        .l_whence = SEEK_SET,
  2121        .l_start = 0,
  2122        .l_len = 0,
  2123        .l_pid = 0,
  2124    };
  2125    FileDescriptor fd1 =
  2126        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
  2127    ASSERT_THAT(fcntl(fd1.get(), F_OFD_SETLK, &fl), SyscallSucceeds());
  2128    FileDescriptor fd2 =
  2129        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
  2130    ASSERT_THAT(fcntl(fd2.get(), F_OFD_GETLK, &fl), SyscallSucceeds());
  2131    ASSERT_EQ(fl.l_pid, -1);
  2132  }
  2133  
  2134  TEST_F(FcntlLockTest, TestOFDCanUpgradeLock) {
  2135    auto file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
  2136    struct flock fl = {
  2137        .l_type = F_RDLCK,
  2138        .l_whence = SEEK_SET,
  2139        .l_start = 0,
  2140        .l_len = 0,
  2141        .l_pid = 0,
  2142    };
  2143    FileDescriptor fd1 =
  2144        ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_RDWR, 0666));
  2145    ASSERT_THAT(fcntl(fd1.get(), F_OFD_SETLK, &fl), SyscallSucceeds());
  2146  
  2147    fl.l_type = F_WRLCK;
  2148    ASSERT_THAT(fcntl(fd1.get(), F_OFD_GETLK, &fl), SyscallSucceeds());
  2149    ASSERT_EQ(fl.l_type, F_UNLCK);
  2150  }
  2151  
  2152  }  // namespace
  2153  
  2154  }  // namespace testing
  2155  }  // namespace gvisor
  2156  
  2157  int set_lock() {
  2158    const std::string set_lock_on = absl::GetFlag(FLAGS_child_set_lock_on);
  2159    int socket_fd = absl::GetFlag(FLAGS_socket_fd);
  2160    int fd = open(set_lock_on.c_str(), O_RDWR, 0666);
  2161    if (fd == -1 && errno != 0) {
  2162      int err = errno;
  2163      std::cerr << "CHILD open " << set_lock_on << " failed: " << err
  2164                << std::endl;
  2165      return err;
  2166    }
  2167  
  2168    struct flock fl;
  2169    if (absl::GetFlag(FLAGS_child_set_lock_write)) {
  2170      fl.l_type = F_WRLCK;
  2171    } else {
  2172      fl.l_type = F_RDLCK;
  2173    }
  2174    fl.l_whence = SEEK_SET;
  2175    fl.l_start = absl::GetFlag(FLAGS_child_set_lock_start);
  2176    fl.l_len = absl::GetFlag(FLAGS_child_set_lock_len);
  2177  
  2178    if (socket_fd != -1) {
  2179      // Send signal to the parent.
  2180      char c = 0;
  2181      gvisor::testing::WriteFd(socket_fd, reinterpret_cast<void*>(&c),
  2182                                     sizeof(c));
  2183    }
  2184    // Test the fcntl.
  2185    int err = 0;
  2186    int ret = 0;
  2187  
  2188    gvisor::testing::MonotonicTimer timer;
  2189    timer.Start();
  2190    do {
  2191      ret = fcntl(fd, absl::GetFlag(FLAGS_blocking) ? F_SETLKW : F_SETLK, &fl);
  2192    } while (absl::GetFlag(FLAGS_retry_eintr) && ret == -1 && errno == EINTR);
  2193    auto usec = absl::ToInt64Microseconds(timer.Duration());
  2194  
  2195    if (ret == -1 && errno != 0) {
  2196      err = errno;
  2197      std::cerr << "CHILD lock " << set_lock_on << " failed " << err << std::endl;
  2198    }
  2199  
  2200    // If there is a socket fd let's send back the time in microseconds it took
  2201    // to execute this syscall.
  2202    if (socket_fd != -1) {
  2203      gvisor::testing::WriteFd(socket_fd, reinterpret_cast<void*>(&usec),
  2204                                     sizeof(usec));
  2205      close(socket_fd);
  2206    }
  2207  
  2208    close(fd);
  2209    return err;
  2210  }
  2211  
  2212  int main(int argc, char** argv) {
  2213    gvisor::testing::TestInit(&argc, &argv);
  2214  
  2215    if (!absl::GetFlag(FLAGS_child_set_lock_on).empty()) {
  2216      exit(set_lock());
  2217    }
  2218  
  2219    return gvisor::testing::RunAllTests();
  2220  }