فهرست منبع

LibC: Implement __freading and __fwriting

These functions are used by gnulib (and therefore many GNU utilities)
to provide access to internal details of the stdio FILE structure.
Tim Schumacher 4 سال پیش
والد
کامیت
a3b4e43dd8
2فایلهای تغییر یافته به همراه57 افزوده شده و 0 حذف شده
  1. 41 0
      Userland/Libraries/LibC/stdio.cpp
  2. 16 0
      Userland/Libraries/LibC/stdio_ext.h

+ 41 - 0
Userland/Libraries/LibC/stdio.cpp

@@ -16,6 +16,7 @@
 #include <fcntl.h>
 #include <stdarg.h>
 #include <stdio.h>
+#include <stdio_ext.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/internals.h>
@@ -43,6 +44,8 @@ public:
 
     int fileno() const { return m_fd; }
     bool eof() const { return m_eof; }
+    int mode() const { return m_mode; }
+    u8 flags() const { return m_flags; }
 
     int error() const { return m_error; }
     void clear_err() { m_error = 0; }
@@ -61,6 +64,12 @@ public:
 
     void reopen(int fd, int mode);
 
+    enum Flags : u8 {
+        None = 0,
+        LastRead = 1,
+        LastWrite = 2,
+    };
+
 private:
     struct Buffer {
         // A ringbuffer that also transparently implements ungetc().
@@ -117,6 +126,7 @@ private:
 
     int m_fd { -1 };
     int m_mode { 0 };
+    u8 m_flags { Flags::None };
     int m_error { 0 };
     bool m_eof { false };
     pid_t m_popen_child { -1 };
@@ -241,6 +251,9 @@ size_t FILE::read(u8* data, size_t size)
 {
     size_t total_read = 0;
 
+    m_flags |= Flags::LastRead;
+    m_flags &= ~Flags::LastWrite;
+
     while (size > 0) {
         size_t actual_size;
 
@@ -280,6 +293,9 @@ size_t FILE::write(const u8* data, size_t size)
 {
     size_t total_written = 0;
 
+    m_flags &= ~Flags::LastRead;
+    m_flags |= Flags::LastWrite;
+
     while (size > 0) {
         size_t actual_size;
 
@@ -332,6 +348,9 @@ bool FILE::gets(u8* data, size_t size)
     if (size == 0)
         return false;
 
+    m_flags |= Flags::LastRead;
+    m_flags &= ~Flags::LastWrite;
+
     while (size > 1) {
         if (m_buffer.may_use()) {
             // Let's see if the buffer has something queued for us.
@@ -1282,4 +1301,26 @@ FILE* tmpfile()
     unlink(tmp_path);
     return fdopen(fd, "rw");
 }
+
+int __freading(FILE* stream)
+{
+    ScopedFileLock lock(stream);
+
+    if ((stream->mode() & O_RDWR) == O_RDONLY) {
+        return 1;
+    }
+
+    return (stream->flags() & FILE::Flags::LastRead);
+}
+
+int __fwriting(FILE* stream)
+{
+    ScopedFileLock lock(stream);
+
+    if ((stream->mode() & O_RDWR) == O_WRONLY) {
+        return 1;
+    }
+
+    return (stream->flags() & FILE::Flags::LastWrite);
+}
 }

+ 16 - 0
Userland/Libraries/LibC/stdio_ext.h

@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2021, the SerenityOS developers
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <stdio.h>
+
+__BEGIN_DECLS
+
+int __freading(FILE*);
+int __fwriting(FILE*);
+
+__END_DECLS