mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 20:52:45 +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); | ||||
| } | ||||
| 
 | ||||
| KResult FIFO::stat(::stat& st) const | ||||
| { | ||||
|     memset(&st, 0, sizeof(st)); | ||||
|     st.st_mode = S_IFIFO; | ||||
|     return KSuccess; | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -59,6 +59,7 @@ private: | |||
|     // ^File
 | ||||
|     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 KResult stat(::stat&) const override; | ||||
|     virtual bool can_read(const FileDescription&, size_t) const override; | ||||
|     virtual bool can_write(const FileDescription&, size_t) 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 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 KResult stat(::stat&) const { return KResult(-EBADF); } | ||||
| 
 | ||||
|     virtual String absolute_path(const FileDescription&) const = 0; | ||||
| 
 | ||||
|  |  | |||
|  | @ -77,20 +77,11 @@ FileDescription::~FileDescription() | |||
| 
 | ||||
| KResult FileDescription::stat(::stat& buffer) | ||||
| { | ||||
|     if (is_fifo()) { | ||||
|         memset(&buffer, 0, sizeof(buffer)); | ||||
|         buffer.st_mode = S_IFIFO; | ||||
|         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); | ||||
|     LOCKER(m_lock); | ||||
|     // FIXME: This is a little awkward, why can't we always forward to File::stat()?
 | ||||
|     if (m_inode) | ||||
|         return metadata().stat(buffer); | ||||
|     return m_file->stat(buffer); | ||||
| } | ||||
| 
 | ||||
| off_t FileDescription::seek(off_t offset, int whence) | ||||
|  |  | |||
|  | @ -220,4 +220,11 @@ KResult Socket::shutdown(int how) | |||
|     return KSuccess; | ||||
| } | ||||
| 
 | ||||
| KResult Socket::stat(::stat& st) const | ||||
| { | ||||
|     memset(&st, 0, sizeof(st)); | ||||
|     st.st_mode = S_IFSOCK; | ||||
|     return KSuccess; | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -58,9 +58,9 @@ public: | |||
|     bool is_shut_down_for_reading() const { return m_shut_down_for_reading; } | ||||
| 
 | ||||
|     enum class SetupState { | ||||
|         Unstarted, // we haven't tried to set the socket up yet
 | ||||
|         Unstarted,  // we haven't tried to set the socket up yet
 | ||||
|         InProgress, // we're in the process of setting things up - for TCP maybe we've sent a SYN packet
 | ||||
|         Completed, // the setup process is complete, but not necessarily successful
 | ||||
|         Completed,  // the setup process is complete, but not necessarily successful
 | ||||
|     }; | ||||
| 
 | ||||
|     enum class Role : u8 { | ||||
|  | @ -126,6 +126,7 @@ public: | |||
|     // ^File
 | ||||
|     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 KResult stat(::stat&) const override; | ||||
|     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; } | ||||
|  | @ -144,8 +145,8 @@ protected: | |||
| 
 | ||||
|     virtual const char* class_name() const override { return "Socket"; } | ||||
| 
 | ||||
|     virtual void shut_down_for_reading() {} | ||||
|     virtual void shut_down_for_writing() {} | ||||
|     virtual void shut_down_for_reading() { } | ||||
|     virtual void shut_down_for_writing() { } | ||||
| 
 | ||||
|     Role m_role { Role::None }; | ||||
| 
 | ||||
|  | @ -175,10 +176,10 @@ private: | |||
|     NonnullRefPtrVector<Socket> m_pending; | ||||
| }; | ||||
| 
 | ||||
| template <typename SocketType> | ||||
| template<typename SocketType> | ||||
| class SocketHandle { | ||||
| public: | ||||
|     SocketHandle() {} | ||||
|     SocketHandle() { } | ||||
| 
 | ||||
|     SocketHandle(NonnullRefPtr<SocketType>&& socket) | ||||
|         : m_socket(move(socket)) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling