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

     1  // Copyright 2021 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 <errno.h>
    16  #include <fcntl.h>
    17  #include <time.h>
    18  #include <unistd.h>
    19  
    20  #include <string>
    21  
    22  #include "gmock/gmock.h"
    23  #include "gtest/gtest.h"
    24  #include "test/util/file_descriptor.h"
    25  #include "test/util/fs_util.h"
    26  #include "test/util/temp_path.h"
    27  #include "test/util/test_util.h"
    28  
    29  constexpr mode_t mode = 1;
    30  
    31  namespace gvisor {
    32  namespace testing {
    33  
    34  namespace {
    35  
    36  PosixErrorOr<FileDescriptor> createdDeleted() {
    37    auto path = NewTempAbsPath();
    38    PosixErrorOr<FileDescriptor> fd = Open(path, O_RDWR | O_CREAT, mode);
    39    if (!fd.ok()) {
    40      return fd.error();
    41    }
    42  
    43    auto err = Unlink(path);
    44    if (!err.ok()) {
    45      return err;
    46    }
    47    return fd;
    48  }
    49  
    50  TEST(DeletedTest, Utime) {
    51    auto fd = ASSERT_NO_ERRNO_AND_VALUE(createdDeleted());
    52  
    53    const struct timespec times[2] = {{10, 0}, {20, 0}};
    54    EXPECT_THAT(futimens(fd.get(), times), SyscallSucceeds());
    55  
    56    struct stat stat;
    57    ASSERT_THAT(fstat(fd.get(), &stat), SyscallSucceeds());
    58    EXPECT_EQ(10, stat.st_atime);
    59    EXPECT_EQ(20, stat.st_mtime);
    60  }
    61  
    62  TEST(DeletedTest, Chmod) {
    63    auto fd = ASSERT_NO_ERRNO_AND_VALUE(createdDeleted());
    64  
    65    ASSERT_THAT(fchmod(fd.get(), mode + 1), SyscallSucceeds());
    66  
    67    struct stat stat;
    68    ASSERT_THAT(fstat(fd.get(), &stat), SyscallSucceeds());
    69    EXPECT_EQ(mode + 1, stat.st_mode & ~S_IFMT);
    70  }
    71  
    72  TEST(DeletedTest, Truncate) {
    73    auto fd = ASSERT_NO_ERRNO_AND_VALUE(createdDeleted());
    74    const std::string data = "foobar";
    75    ASSERT_THAT(write(fd.get(), data.c_str(), data.size()), SyscallSucceeds());
    76  
    77    ASSERT_THAT(ftruncate(fd.get(), 0), SyscallSucceeds());
    78  
    79    struct stat stat;
    80    ASSERT_THAT(fstat(fd.get(), &stat), SyscallSucceeds());
    81    ASSERT_EQ(stat.st_size, 0);
    82  }
    83  
    84  TEST(DeletedTest, Fallocate) {
    85    auto fd = ASSERT_NO_ERRNO_AND_VALUE(createdDeleted());
    86  
    87    ASSERT_THAT(RetryEINTR(fallocate)(fd.get(), 0, 0, 123), SyscallSucceeds());
    88  
    89    struct stat stat;
    90    ASSERT_THAT(fstat(fd.get(), &stat), SyscallSucceeds());
    91    EXPECT_EQ(123, stat.st_size);
    92  }
    93  
    94  // Tests that a file can be created with the same path as a deleted file that
    95  // still have an open FD to it.
    96  TEST(DeletedTest, Replace) {
    97    auto path = NewTempAbsPath();
    98    auto fd = ASSERT_NO_ERRNO_AND_VALUE(Open(path, O_RDWR | O_CREAT, mode));
    99    ASSERT_NO_ERRNO(Unlink(path));
   100  
   101    auto other =
   102        ASSERT_NO_ERRNO_AND_VALUE(Open(path, O_RDWR | O_CREAT | O_EXCL, mode));
   103  
   104    auto stat = ASSERT_NO_ERRNO_AND_VALUE(Fstat(fd.get()));
   105    auto stat_other = ASSERT_NO_ERRNO_AND_VALUE(Fstat(other.get()));
   106    ASSERT_NE(stat.st_ino, stat_other.st_ino);
   107  
   108    // Check that the path points to the new file.
   109    stat = ASSERT_NO_ERRNO_AND_VALUE(Stat(path));
   110    ASSERT_EQ(stat.st_ino, stat_other.st_ino);
   111  }
   112  
   113  }  // namespace
   114  
   115  }  // namespace testing
   116  }  // namespace gvisor