mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 21:42:43 +00:00 
			
		
		
		
	Kernel: Virtualize the File::stat() operation
Instead of FileDescriptor branching on the type of File it's wrapping, add a File::stat() function that can be overridden to provide custom behavior for the stat syscalls.
This commit is contained in:
		
							parent
							
								
									5444cabd39
								
							
						
					
					
						commit
						22831033d0
					
				
					 6 changed files with 28 additions and 20 deletions
				
			
		|  | @ -166,4 +166,11 @@ String FIFO::absolute_path(const FileDescription&) const | ||||||
|     return String::format("fifo:%u", m_fifo_id); |     return String::format("fifo:%u", m_fifo_id); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | KResult FIFO::stat(::stat& st) const | ||||||
|  | { | ||||||
|  |     memset(&st, 0, sizeof(st)); | ||||||
|  |     st.st_mode = S_IFIFO; | ||||||
|  |     return KSuccess; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -59,6 +59,7 @@ private: | ||||||
|     // ^File
 |     // ^File
 | ||||||
|     virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override; |     virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override; | ||||||
|     virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override; |     virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override; | ||||||
|  |     virtual KResult stat(::stat&) const override; | ||||||
|     virtual bool can_read(const FileDescription&, size_t) const override; |     virtual bool can_read(const FileDescription&, size_t) const override; | ||||||
|     virtual bool can_write(const FileDescription&, size_t) const override; |     virtual bool can_write(const FileDescription&, size_t) const override; | ||||||
|     virtual String absolute_path(const FileDescription&) const override; |     virtual String absolute_path(const FileDescription&) const override; | ||||||
|  |  | ||||||
|  | @ -78,6 +78,7 @@ public: | ||||||
|     virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) = 0; |     virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) = 0; | ||||||
|     virtual int ioctl(FileDescription&, unsigned request, FlatPtr arg); |     virtual int ioctl(FileDescription&, unsigned request, FlatPtr arg); | ||||||
|     virtual KResultOr<Region*> mmap(Process&, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot, bool shared); |     virtual KResultOr<Region*> mmap(Process&, FileDescription&, VirtualAddress preferred_vaddr, size_t offset, size_t size, int prot, bool shared); | ||||||
|  |     virtual KResult stat(::stat&) const { return KResult(-EBADF); } | ||||||
| 
 | 
 | ||||||
|     virtual String absolute_path(const FileDescription&) const = 0; |     virtual String absolute_path(const FileDescription&) const = 0; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -77,20 +77,11 @@ FileDescription::~FileDescription() | ||||||
| 
 | 
 | ||||||
| KResult FileDescription::stat(::stat& buffer) | KResult FileDescription::stat(::stat& buffer) | ||||||
| { | { | ||||||
|     if (is_fifo()) { |     LOCKER(m_lock); | ||||||
|         memset(&buffer, 0, sizeof(buffer)); |     // FIXME: This is a little awkward, why can't we always forward to File::stat()?
 | ||||||
|         buffer.st_mode = S_IFIFO; |     if (m_inode) | ||||||
|         return KSuccess; |  | ||||||
|     } |  | ||||||
|     if (is_socket()) { |  | ||||||
|         memset(&buffer, 0, sizeof(buffer)); |  | ||||||
|         buffer.st_mode = S_IFSOCK; |  | ||||||
|         return KSuccess; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     if (!m_inode) |  | ||||||
|         return KResult(-EBADF); |  | ||||||
|         return metadata().stat(buffer); |         return metadata().stat(buffer); | ||||||
|  |     return m_file->stat(buffer); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| off_t FileDescription::seek(off_t offset, int whence) | off_t FileDescription::seek(off_t offset, int whence) | ||||||
|  |  | ||||||
|  | @ -220,4 +220,11 @@ KResult Socket::shutdown(int how) | ||||||
|     return KSuccess; |     return KSuccess; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | KResult Socket::stat(::stat& st) const | ||||||
|  | { | ||||||
|  |     memset(&st, 0, sizeof(st)); | ||||||
|  |     st.st_mode = S_IFSOCK; | ||||||
|  |     return KSuccess; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -126,6 +126,7 @@ public: | ||||||
|     // ^File
 |     // ^File
 | ||||||
|     virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override final; |     virtual KResultOr<size_t> read(FileDescription&, size_t, u8*, size_t) override final; | ||||||
|     virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override final; |     virtual KResultOr<size_t> write(FileDescription&, size_t, const u8*, size_t) override final; | ||||||
|  |     virtual KResult stat(::stat&) const override; | ||||||
|     virtual String absolute_path(const FileDescription&) const override = 0; |     virtual String absolute_path(const FileDescription&) const override = 0; | ||||||
| 
 | 
 | ||||||
|     bool has_receive_timeout() const { return m_receive_timeout.tv_sec || m_receive_timeout.tv_usec; } |     bool has_receive_timeout() const { return m_receive_timeout.tv_sec || m_receive_timeout.tv_usec; } | ||||||
|  | @ -144,8 +145,8 @@ protected: | ||||||
| 
 | 
 | ||||||
|     virtual const char* class_name() const override { return "Socket"; } |     virtual const char* class_name() const override { return "Socket"; } | ||||||
| 
 | 
 | ||||||
|     virtual void shut_down_for_reading() {} |     virtual void shut_down_for_reading() { } | ||||||
|     virtual void shut_down_for_writing() {} |     virtual void shut_down_for_writing() { } | ||||||
| 
 | 
 | ||||||
|     Role m_role { Role::None }; |     Role m_role { Role::None }; | ||||||
| 
 | 
 | ||||||
|  | @ -175,10 +176,10 @@ private: | ||||||
|     NonnullRefPtrVector<Socket> m_pending; |     NonnullRefPtrVector<Socket> m_pending; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| template <typename SocketType> | template<typename SocketType> | ||||||
| class SocketHandle { | class SocketHandle { | ||||||
| public: | public: | ||||||
|     SocketHandle() {} |     SocketHandle() { } | ||||||
| 
 | 
 | ||||||
|     SocketHandle(NonnullRefPtr<SocketType>&& socket) |     SocketHandle(NonnullRefPtr<SocketType>&& socket) | ||||||
|         : m_socket(move(socket)) |         : m_socket(move(socket)) | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling