forked from Bananymous/banan-os
				
			
			update main #1
			
				
			
		
		
		
	| 
						 | 
				
			
			@ -20,11 +20,11 @@ namespace Kernel
 | 
			
		|||
		Process& m_process;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	class ProcMemInode final : public RamInode
 | 
			
		||||
	class ProcROInode final : public RamInode
 | 
			
		||||
	{
 | 
			
		||||
	public:
 | 
			
		||||
		static BAN::ErrorOr<BAN::RefPtr<ProcMemInode>> create(Process&, RamFileSystem&, mode_t, uid_t, gid_t);
 | 
			
		||||
		~ProcMemInode() = default;
 | 
			
		||||
		static BAN::ErrorOr<BAN::RefPtr<ProcROInode>> create(Process&, size_t (Process::*callback)(off_t, void*, size_t) const, RamFileSystem&, mode_t, uid_t, gid_t);
 | 
			
		||||
		~ProcROInode() = default;
 | 
			
		||||
 | 
			
		||||
	protected:
 | 
			
		||||
		virtual BAN::ErrorOr<size_t> read_impl(off_t, void*, size_t) override;
 | 
			
		||||
| 
						 | 
				
			
			@ -35,10 +35,11 @@ namespace Kernel
 | 
			
		|||
		virtual bool has_data_impl() const override										{ return true; }
 | 
			
		||||
 | 
			
		||||
	private:
 | 
			
		||||
		ProcMemInode(Process&, RamFileSystem&, const FullInodeInfo&);
 | 
			
		||||
		ProcROInode(Process&, size_t (Process::*)(off_t, void*, size_t) const, RamFileSystem&, const FullInodeInfo&);
 | 
			
		||||
	
 | 
			
		||||
	private:
 | 
			
		||||
		Process& m_process;
 | 
			
		||||
		size_t (Process::*m_callback)(off_t, void*, size_t) const;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -139,7 +139,9 @@ namespace Kernel
 | 
			
		|||
 | 
			
		||||
		PageTable& page_table() { return m_page_table ? *m_page_table : PageTable::kernel(); }
 | 
			
		||||
 | 
			
		||||
		void get_meminfo(proc_meminfo_t*) const;
 | 
			
		||||
		size_t proc_meminfo(off_t offset, void* buffer, size_t buffer_size) const;
 | 
			
		||||
		size_t proc_cmdline(off_t offset, void* buffer, size_t buffer_size) const;
 | 
			
		||||
		size_t proc_environ(off_t offset, void* buffer, size_t buffer_size) const;
 | 
			
		||||
 | 
			
		||||
		bool is_userspace() const { return m_is_userspace; }
 | 
			
		||||
		const userspace_info_t& userspace_info() const { return m_userspace_info; }
 | 
			
		||||
| 
						 | 
				
			
			@ -192,6 +194,9 @@ namespace Kernel
 | 
			
		|||
		vaddr_t m_signal_handlers[_SIGMAX + 1] { };
 | 
			
		||||
		uint64_t m_signal_pending_mask { 0 };
 | 
			
		||||
 | 
			
		||||
		BAN::Vector<BAN::String> m_cmdline;
 | 
			
		||||
		BAN::Vector<BAN::String> m_environ;
 | 
			
		||||
 | 
			
		||||
		bool m_is_userspace { false };
 | 
			
		||||
		userspace_info_t m_userspace_info;
 | 
			
		||||
		ExitStatus m_exit_status;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,7 +12,9 @@ namespace Kernel
 | 
			
		|||
			return BAN::Error::from_errno(ENOMEM);
 | 
			
		||||
		auto inode = BAN::RefPtr<ProcPidInode>::adopt(inode_ptr);
 | 
			
		||||
 | 
			
		||||
		TRY(inode->add_inode("meminfo"sv, MUST(ProcMemInode::create(process, fs, 0755, 0, 0))));
 | 
			
		||||
		TRY(inode->add_inode("meminfo"sv, MUST(ProcROInode::create(process, &Process::proc_meminfo, fs, 0755, 0, 0))));
 | 
			
		||||
		TRY(inode->add_inode("cmdline"sv, MUST(ProcROInode::create(process, &Process::proc_cmdline, fs, 0755, 0, 0))));
 | 
			
		||||
		TRY(inode->add_inode("environ"sv, MUST(ProcROInode::create(process, &Process::proc_environ, fs, 0755, 0, 0))));
 | 
			
		||||
 | 
			
		||||
		return inode;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -23,36 +25,30 @@ namespace Kernel
 | 
			
		|||
	{
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<BAN::RefPtr<ProcMemInode>> ProcMemInode::create(Process& process, RamFileSystem& fs, mode_t mode, uid_t uid, gid_t gid)
 | 
			
		||||
	BAN::ErrorOr<BAN::RefPtr<ProcROInode>> ProcROInode::create(Process& process, size_t (Process::*callback)(off_t, void*, size_t) const, RamFileSystem& fs, mode_t mode, uid_t uid, gid_t gid)
 | 
			
		||||
	{
 | 
			
		||||
		FullInodeInfo inode_info(fs, mode, uid, gid);
 | 
			
		||||
 | 
			
		||||
		auto* inode_ptr = new ProcMemInode(process, fs, inode_info);
 | 
			
		||||
		auto* inode_ptr = new ProcROInode(process, callback, fs, inode_info);
 | 
			
		||||
		if (inode_ptr == nullptr)
 | 
			
		||||
			return BAN::Error::from_errno(ENOMEM);
 | 
			
		||||
		return BAN::RefPtr<ProcMemInode>::adopt(inode_ptr);
 | 
			
		||||
		return BAN::RefPtr<ProcROInode>::adopt(inode_ptr);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ProcMemInode::ProcMemInode(Process& process, RamFileSystem& fs, const FullInodeInfo& inode_info)
 | 
			
		||||
	ProcROInode::ProcROInode(Process& process, size_t (Process::*callback)(off_t, void*, size_t) const, RamFileSystem& fs, const FullInodeInfo& inode_info)
 | 
			
		||||
		: RamInode(fs, inode_info)
 | 
			
		||||
		, m_process(process)
 | 
			
		||||
		, m_callback(callback)
 | 
			
		||||
	{
 | 
			
		||||
		m_inode_info.mode |= Inode::Mode::IFREG;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<size_t> ProcMemInode::read_impl(off_t offset, void* buffer, size_t buffer_size)
 | 
			
		||||
	BAN::ErrorOr<size_t> ProcROInode::read_impl(off_t offset, void* buffer, size_t buffer_size)
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT(offset >= 0);
 | 
			
		||||
		if ((size_t)offset >= sizeof(proc_meminfo_t))
 | 
			
		||||
			return 0;
 | 
			
		||||
 | 
			
		||||
		proc_meminfo_t meminfo;
 | 
			
		||||
		m_process.get_meminfo(&meminfo);
 | 
			
		||||
 | 
			
		||||
		size_t bytes = BAN::Math::min<size_t>(buffer_size, sizeof(meminfo) - offset);
 | 
			
		||||
		memcpy(buffer, &meminfo, bytes);
 | 
			
		||||
		
 | 
			
		||||
		return bytes;
 | 
			
		||||
		return (m_process.*m_callback)(offset, buffer, buffer_size);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -119,6 +119,9 @@ namespace Kernel
 | 
			
		|||
		MUST(process->m_working_directory.push_back('/'));
 | 
			
		||||
		process->m_page_table = BAN::UniqPtr<PageTable>::adopt(MUST(PageTable::create_userspace()));
 | 
			
		||||
 | 
			
		||||
		TRY(process->m_cmdline.push_back({}));
 | 
			
		||||
		TRY(process->m_cmdline.back().append(path));
 | 
			
		||||
 | 
			
		||||
		process->m_loadable_elf = TRY(load_elf_for_exec(credentials, path, "/"sv, process->page_table()));
 | 
			
		||||
		process->m_loadable_elf->reserve_address_space();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -252,29 +255,75 @@ namespace Kernel
 | 
			
		|||
			thread->set_terminating();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void Process::get_meminfo(proc_meminfo_t* out) const
 | 
			
		||||
	size_t Process::proc_meminfo(off_t offset, void* buffer, size_t buffer_size) const
 | 
			
		||||
	{
 | 
			
		||||
		ASSERT(offset >= 0);
 | 
			
		||||
		if ((size_t)offset >= sizeof(proc_meminfo_t))
 | 
			
		||||
			return 0;
 | 
			
		||||
 | 
			
		||||
		proc_meminfo_t meminfo;
 | 
			
		||||
		meminfo.page_size = PAGE_SIZE;
 | 
			
		||||
		meminfo.virt_pages = 0;
 | 
			
		||||
		meminfo.phys_pages = 0;
 | 
			
		||||
 | 
			
		||||
		{
 | 
			
		||||
			LockGuard _(m_lock);
 | 
			
		||||
			for (auto* thread : m_threads)
 | 
			
		||||
			{
 | 
			
		||||
				meminfo.virt_pages += thread->virtual_page_count();
 | 
			
		||||
				meminfo.phys_pages += thread->physical_page_count();
 | 
			
		||||
			}
 | 
			
		||||
			for (auto& region : m_mapped_regions)
 | 
			
		||||
			{
 | 
			
		||||
				meminfo.virt_pages += region->virtual_page_count();
 | 
			
		||||
				meminfo.phys_pages += region->physical_page_count();
 | 
			
		||||
			}
 | 
			
		||||
			if (m_loadable_elf)
 | 
			
		||||
			{
 | 
			
		||||
				meminfo.virt_pages += m_loadable_elf->virtual_page_count();
 | 
			
		||||
				meminfo.phys_pages += m_loadable_elf->physical_page_count();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		size_t bytes = BAN::Math::min<size_t>(sizeof(proc_meminfo_t) - offset, buffer_size);
 | 
			
		||||
		memcpy(buffer, (uint8_t*)&meminfo + offset, bytes);
 | 
			
		||||
		return bytes;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static size_t read_from_vec_of_str(const BAN::Vector<BAN::String>& container, size_t start, void* buffer, size_t buffer_size)
 | 
			
		||||
	{
 | 
			
		||||
		size_t offset = 0;
 | 
			
		||||
		size_t written = 0;
 | 
			
		||||
		for (const auto& elem : container)
 | 
			
		||||
		{
 | 
			
		||||
			if (start < offset + elem.size() + 1)
 | 
			
		||||
			{
 | 
			
		||||
				size_t elem_offset = 0;
 | 
			
		||||
				if (offset < start)
 | 
			
		||||
					elem_offset = start - offset;
 | 
			
		||||
 | 
			
		||||
				size_t bytes = BAN::Math::min<size_t>(elem.size() + 1 - elem_offset, buffer_size - written);
 | 
			
		||||
				memcpy((uint8_t*)buffer + written, elem.data() + elem_offset, bytes);
 | 
			
		||||
 | 
			
		||||
				written += bytes;
 | 
			
		||||
				if (written >= buffer_size)
 | 
			
		||||
					break;
 | 
			
		||||
			}
 | 
			
		||||
			offset += elem.size() + 1;
 | 
			
		||||
		}
 | 
			
		||||
		return written;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	size_t Process::proc_cmdline(off_t offset, void* buffer, size_t buffer_size) const
 | 
			
		||||
	{
 | 
			
		||||
		LockGuard _(m_lock);
 | 
			
		||||
		return read_from_vec_of_str(m_cmdline, offset, buffer, buffer_size);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
		out->page_size = PAGE_SIZE;
 | 
			
		||||
		out->virt_pages = 0;
 | 
			
		||||
		out->phys_pages = 0;
 | 
			
		||||
 | 
			
		||||
		for (auto* thread : m_threads)
 | 
			
		||||
		{
 | 
			
		||||
			out->virt_pages += thread->virtual_page_count();
 | 
			
		||||
			out->phys_pages += thread->physical_page_count();
 | 
			
		||||
		}
 | 
			
		||||
		for (auto& region : m_mapped_regions)
 | 
			
		||||
		{
 | 
			
		||||
			out->virt_pages += region->virtual_page_count();
 | 
			
		||||
			out->phys_pages += region->physical_page_count();
 | 
			
		||||
		}
 | 
			
		||||
		if (m_loadable_elf)
 | 
			
		||||
		{
 | 
			
		||||
			out->virt_pages += m_loadable_elf->virtual_page_count();
 | 
			
		||||
			out->phys_pages += m_loadable_elf->physical_page_count();
 | 
			
		||||
		}
 | 
			
		||||
	size_t Process::proc_environ(off_t offset, void* buffer, size_t buffer_size) const
 | 
			
		||||
	{
 | 
			
		||||
		LockGuard _(m_lock);
 | 
			
		||||
		return read_from_vec_of_str(m_environ, offset, buffer, buffer_size);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	BAN::ErrorOr<long> Process::sys_exit(int status)
 | 
			
		||||
| 
						 | 
				
			
			@ -461,9 +510,12 @@ namespace Kernel
 | 
			
		|||
			auto envp_region = MUST(create_region(str_envp.span()));
 | 
			
		||||
			m_userspace_info.envp = (char**)envp_region->vaddr();
 | 
			
		||||
			MUST(m_mapped_regions.push_back(BAN::move(envp_region)));
 | 
			
		||||
 | 
			
		||||
			
 | 
			
		||||
			m_userspace_info.argc = str_argv.size();
 | 
			
		||||
 | 
			
		||||
			m_cmdline = BAN::move(str_argv);
 | 
			
		||||
			m_environ = BAN::move(str_envp);
 | 
			
		||||
 | 
			
		||||
			asm volatile("cli");
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue