|
@@ -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);
|
|
|
+}
|
|
|
}
|