diff --git a/AK/Function.h b/AK/Function.h index 34a2bc68fc9..99fc8089b5b 100644 --- a/AK/Function.h +++ b/AK/Function.h @@ -51,7 +51,7 @@ public: { } - Out operator()(In... in) + Out operator()(In... in) const { ASSERT(m_callableWrapper); return m_callableWrapper->call(forward(in)...); @@ -83,7 +83,7 @@ private: class CallableWrapperBase { public: virtual ~CallableWrapperBase() { } - virtual Out call(In...) = 0; + virtual Out call(In...) const = 0; }; template @@ -97,7 +97,7 @@ private: CallableWrapper(const CallableWrapper&) = delete; CallableWrapper& operator=(const CallableWrapper&) = delete; - Out call(In... in) final { return m_callable(forward(in)...); } + Out call(In... in) const final { return m_callable(forward(in)...); } private: CallableType m_callable; diff --git a/Kernel/Makefile b/Kernel/Makefile index 6cedc789617..5929be10447 100644 --- a/Kernel/Makefile +++ b/Kernel/Makefile @@ -21,7 +21,8 @@ KERNEL_OBJS = \ MemoryManager.o \ Console.o \ IRQHandler.o \ - kprintf.o + kprintf.o \ + ProcFileSystem.o VFS_OBJS = \ ../VirtualFileSystem/DiskDevice.o \ @@ -35,7 +36,8 @@ VFS_OBJS = \ ../VirtualFileSystem/Ext2FileSystem.o \ ../VirtualFileSystem/InodeIdentifier.o \ ../VirtualFileSystem/VirtualFileSystem.o \ - ../VirtualFileSystem/FileHandle.o + ../VirtualFileSystem/FileHandle.o \ + ../VirtualFileSystem/SyntheticFileSystem.o ELFLOADER_OBJS = \ ../ELFLoader/ELFImage.o \ diff --git a/Kernel/ProcFileSystem.cpp b/Kernel/ProcFileSystem.cpp new file mode 100644 index 00000000000..751d5e9c8d3 --- /dev/null +++ b/Kernel/ProcFileSystem.cpp @@ -0,0 +1,29 @@ +#include "ProcFileSystem.h" +#include + +RetainPtr ProcFileSystem::create() +{ + return adopt(*new ProcFileSystem); +} + +ProcFileSystem::ProcFileSystem() +{ +} + +ProcFileSystem::~ProcFileSystem() +{ +} + +bool ProcFileSystem::initialize() +{ + SyntheticFileSystem::initialize(); + addFile(createGeneratedFile("summary", [] { + return String("Process summary!").toByteBuffer(); + })); + return true; +} + +const char* ProcFileSystem::className() const +{ + return "procfs"; +} diff --git a/Kernel/ProcFileSystem.h b/Kernel/ProcFileSystem.h new file mode 100644 index 00000000000..68d8d04a689 --- /dev/null +++ b/Kernel/ProcFileSystem.h @@ -0,0 +1,17 @@ +#pragma once + +#include +#include + +class ProcFileSystem final : public SyntheticFileSystem { +public: + virtual ~ProcFileSystem() override; + static RetainPtr create(); + + virtual bool initialize() override; + virtual const char* className() const override; + +private: + ProcFileSystem(); +}; + diff --git a/Kernel/Task.cpp b/Kernel/Task.cpp index 10f111ea500..065fe028690 100644 --- a/Kernel/Task.cpp +++ b/Kernel/Task.cpp @@ -645,7 +645,9 @@ FileHandle* Task::openFile(String&& path) { auto handle = VirtualFileSystem::the().open(move(path)); if (!handle) { +#ifdef DEBUG_IO kprintf("vfs::open() failed\n"); +#endif return nullptr; } handle->setFD(m_fileHandles.size()); diff --git a/Kernel/_fs_contents b/Kernel/_fs_contents index 344bc920023..3aaa2fc34ea 100644 Binary files a/Kernel/_fs_contents and b/Kernel/_fs_contents differ diff --git a/Kernel/init.cpp b/Kernel/init.cpp index 743c2b06ca0..c71010136fb 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -25,6 +25,7 @@ #include "MemoryManager.h" #include #include "Console.h" +#include "ProcFileSystem.h" #define TEST_VFS //#define TEST_ELF_LOADER @@ -132,7 +133,9 @@ static void init_stage2() vfs->mountRoot(e2fs.copyRef()); - //vfs->listDirectory("/"); + auto procfs = ProcFileSystem::create(); + procfs->initialize(); + vfs->mount(procfs.copyRef(), "/proc"); { auto motdFile = vfs->open("/motd.txt"); diff --git a/Kernel/sync-sh b/Kernel/sync-sh index 3a32e3b5cb8..971ab5c9cba 100755 --- a/Kernel/sync-sh +++ b/Kernel/sync-sh @@ -1,5 +1,7 @@ mkdir mnt mount -o loop _fs_contents mnt/ cp ../Userland/sh mnt/bin/sh +cp ../Userland/id mnt/bin/id +cp ../Userland/ps mnt/bin/ps umount mnt sync diff --git a/Userland/.gitignore b/Userland/.gitignore index 89dadc36dd6..27529b9b9b5 100644 --- a/Userland/.gitignore +++ b/Userland/.gitignore @@ -1,3 +1,4 @@ id sh +ps *.o diff --git a/Userland/Makefile b/Userland/Makefile index 0266a2edd05..ec3fddd3810 100644 --- a/Userland/Makefile +++ b/Userland/Makefile @@ -1,10 +1,12 @@ OBJS = \ id.o \ - sh.o + sh.o \ + ps.o APPS = \ id \ - sh + sh \ + ps ARCH_FLAGS = STANDARD_FLAGS = -std=c++17 -nostdinc++ -nostdlib @@ -30,6 +32,9 @@ id: id.o sh: sh.o $(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a +ps: ps.o + $(LD) -o $@ $(LDFLAGS) $< ../LibC/LibC.a + .cpp.o: @echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $< diff --git a/Userland/ps.cpp b/Userland/ps.cpp new file mode 100644 index 00000000000..5b620d96e45 --- /dev/null +++ b/Userland/ps.cpp @@ -0,0 +1,25 @@ +#include +#include + +int main(int c, char** v) +{ + int fd = open("/proc/summary"); + if (fd == -1) { + printf("failed to open /proc/summary :(\n"); + return 1; + } + for (;;) { + char buf[16]; + ssize_t nread = read(fd, buf, sizeof(buf)); + if (nread == 0) + break; + if (nread < 0) { + printf("failed to read :(\n"); + return 2; + } + for (ssize_t i = 0; i < nread; ++i) { + putchar(buf[i]); + } + } + return 0; +} diff --git a/VirtualFileSystem/SyntheticFileSystem.cpp b/VirtualFileSystem/SyntheticFileSystem.cpp index 4da29bbf95a..76de74499e4 100644 --- a/VirtualFileSystem/SyntheticFileSystem.cpp +++ b/VirtualFileSystem/SyntheticFileSystem.cpp @@ -1,6 +1,8 @@ #include "SyntheticFileSystem.h" #include +//#define SYNTHFS_DEBUG + RetainPtr SyntheticFileSystem::create() { return adopt(*new SyntheticFileSystem); @@ -25,10 +27,12 @@ bool SyntheticFileSystem::initialize() rootDir->metadata.gid = 0; rootDir->metadata.size = 0; rootDir->metadata.mtime = mepoch; - m_files.append(std::move(rootDir)); + m_files.append(move(rootDir)); +#ifndef SERENITY addFile(createTextFile("file", "I'm a synthetic file!\n")); addFile(createTextFile("message", "Hey! This isn't my bottle!\n")); +#endif return true; } @@ -36,7 +40,7 @@ auto SyntheticFileSystem::createTextFile(String&& name, String&& text) -> OwnPtr { auto file = make(); file->data = text.toByteBuffer(); - file->name = std::move(name); + file->name = move(name); file->metadata.size = file->data.size(); file->metadata.uid = 100; file->metadata.gid = 200; @@ -45,11 +49,24 @@ auto SyntheticFileSystem::createTextFile(String&& name, String&& text) -> OwnPtr return file; } +auto SyntheticFileSystem::createGeneratedFile(String&& name, Function&& generator) -> OwnPtr +{ + auto file = make(); + file->generator = move(generator); + file->name = move(name); + file->metadata.size = 0; + file->metadata.uid = 0; + file->metadata.gid = 0; + file->metadata.mode = 0100644; + file->metadata.mtime = mepoch; + return file; +} + void SyntheticFileSystem::addFile(OwnPtr&& file) { ASSERT(file); file->metadata.inode = { id(), m_files.size() + 1 }; - m_files.append(std::move(file)); + m_files.append(move(file)); } const char* SyntheticFileSystem::className() const @@ -66,7 +83,7 @@ bool SyntheticFileSystem::enumerateDirectoryInode(InodeIdentifier inode, Functio { ASSERT(inode.fileSystemID() == id()); #ifdef SYNTHFS_DEBUG - printf("[synthfs] enumerateDirectoryInode %u\n", inode.index()); + kprintf("[synthfs] enumerateDirectoryInode %u\n", inode.index()); #endif if (inode.index() != 1) return false; @@ -83,17 +100,21 @@ InodeMetadata SyntheticFileSystem::inodeMetadata(InodeIdentifier inode) const { ASSERT(inode.fileSystemID() == id()); #ifdef SYNTHFS_DEBUG - printf("[synthfs] inodeMetadata(%u)\n", inode.index); + kprintf("[synthfs] inodeMetadata(%u)\n", inode.index()); #endif if (inode.index() == 0 || inode.index() > m_files.size()) return InodeMetadata(); - return m_files[inode.index() - 1]->metadata; + auto& file = *m_files[inode.index() - 1]; + auto metadata = file.metadata; + if (file.generator) + metadata.size = file.generator().size(); + return metadata; } bool SyntheticFileSystem::setModificationTime(InodeIdentifier, dword timestamp) { (void) timestamp; - printf("FIXME: Implement SyntheticFileSystem::setModificationTime().\n"); + kprintf("FIXME: Implement SyntheticFileSystem::setModificationTime().\n"); return false; } @@ -102,13 +123,13 @@ InodeIdentifier SyntheticFileSystem::createInode(InodeIdentifier parentInode, co (void) parentInode; (void) name; (void) mode; - printf("FIXME: Implement SyntheticFileSystem::createDirectoryInode().\n"); + kprintf("FIXME: Implement SyntheticFileSystem::createDirectoryInode().\n"); return { }; } bool SyntheticFileSystem::writeInode(InodeIdentifier, const ByteBuffer&) { - printf("FIXME: Implement SyntheticFileSystem::writeInode().\n"); + kprintf("FIXME: Implement SyntheticFileSystem::writeInode().\n"); return false; } @@ -116,7 +137,7 @@ Unix::ssize_t SyntheticFileSystem::readInodeBytes(InodeIdentifier inode, Unix::o { ASSERT(inode.fileSystemID() == id()); #ifdef SYNTHFS_DEBUG - printf("[synthfs] readInode %u\n", inode.index()); + kprintf("[synthfs] readInode %u\n", inode.index()); #endif ASSERT(inode.index() != 1); ASSERT(inode.index() <= m_files.size()); @@ -124,13 +145,18 @@ Unix::ssize_t SyntheticFileSystem::readInodeBytes(InodeIdentifier inode, Unix::o ASSERT(buffer); auto& file = *m_files[inode.index() - 1]; - Unix::ssize_t nread = min(static_cast(file.data.size() - offset), static_cast(count)); - memcpy(buffer, file.data.pointer() + offset, nread); + ByteBuffer generatedData; + if (file.generator) + generatedData = file.generator(); + auto* data = generatedData ? &generatedData : &file.data; + + Unix::ssize_t nread = min(static_cast(data->size() - offset), static_cast(count)); + memcpy(buffer, data->pointer() + offset, nread); return nread; } InodeIdentifier SyntheticFileSystem::makeDirectory(InodeIdentifier parentInode, const String& name, Unix::mode_t) { - printf("FIXME: Implement SyntheticFileSystem::makeDirectory().\n"); + kprintf("FIXME: Implement SyntheticFileSystem::makeDirectory().\n"); return { }; } diff --git a/VirtualFileSystem/SyntheticFileSystem.h b/VirtualFileSystem/SyntheticFileSystem.h index 97f48e883a4..419ea647a9b 100644 --- a/VirtualFileSystem/SyntheticFileSystem.h +++ b/VirtualFileSystem/SyntheticFileSystem.h @@ -4,7 +4,7 @@ #include "UnixTypes.h" #include -class SyntheticFileSystem final : public FileSystem { +class SyntheticFileSystem : public FileSystem { public: virtual ~SyntheticFileSystem() override; static RetainPtr create(); @@ -20,18 +20,22 @@ public: virtual Unix::ssize_t readInodeBytes(InodeIdentifier, Unix::off_t offset, Unix::size_t count, byte* buffer) const override; virtual InodeIdentifier makeDirectory(InodeIdentifier parentInode, const String& name, Unix::mode_t) override; -private: +protected: SyntheticFileSystem(); struct File { String name; InodeMetadata metadata; ByteBuffer data; + Function generator; }; OwnPtr createTextFile(String&& name, String&& text); + OwnPtr createGeneratedFile(String&& name, Function&&); + void addFile(OwnPtr&&); +private: Vector> m_files; };