diff options
Diffstat (limited to 'test/syscalls/linux/proc.cc')
-rw-r--r-- | test/syscalls/linux/proc.cc | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/test/syscalls/linux/proc.cc b/test/syscalls/linux/proc.cc index 7a0f33dff..e508ce27f 100644 --- a/test/syscalls/linux/proc.cc +++ b/test/syscalls/linux/proc.cc @@ -17,6 +17,7 @@ #include <fcntl.h> #include <limits.h> #include <linux/magic.h> +#include <linux/sem.h> #include <sched.h> #include <signal.h> #include <stddef.h> @@ -1801,6 +1802,33 @@ TEST(ProcPidCmdline, SubprocessForkSameCmdline) { } } +TEST(ProcPidCmdline, SubprocessSeekCmdline) { + FileDescriptor fd; + ASSERT_NO_ERRNO(WithSubprocess( + [&](int pid) -> PosixError { + // Running. Open /proc/pid/cmdline. + ASSIGN_OR_RETURN_ERRNO( + fd, Open(absl::StrCat("/proc/", pid, "/cmdline"), O_RDONLY)); + return NoError(); + }, + [&](int pid) -> PosixError { + // Zombie, but seek should still succeed. + int ret = lseek(fd.get(), 0x801, 0); + if (ret < 0) { + return PosixError(errno); + } + return NoError(); + }, + [&](int pid) -> PosixError { + // Exited. + int ret = lseek(fd.get(), 0x801, 0); + if (ret < 0) { + return PosixError(errno); + } + return NoError(); + })); +} + // Test whether /proc/PID/ symlinks can be read for a running process. TEST(ProcPidSymlink, SubprocessRunning) { char buf[1]; @@ -2409,6 +2437,28 @@ TEST(ProcFilesystems, PresenceOfShmMaxMniAll) { ASSERT_LE(shmall, ULONG_MAX - (1UL << 24)); } +TEST(ProcFilesystems, PresenceOfSem) { + uint32_t semmsl = 0; + uint32_t semmns = 0; + uint32_t semopm = 0; + uint32_t semmni = 0; + std::string proc_file; + proc_file = ASSERT_NO_ERRNO_AND_VALUE(GetContents("/proc/sys/kernel/sem")); + ASSERT_FALSE(proc_file.empty()); + std::vector<absl::string_view> sem_limits = + absl::StrSplit(proc_file, absl::ByAnyChar("\t"), absl::SkipWhitespace()); + ASSERT_EQ(sem_limits.size(), 4); + ASSERT_TRUE(absl::SimpleAtoi(sem_limits[0], &semmsl)); + ASSERT_TRUE(absl::SimpleAtoi(sem_limits[1], &semmns)); + ASSERT_TRUE(absl::SimpleAtoi(sem_limits[2], &semopm)); + ASSERT_TRUE(absl::SimpleAtoi(sem_limits[3], &semmni)); + + ASSERT_EQ(semmsl, SEMMSL); + ASSERT_EQ(semmns, SEMMNS); + ASSERT_EQ(semopm, SEMOPM); + ASSERT_EQ(semmni, SEMMNI); +} + // Check that /proc/mounts is a symlink to self/mounts. TEST(ProcMounts, IsSymlink) { auto link = ASSERT_NO_ERRNO_AND_VALUE(ReadLink("/proc/mounts")); @@ -2459,7 +2509,7 @@ void CheckDuplicatesRecursively(std::string path) { return; } auto dir_closer = Cleanup([&dir]() { closedir(dir); }); - std::unordered_set<std::string> children; + absl::node_hash_set<std::string> children; while (true) { // Readdir(3): If the end of the directory stream is reached, NULL is // returned and errno is not changed. If an error occurs, NULL is @@ -2478,6 +2528,10 @@ void CheckDuplicatesRecursively(std::string path) { absl::EndsWith(path, "/net")) { break; } + // We may also see permission failures traversing some files. + if (errno == EACCES && absl::StartsWith(path, "/proc/")) { + break; + } // Otherwise, no errors are allowed. ASSERT_EQ(errno, 0) << path; |