mirror of
https://github.com/RGBCube/serenity
synced 2025-05-14 09:04:59 +00:00
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.
This commit is contained in:
parent
a49c77b76d
commit
a3b4e43dd8
2 changed files with 57 additions and 0 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue