diff --git a/Kernel/ProcFileSystem.cpp b/Kernel/ProcFileSystem.cpp index 1c1c589ec0..9ab89bb11c 100644 --- a/Kernel/ProcFileSystem.cpp +++ b/Kernel/ProcFileSystem.cpp @@ -27,6 +27,22 @@ ProcFileSystem::~ProcFileSystem() { } +ByteBuffer procfs$pid_fds(const Process& process) +{ + char* buffer; + auto stringImpl = StringImpl::createUninitialized(process.number_of_open_file_descriptors() * 80, buffer); + memset(buffer, 0, stringImpl->length()); + char* ptr = buffer; + for (size_t i = 0; i < process.max_open_file_descriptors(); ++i) { + auto* handle = process.file_descriptor(i); + if (!handle) + continue; + ptr += ksprintf(ptr, "% 3u %s\n", i, handle->absolute_path().characters()); + } + *ptr = '\0'; + return ByteBuffer::copy((byte*)buffer, ptr - buffer); +} + ByteBuffer procfs$pid_vm(const Process& process) { InterruptDisabler disabler; @@ -109,6 +125,7 @@ void ProcFileSystem::addProcess(Process& process) m_pid2inode.set(process.pid(), dir.index()); addFile(createGeneratedFile("vm", [&process] { return procfs$pid_vm(process); }), dir.index()); addFile(createGeneratedFile("stack", [&process] { return procfs$pid_stack(process); }), dir.index()); + addFile(createGeneratedFile("fds", [&process] { return procfs$pid_fds(process); }), dir.index()); if (process.executableInode().isValid()) addFile(createGeneratedFile("exe", [&process] { return procfs$pid_exe(process); }, 00120777), dir.index()); } diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index c6c6fb3a04..08c6a74a54 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -867,8 +867,9 @@ int Process::sys$close(int fd) auto* handle = fileHandleIfExists(fd); if (!handle) return -EBADF; - // FIXME: Implement. - return 0; + int rc = handle->close(); + m_file_descriptors[fd] = nullptr; + return rc; } int Process::sys$lstat(const char* path, Unix::stat* statbuf) @@ -966,9 +967,13 @@ int Process::sys$open(const char* path, int options) if (options & O_DIRECTORY && !handle->isDirectory()) return -ENOTDIR; // FIXME: This should be handled by VFS::open. - int fd = m_file_descriptors.size(); + int fd = 0; + for (; fd < m_max_open_file_descriptors; ++fd) { + if (!m_file_descriptors[fd]) + break; + } handle->setFD(fd); - m_file_descriptors.append(move(handle)); + m_file_descriptors[fd] = move(handle); return fd; } diff --git a/Kernel/Process.h b/Kernel/Process.h index 78d5bfccb4..132ff30bd1 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -136,6 +136,9 @@ public: InodeIdentifier executableInode() const { return m_executable ? m_executable->inode : InodeIdentifier(); } size_t number_of_open_file_descriptors() const; + size_t max_open_file_descriptors() const { return m_max_open_file_descriptors; } + FileHandle* file_descriptor(size_t i) { return m_file_descriptors[i].ptr(); } + const FileHandle* file_descriptor(size_t i) const { return m_file_descriptors[i].ptr(); } private: friend class MemoryManager; diff --git a/VirtualFileSystem/FileHandle.cpp b/VirtualFileSystem/FileHandle.cpp index 7e795906e3..6f9354a143 100644 --- a/VirtualFileSystem/FileHandle.cpp +++ b/VirtualFileSystem/FileHandle.cpp @@ -175,3 +175,15 @@ const TTY* FileHandle::tty() const return static_cast(device); return nullptr; } + +int FileHandle::close() +{ + return 0; +} + +String FileHandle::absolute_path() const +{ + if (isTTY()) + return tty()->ttyName(); + return VirtualFileSystem::the().absolutePath(m_vnode->inode); +} diff --git a/VirtualFileSystem/FileHandle.h b/VirtualFileSystem/FileHandle.h index e31cebf63b..d5e0d1bf2d 100644 --- a/VirtualFileSystem/FileHandle.h +++ b/VirtualFileSystem/FileHandle.h @@ -11,6 +11,8 @@ public: explicit FileHandle(RetainPtr&&); ~FileHandle(); + int close(); + Unix::off_t seek(Unix::off_t, int whence); Unix::ssize_t read(byte*, Unix::size_t); Unix::ssize_t write(const byte* data, Unix::size_t); @@ -22,7 +24,7 @@ public: ByteBuffer readEntireFile(); - String absolutePath() const; + String absolute_path() const; bool isDirectory() const;