mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 17:02:45 +00:00 
			
		
		
		
	Kernel: Add Inode::truncate(size).
- Use this to implement the O_TRUNC open flag. - Fix creat() to pass O_CREAT | O_TRUNC | O_WRONLY. - Make sure we truncate wherever appropriate.
This commit is contained in:
		
							parent
							
								
									e9f2cc3595
								
							
						
					
					
						commit
						0058da734e
					
				
					 8 changed files with 26 additions and 8 deletions
				
			
		|  | @ -1391,6 +1391,16 @@ KResult Ext2FSInode::chown(uid_t uid, gid_t gid) | ||||||
|     return KSuccess; |     return KSuccess; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | KResult Ext2FSInode::truncate(int size) | ||||||
|  | { | ||||||
|  |     LOCKER(m_lock); | ||||||
|  |     if (m_raw_inode.i_size == size) | ||||||
|  |         return KSuccess; | ||||||
|  |     m_raw_inode.i_size = size; | ||||||
|  |     set_metadata_dirty(true); | ||||||
|  |     return KSuccess; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| unsigned Ext2FS::total_block_count() const | unsigned Ext2FS::total_block_count() const | ||||||
| { | { | ||||||
|     LOCKER(m_lock); |     LOCKER(m_lock); | ||||||
|  |  | ||||||
|  | @ -42,6 +42,7 @@ private: | ||||||
|     virtual size_t directory_entry_count() const override; |     virtual size_t directory_entry_count() const override; | ||||||
|     virtual KResult chmod(mode_t) override; |     virtual KResult chmod(mode_t) override; | ||||||
|     virtual KResult chown(uid_t, gid_t) override; |     virtual KResult chown(uid_t, gid_t) override; | ||||||
|  |     virtual KResult truncate(int) override; | ||||||
| 
 | 
 | ||||||
|     void populate_lookup_cache() const; |     void populate_lookup_cache() const; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -103,6 +103,7 @@ public: | ||||||
|     virtual size_t directory_entry_count() const = 0; |     virtual size_t directory_entry_count() const = 0; | ||||||
|     virtual KResult chmod(mode_t) = 0; |     virtual KResult chmod(mode_t) = 0; | ||||||
|     virtual KResult chown(uid_t, gid_t) = 0; |     virtual KResult chown(uid_t, gid_t) = 0; | ||||||
|  |     virtual KResult truncate(int) { return KSuccess; } | ||||||
| 
 | 
 | ||||||
|     LocalSocket* socket() { return m_socket.ptr(); } |     LocalSocket* socket() { return m_socket.ptr(); } | ||||||
|     const LocalSocket* socket() const { return m_socket.ptr(); } |     const LocalSocket* socket() const { return m_socket.ptr(); } | ||||||
|  |  | ||||||
|  | @ -170,7 +170,10 @@ KResultOr<Retained<FileDescriptor>> VFS::open(const String& path, int options, m | ||||||
|     if (inode_or_error.is_error()) |     if (inode_or_error.is_error()) | ||||||
|         return inode_or_error.error(); |         return inode_or_error.error(); | ||||||
| 
 | 
 | ||||||
|     auto metadata = inode_or_error.value()->metadata(); |     auto inode = inode_or_error.value(); | ||||||
|  |     auto metadata = inode->metadata(); | ||||||
|  | 
 | ||||||
|  |     bool should_truncate_file = false; | ||||||
| 
 | 
 | ||||||
|     // NOTE: Read permission is a bit weird, since O_RDONLY == 0,
 |     // NOTE: Read permission is a bit weird, since O_RDONLY == 0,
 | ||||||
|     //       so we check if (NOT write_only OR read_and_write)
 |     //       so we check if (NOT write_only OR read_and_write)
 | ||||||
|  | @ -183,6 +186,7 @@ KResultOr<Retained<FileDescriptor>> VFS::open(const String& path, int options, m | ||||||
|             return KResult(-EACCES); |             return KResult(-EACCES); | ||||||
|         if (metadata.is_directory()) |         if (metadata.is_directory()) | ||||||
|             return KResult(-EISDIR); |             return KResult(-EISDIR); | ||||||
|  |         should_truncate_file = options & O_TRUNC; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (metadata.is_device()) { |     if (metadata.is_device()) { | ||||||
|  | @ -193,10 +197,12 @@ KResultOr<Retained<FileDescriptor>> VFS::open(const String& path, int options, m | ||||||
|         auto descriptor_or_error = (*it).value->open(options); |         auto descriptor_or_error = (*it).value->open(options); | ||||||
|         if (descriptor_or_error.is_error()) |         if (descriptor_or_error.is_error()) | ||||||
|             return descriptor_or_error.error(); |             return descriptor_or_error.error(); | ||||||
|         descriptor_or_error.value()->set_original_inode(Badge<VFS>(), *inode_or_error.value()); |         descriptor_or_error.value()->set_original_inode(Badge<VFS>(), *inode); | ||||||
|         return descriptor_or_error; |         return descriptor_or_error; | ||||||
|     } |     } | ||||||
|     return FileDescriptor::create(*inode_or_error.value()); |     if (should_truncate_file) | ||||||
|  |         inode->truncate(0); | ||||||
|  |     return FileDescriptor::create(*inode); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| KResultOr<Retained<FileDescriptor>> VFS::create(const String& path, int options, mode_t mode, Inode& base) | KResultOr<Retained<FileDescriptor>> VFS::create(const String& path, int options, mode_t mode, Inode& base) | ||||||
|  |  | ||||||
|  | @ -146,7 +146,7 @@ pid_t getpgrp() | ||||||
| 
 | 
 | ||||||
| int creat(const char* path, mode_t mode) | int creat(const char* path, mode_t mode) | ||||||
| { | { | ||||||
|     return open(path, O_CREAT, mode); |     return open(path, O_CREAT | O_WRONLY | O_TRUNC, mode); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int open(const char* path, int options, ...) | int open(const char* path, int options, ...) | ||||||
|  |  | ||||||
|  | @ -645,7 +645,7 @@ void GTextEditor::Line::truncate(int length) | ||||||
| 
 | 
 | ||||||
| bool GTextEditor::write_to_file(const String& path) | bool GTextEditor::write_to_file(const String& path) | ||||||
| { | { | ||||||
|     int fd = open(path.characters(), O_WRONLY | O_CREAT, 0666); |     int fd = open(path.characters(), O_WRONLY | O_CREAT | O_TRUNC, 0666); | ||||||
|     if (fd < 0) { |     if (fd < 0) { | ||||||
|         perror("open"); |         perror("open"); | ||||||
|         return false; |         return false; | ||||||
|  |  | ||||||
|  | @ -143,7 +143,7 @@ RetainPtr<Font> Font::load_from_file(const String& path) | ||||||
| 
 | 
 | ||||||
| bool Font::write_to_file(const String& path) | bool Font::write_to_file(const String& path) | ||||||
| { | { | ||||||
|     int fd = open(path.characters(), O_WRONLY | O_CREAT, 0644); |     int fd = creat(path.characters(), 0644); | ||||||
|     if (fd < 0) { |     if (fd < 0) { | ||||||
|         perror("open"); |         perror("open"); | ||||||
|         return false; |         return false; | ||||||
|  |  | ||||||
|  | @ -34,7 +34,7 @@ int main(int argc, char** argv) | ||||||
|         return 1; |         return 1; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     int dst_fd = open(dst_path.characters(), O_WRONLY | O_CREAT, 0666); |     int dst_fd = creat(dst_path.characters(), 0666); | ||||||
|     if (dst_fd < 0) { |     if (dst_fd < 0) { | ||||||
|         if (errno != EISDIR) { |         if (errno != EISDIR) { | ||||||
|             perror("open dst"); |             perror("open dst"); | ||||||
|  | @ -45,7 +45,7 @@ int main(int argc, char** argv) | ||||||
|         builder.append('/'); |         builder.append('/'); | ||||||
|         builder.append(FileSystemPath(src_path).basename()); |         builder.append(FileSystemPath(src_path).basename()); | ||||||
|         dst_path = builder.to_string(); |         dst_path = builder.to_string(); | ||||||
|         dst_fd = open(dst_path.characters(), O_WRONLY | O_CREAT, 0666); |         dst_fd = creat(dst_path.characters(), 0666); | ||||||
|         if (dst_fd < 0) { |         if (dst_fd < 0) { | ||||||
|             perror("open dst"); |             perror("open dst"); | ||||||
|             return 1; |             return 1; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling