Browse Source

Kernel: Support O_APPEND

As per the manpage, this acts as a transparent lseek() before write.
Robin Burchell 6 years ago
parent
commit
c6e79bd53a
3 changed files with 13 additions and 2 deletions
  1. 1 0
      Kernel/FileSystem/FileDescriptor.cpp
  2. 3 0
      Kernel/FileSystem/FileDescriptor.h
  3. 9 2
      Kernel/Process.cpp

+ 1 - 0
Kernel/FileSystem/FileDescriptor.cpp

@@ -75,6 +75,7 @@ Retained<FileDescriptor> FileDescriptor::clone()
     ASSERT(descriptor);
     ASSERT(descriptor);
     descriptor->m_current_offset = m_current_offset;
     descriptor->m_current_offset = m_current_offset;
     descriptor->m_is_blocking = m_is_blocking;
     descriptor->m_is_blocking = m_is_blocking;
+    descriptor->m_should_append = m_should_append;
     descriptor->m_file_flags = m_file_flags;
     descriptor->m_file_flags = m_file_flags;
     return *descriptor;
     return *descriptor;
 }
 }

+ 3 - 0
Kernel/FileSystem/FileDescriptor.h

@@ -70,6 +70,8 @@ public:
 
 
     bool is_blocking() const { return m_is_blocking; }
     bool is_blocking() const { return m_is_blocking; }
     void set_blocking(bool b) { m_is_blocking = b; }
     void set_blocking(bool b) { m_is_blocking = b; }
+    bool should_append() const { return m_should_append; }
+    void set_should_append(bool s) { m_should_append = s; }
 
 
     dword file_flags() const { return m_file_flags; }
     dword file_flags() const { return m_file_flags; }
     void set_file_flags(dword flags) { m_file_flags = flags; }
     void set_file_flags(dword flags) { m_file_flags = flags; }
@@ -113,6 +115,7 @@ private:
     dword m_file_flags { 0 };
     dword m_file_flags { 0 };
 
 
     bool m_is_blocking { true };
     bool m_is_blocking { true };
+    bool m_should_append { false };
     SocketRole m_socket_role { SocketRole::None };
     SocketRole m_socket_role { SocketRole::None };
     FIFO::Direction m_fifo_direction { FIFO::Direction::Neither };
     FIFO::Direction m_fifo_direction { FIFO::Direction::Neither };
 };
 };

+ 9 - 2
Kernel/Process.cpp

@@ -861,6 +861,13 @@ ssize_t Process::do_write(FileDescriptor& descriptor, const byte* data, int data
             return -EAGAIN;
             return -EAGAIN;
     }
     }
 
 
+    if (descriptor.should_append()) {
+#ifdef IO_DEBUG
+        dbgprintf("seeking to end (O_APPEND)\n");
+#endif
+        descriptor.seek(0, SEEK_END);
+    }
+
     while (nwritten < data_size) {
     while (nwritten < data_size) {
 #ifdef IO_DEBUG
 #ifdef IO_DEBUG
         dbgprintf("while %u < %u\n", nwritten, size);
         dbgprintf("while %u < %u\n", nwritten, size);
@@ -1118,8 +1125,8 @@ int Process::sys$open(const char* path, int options, mode_t mode)
     auto descriptor = result.value();
     auto descriptor = result.value();
     if (options & O_DIRECTORY && !descriptor->is_directory())
     if (options & O_DIRECTORY && !descriptor->is_directory())
         return -ENOTDIR; // FIXME: This should be handled by VFS::open.
         return -ENOTDIR; // FIXME: This should be handled by VFS::open.
-    if (options & O_NONBLOCK)
-        descriptor->set_blocking(false);
+    descriptor->set_blocking(!(options & O_NONBLOCK));
+    descriptor->set_should_append(options & O_APPEND);
     dword flags = (options & O_CLOEXEC) ? FD_CLOEXEC : 0;
     dword flags = (options & O_CLOEXEC) ? FD_CLOEXEC : 0;
     m_fds[fd].set(move(descriptor), flags);
     m_fds[fd].set(move(descriptor), flags);
     return fd;
     return fd;