mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 20:47:45 +00:00
Kernel: Move FIFO into FileSystem/ and Socket+LocalSocket into Net/.
This commit is contained in:
parent
f2580dcfeb
commit
644c887594
15 changed files with 20 additions and 20 deletions
79
Kernel/FileSystem/FIFO.cpp
Normal file
79
Kernel/FileSystem/FIFO.cpp
Normal file
|
@ -0,0 +1,79 @@
|
|||
#include <Kernel/FileSystem/FIFO.h>
|
||||
#include <AK/StdLibExtras.h>
|
||||
|
||||
//#define FIFO_DEBUG
|
||||
|
||||
Retained<FIFO> FIFO::create()
|
||||
{
|
||||
return adopt(*new FIFO);
|
||||
}
|
||||
|
||||
FIFO::FIFO()
|
||||
{
|
||||
}
|
||||
|
||||
void FIFO::open(Direction direction)
|
||||
{
|
||||
if (direction == Reader) {
|
||||
++m_readers;
|
||||
#ifdef FIFO_DEBUG
|
||||
kprintf("open reader (%u)\n", m_readers);
|
||||
#endif
|
||||
} else if (direction == Writer) {
|
||||
++m_writers;
|
||||
#ifdef FIFO_DEBUG
|
||||
kprintf("open writer (%u)\n", m_writers);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void FIFO::close(Direction direction)
|
||||
{
|
||||
if (direction == Reader) {
|
||||
#ifdef FIFO_DEBUG
|
||||
kprintf("close reader (%u - 1)\n", m_readers);
|
||||
#endif
|
||||
ASSERT(m_readers);
|
||||
--m_readers;
|
||||
} else if (direction == Writer) {
|
||||
#ifdef FIFO_DEBUG
|
||||
kprintf("close writer (%u - 1)\n", m_writers);
|
||||
#endif
|
||||
ASSERT(m_writers);
|
||||
--m_writers;
|
||||
}
|
||||
}
|
||||
|
||||
bool FIFO::can_read() const
|
||||
{
|
||||
return !m_buffer.is_empty() || !m_writers;
|
||||
}
|
||||
|
||||
bool FIFO::can_write() const
|
||||
{
|
||||
return m_buffer.bytes_in_write_buffer() < 4096;
|
||||
}
|
||||
|
||||
ssize_t FIFO::read(byte* buffer, ssize_t size)
|
||||
{
|
||||
if (!m_writers && m_buffer.is_empty())
|
||||
return 0;
|
||||
#ifdef FIFO_DEBUG
|
||||
dbgprintf("fifo: read(%u)\n",size);
|
||||
#endif
|
||||
ssize_t nread = m_buffer.read(buffer, size);
|
||||
#ifdef FIFO_DEBUG
|
||||
dbgprintf(" -> read (%c) %u\n", buffer[0], nread);
|
||||
#endif
|
||||
return nread;
|
||||
}
|
||||
|
||||
ssize_t FIFO::write(const byte* buffer, ssize_t size)
|
||||
{
|
||||
if (!m_readers)
|
||||
return 0;
|
||||
#ifdef FIFO_DEBUG
|
||||
dbgprintf("fifo: write(%p, %u)\n", buffer, size);
|
||||
#endif
|
||||
return m_buffer.write(buffer, size);
|
||||
}
|
31
Kernel/FileSystem/FIFO.h
Normal file
31
Kernel/FileSystem/FIFO.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
#pragma once
|
||||
|
||||
#include "DoubleBuffer.h"
|
||||
#include <AK/Retainable.h>
|
||||
#include <AK/RetainPtr.h>
|
||||
#include <Kernel/UnixTypes.h>
|
||||
|
||||
class FIFO : public Retainable<FIFO> {
|
||||
public:
|
||||
enum Direction {
|
||||
Neither, Reader, Writer
|
||||
};
|
||||
|
||||
static Retained<FIFO> create();
|
||||
|
||||
void open(Direction);
|
||||
void close(Direction);
|
||||
|
||||
ssize_t write(const byte*, ssize_t);
|
||||
ssize_t read(byte*, ssize_t);
|
||||
|
||||
bool can_read() const;
|
||||
bool can_write() const;
|
||||
|
||||
private:
|
||||
FIFO();
|
||||
|
||||
unsigned m_writers { 0 };
|
||||
unsigned m_readers { 0 };
|
||||
DoubleBuffer m_buffer;
|
||||
};
|
441
Kernel/FileSystem/FileDescriptor.cpp
Normal file
441
Kernel/FileSystem/FileDescriptor.cpp
Normal file
|
@ -0,0 +1,441 @@
|
|||
#include "FileDescriptor.h"
|
||||
#include <Kernel/FileSystem/FileSystem.h>
|
||||
#include <Kernel/Devices/CharacterDevice.h>
|
||||
#include <LibC/errno_numbers.h>
|
||||
#include "UnixTypes.h"
|
||||
#include <AK/BufferStream.h>
|
||||
#include <Kernel/FileSystem/FIFO.h>
|
||||
#include <Kernel/TTY/TTY.h>
|
||||
#include <Kernel/TTY/MasterPTY.h>
|
||||
#include <Kernel/Net/Socket.h>
|
||||
#include <Kernel/Process.h>
|
||||
#include <Kernel/Devices/BlockDevice.h>
|
||||
#include <Kernel/VM/MemoryManager.h>
|
||||
|
||||
Retained<FileDescriptor> FileDescriptor::create(RetainPtr<Inode>&& inode)
|
||||
{
|
||||
return adopt(*new FileDescriptor(move(inode)));
|
||||
}
|
||||
|
||||
Retained<FileDescriptor> FileDescriptor::create(RetainPtr<Device>&& device)
|
||||
{
|
||||
return adopt(*new FileDescriptor(move(device)));
|
||||
}
|
||||
|
||||
Retained<FileDescriptor> FileDescriptor::create(RetainPtr<Socket>&& socket, SocketRole role)
|
||||
{
|
||||
return adopt(*new FileDescriptor(move(socket), role));
|
||||
}
|
||||
|
||||
Retained<FileDescriptor> FileDescriptor::create_pipe_writer(FIFO& fifo)
|
||||
{
|
||||
return adopt(*new FileDescriptor(fifo, FIFO::Writer));
|
||||
}
|
||||
|
||||
Retained<FileDescriptor> FileDescriptor::create_pipe_reader(FIFO& fifo)
|
||||
{
|
||||
return adopt(*new FileDescriptor(fifo, FIFO::Reader));
|
||||
}
|
||||
|
||||
FileDescriptor::FileDescriptor(RetainPtr<Inode>&& inode)
|
||||
: m_inode(move(inode))
|
||||
{
|
||||
}
|
||||
|
||||
FileDescriptor::FileDescriptor(RetainPtr<Device>&& device)
|
||||
: m_device(move(device))
|
||||
{
|
||||
}
|
||||
|
||||
FileDescriptor::FileDescriptor(RetainPtr<Socket>&& socket, SocketRole role)
|
||||
: m_socket(move(socket))
|
||||
{
|
||||
set_socket_role(role);
|
||||
}
|
||||
|
||||
FileDescriptor::~FileDescriptor()
|
||||
{
|
||||
if (m_socket) {
|
||||
m_socket->detach_fd(m_socket_role);
|
||||
m_socket = nullptr;
|
||||
}
|
||||
if (m_device) {
|
||||
m_device->close();
|
||||
m_device = nullptr;
|
||||
}
|
||||
if (m_fifo) {
|
||||
m_fifo->close(fifo_direction());
|
||||
m_fifo = nullptr;
|
||||
}
|
||||
m_inode = nullptr;
|
||||
}
|
||||
|
||||
void FileDescriptor::set_socket_role(SocketRole role)
|
||||
{
|
||||
if (role == m_socket_role)
|
||||
return;
|
||||
|
||||
ASSERT(m_socket);
|
||||
auto old_socket_role = m_socket_role;
|
||||
m_socket_role = role;
|
||||
m_socket->attach_fd(role);
|
||||
if (old_socket_role != SocketRole::None)
|
||||
m_socket->detach_fd(old_socket_role);
|
||||
}
|
||||
|
||||
Retained<FileDescriptor> FileDescriptor::clone()
|
||||
{
|
||||
RetainPtr<FileDescriptor> descriptor;
|
||||
if (is_fifo()) {
|
||||
descriptor = fifo_direction() == FIFO::Reader
|
||||
? FileDescriptor::create_pipe_reader(*m_fifo)
|
||||
: FileDescriptor::create_pipe_writer(*m_fifo);
|
||||
} else {
|
||||
if (m_device) {
|
||||
descriptor = FileDescriptor::create(m_device.copy_ref());
|
||||
descriptor->m_inode = m_inode.copy_ref();
|
||||
} else if (m_socket) {
|
||||
descriptor = FileDescriptor::create(m_socket.copy_ref(), m_socket_role);
|
||||
descriptor->m_inode = m_inode.copy_ref();
|
||||
} else {
|
||||
descriptor = FileDescriptor::create(m_inode.copy_ref());
|
||||
}
|
||||
}
|
||||
ASSERT(descriptor);
|
||||
descriptor->m_current_offset = m_current_offset;
|
||||
descriptor->m_is_blocking = m_is_blocking;
|
||||
descriptor->m_file_flags = m_file_flags;
|
||||
return *descriptor;
|
||||
}
|
||||
|
||||
bool addition_would_overflow(off_t a, off_t b)
|
||||
{
|
||||
ASSERT(a > 0);
|
||||
uint64_t ua = a;
|
||||
return (ua + b) > OFF_T_MAX;
|
||||
}
|
||||
|
||||
KResult FileDescriptor::fstat(stat& buffer)
|
||||
{
|
||||
ASSERT(!is_fifo());
|
||||
if (!m_inode && !m_device)
|
||||
return KResult(-EBADF);
|
||||
|
||||
auto metadata = this->metadata();
|
||||
if (!metadata.is_valid())
|
||||
return KResult(-EIO);
|
||||
|
||||
buffer.st_rdev = encoded_device(metadata.major_device, metadata.minor_device);
|
||||
buffer.st_ino = metadata.inode.index();
|
||||
buffer.st_mode = metadata.mode;
|
||||
buffer.st_nlink = metadata.link_count;
|
||||
buffer.st_uid = metadata.uid;
|
||||
buffer.st_gid = metadata.gid;
|
||||
buffer.st_dev = 0; // FIXME
|
||||
buffer.st_size = metadata.size;
|
||||
buffer.st_blksize = metadata.block_size;
|
||||
buffer.st_blocks = metadata.block_count;
|
||||
buffer.st_atime = metadata.atime;
|
||||
buffer.st_mtime = metadata.mtime;
|
||||
buffer.st_ctime = metadata.ctime;
|
||||
return KSuccess;
|
||||
}
|
||||
|
||||
KResult FileDescriptor::fchmod(mode_t mode)
|
||||
{
|
||||
if (!m_inode)
|
||||
return KResult(-EBADF);
|
||||
return VFS::the().chmod(*m_inode, mode);
|
||||
}
|
||||
|
||||
off_t FileDescriptor::seek(off_t offset, int whence)
|
||||
{
|
||||
ASSERT(!is_fifo());
|
||||
if (!m_inode && !m_device)
|
||||
return -EBADF;
|
||||
|
||||
// FIXME: The file type should be cached on the vnode.
|
||||
// It's silly that we have to do a full metadata lookup here.
|
||||
auto metadata = this->metadata();
|
||||
if (!metadata.is_valid())
|
||||
return -EIO;
|
||||
|
||||
if (metadata.is_socket() || metadata.is_fifo())
|
||||
return -ESPIPE;
|
||||
|
||||
off_t newOffset;
|
||||
|
||||
switch (whence) {
|
||||
case SEEK_SET:
|
||||
newOffset = offset;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
newOffset = m_current_offset + offset;
|
||||
if (newOffset < 0)
|
||||
return -EINVAL;
|
||||
break;
|
||||
case SEEK_END:
|
||||
ASSERT(metadata.size); // FIXME: What do I do?
|
||||
newOffset = metadata.size;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
m_current_offset = newOffset;
|
||||
return m_current_offset;
|
||||
}
|
||||
|
||||
ssize_t FileDescriptor::read(Process& process, byte* buffer, ssize_t count)
|
||||
{
|
||||
if (is_fifo()) {
|
||||
ASSERT(fifo_direction() == FIFO::Reader);
|
||||
return m_fifo->read(buffer, count);
|
||||
}
|
||||
if (m_device) {
|
||||
// FIXME: What should happen to m_currentOffset?
|
||||
return m_device->read(process, buffer, count);
|
||||
}
|
||||
if (m_socket)
|
||||
return m_socket->read(m_socket_role, buffer, count);
|
||||
ASSERT(inode());
|
||||
ssize_t nread = inode()->read_bytes(m_current_offset, count, buffer, this);
|
||||
m_current_offset += nread;
|
||||
return nread;
|
||||
}
|
||||
|
||||
ssize_t FileDescriptor::write(Process& process, const byte* data, ssize_t size)
|
||||
{
|
||||
if (is_fifo()) {
|
||||
ASSERT(fifo_direction() == FIFO::Writer);
|
||||
return m_fifo->write(data, size);
|
||||
}
|
||||
if (m_device) {
|
||||
// FIXME: What should happen to m_currentOffset?
|
||||
return m_device->write(process, data, size);
|
||||
}
|
||||
if (m_socket)
|
||||
return m_socket->write(m_socket_role, data, size);
|
||||
ASSERT(m_inode);
|
||||
ssize_t nwritten = m_inode->write_bytes(m_current_offset, size, data, this);
|
||||
m_current_offset += nwritten;
|
||||
return nwritten;
|
||||
}
|
||||
|
||||
bool FileDescriptor::can_write(Process& process)
|
||||
{
|
||||
if (is_fifo()) {
|
||||
ASSERT(fifo_direction() == FIFO::Writer);
|
||||
return m_fifo->can_write();
|
||||
}
|
||||
if (m_device)
|
||||
return m_device->can_write(process);
|
||||
if (m_socket)
|
||||
return m_socket->can_write(m_socket_role);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FileDescriptor::can_read(Process& process)
|
||||
{
|
||||
if (is_fifo()) {
|
||||
ASSERT(fifo_direction() == FIFO::Reader);
|
||||
return m_fifo->can_read();
|
||||
}
|
||||
if (m_device)
|
||||
return m_device->can_read(process);
|
||||
if (m_socket)
|
||||
return m_socket->can_read(m_socket_role);
|
||||
return true;
|
||||
}
|
||||
|
||||
ByteBuffer FileDescriptor::read_entire_file(Process& process)
|
||||
{
|
||||
ASSERT(!is_fifo());
|
||||
|
||||
if (m_device) {
|
||||
auto buffer = ByteBuffer::create_uninitialized(1024);
|
||||
ssize_t nread = m_device->read(process, buffer.pointer(), buffer.size());
|
||||
ASSERT(nread >= 0);
|
||||
buffer.trim(nread);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
ASSERT(m_inode);
|
||||
return m_inode->read_entire(this);
|
||||
}
|
||||
|
||||
bool FileDescriptor::is_directory() const
|
||||
{
|
||||
ASSERT(!is_fifo());
|
||||
return metadata().is_directory();
|
||||
}
|
||||
|
||||
ssize_t FileDescriptor::get_dir_entries(byte* buffer, ssize_t size)
|
||||
{
|
||||
auto metadata = this->metadata();
|
||||
if (!metadata.is_valid())
|
||||
return -EIO;
|
||||
if (!metadata.is_directory())
|
||||
return -ENOTDIR;
|
||||
|
||||
int size_to_allocate = max(PAGE_SIZE, metadata.size);
|
||||
|
||||
auto temp_buffer = ByteBuffer::create_uninitialized(size_to_allocate);
|
||||
BufferStream stream(temp_buffer);
|
||||
VFS::the().traverse_directory_inode(*m_inode, [&stream] (auto& entry) {
|
||||
stream << (dword)entry.inode.index();
|
||||
stream << (byte)entry.file_type;
|
||||
stream << (dword)entry.name_length;
|
||||
stream << entry.name;
|
||||
return true;
|
||||
});
|
||||
stream.snip();
|
||||
|
||||
if (size < temp_buffer.size())
|
||||
return -1;
|
||||
|
||||
memcpy(buffer, temp_buffer.pointer(), temp_buffer.size());
|
||||
return stream.offset();
|
||||
}
|
||||
|
||||
bool FileDescriptor::is_tty() const
|
||||
{
|
||||
return m_device && m_device->is_tty();
|
||||
}
|
||||
|
||||
const TTY* FileDescriptor::tty() const
|
||||
{
|
||||
if (!is_tty())
|
||||
return nullptr;
|
||||
return static_cast<const TTY*>(m_device.ptr());
|
||||
}
|
||||
|
||||
TTY* FileDescriptor::tty()
|
||||
{
|
||||
if (!is_tty())
|
||||
return nullptr;
|
||||
return static_cast<TTY*>(m_device.ptr());
|
||||
}
|
||||
|
||||
bool FileDescriptor::is_master_pty() const
|
||||
{
|
||||
if (m_device)
|
||||
return m_device->is_master_pty();
|
||||
return false;
|
||||
}
|
||||
|
||||
const MasterPTY* FileDescriptor::master_pty() const
|
||||
{
|
||||
if (!is_master_pty())
|
||||
return nullptr;
|
||||
return static_cast<const MasterPTY*>(m_device.ptr());
|
||||
}
|
||||
|
||||
MasterPTY* FileDescriptor::master_pty()
|
||||
{
|
||||
if (!is_master_pty())
|
||||
return nullptr;
|
||||
return static_cast<MasterPTY*>(m_device.ptr());
|
||||
}
|
||||
|
||||
int FileDescriptor::close()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* to_string(SocketRole role)
|
||||
{
|
||||
switch (role) {
|
||||
case SocketRole::Listener:
|
||||
return "Listener";
|
||||
case SocketRole::Accepted:
|
||||
return "Accepted";
|
||||
case SocketRole::Connected:
|
||||
return "Connected";
|
||||
default:
|
||||
return "None";
|
||||
}
|
||||
}
|
||||
|
||||
KResultOr<String> FileDescriptor::absolute_path()
|
||||
{
|
||||
Stopwatch sw("absolute_path");
|
||||
if (is_tty())
|
||||
return tty()->tty_name();
|
||||
if (is_fifo())
|
||||
return String::format("fifo:%x", m_fifo.ptr());
|
||||
if (is_device())
|
||||
return String::format("device:%u,%u (%s)", m_device->major(), m_device->minor(), m_device->class_name());
|
||||
if (is_socket())
|
||||
return String::format("socket:%x (role: %s)", m_socket.ptr(), to_string(m_socket_role));
|
||||
ASSERT(m_inode);
|
||||
return VFS::the().absolute_path(*m_inode);
|
||||
}
|
||||
|
||||
FileDescriptor::FileDescriptor(FIFO& fifo, FIFO::Direction direction)
|
||||
: m_is_blocking(true)
|
||||
, m_fifo(fifo)
|
||||
, m_fifo_direction(direction)
|
||||
{
|
||||
m_fifo->open(direction);
|
||||
}
|
||||
|
||||
InodeMetadata FileDescriptor::metadata() const
|
||||
{
|
||||
if (m_inode)
|
||||
return m_inode->metadata();
|
||||
return { };
|
||||
}
|
||||
|
||||
bool FileDescriptor::supports_mmap() const
|
||||
{
|
||||
if (m_inode)
|
||||
return true;
|
||||
if (m_device)
|
||||
return m_device->is_block_device();
|
||||
return false;
|
||||
}
|
||||
|
||||
Region* FileDescriptor::mmap(Process& process, LinearAddress laddr, size_t offset, size_t size, int prot)
|
||||
{
|
||||
ASSERT(supports_mmap());
|
||||
|
||||
if (is_block_device())
|
||||
return static_cast<BlockDevice&>(*m_device).mmap(process, laddr, offset, size);
|
||||
|
||||
ASSERT(m_inode);
|
||||
// FIXME: If PROT_EXEC, check that the underlying file system isn't mounted noexec.
|
||||
String region_name;
|
||||
#if 0
|
||||
// FIXME: I would like to do this, but it would instantiate all the damn inodes.
|
||||
region_name = absolute_path();
|
||||
#else
|
||||
region_name = "Memory-mapped file";
|
||||
#endif
|
||||
InterruptDisabler disabler;
|
||||
// FIXME: Implement mapping at a client-specified address. Most of the support is already in plcae.
|
||||
ASSERT(laddr.as_ptr() == nullptr);
|
||||
auto* region = process.allocate_file_backed_region(LinearAddress(), size, inode(), move(region_name), prot & PROT_READ, prot & PROT_WRITE);
|
||||
region->page_in();
|
||||
return region;
|
||||
}
|
||||
|
||||
bool FileDescriptor::is_block_device() const
|
||||
{
|
||||
return m_device && m_device->is_block_device();
|
||||
}
|
||||
|
||||
bool FileDescriptor::is_character_device() const
|
||||
{
|
||||
return m_device && m_device->is_character_device();
|
||||
}
|
||||
|
||||
CharacterDevice* FileDescriptor::character_device()
|
||||
{
|
||||
return is_character_device() ? static_cast<CharacterDevice*>(device()) : nullptr;
|
||||
}
|
||||
|
||||
const CharacterDevice* FileDescriptor::character_device() const
|
||||
{
|
||||
return is_character_device() ? static_cast<const CharacterDevice*>(device()) : nullptr;
|
||||
}
|
120
Kernel/FileSystem/FileDescriptor.h
Normal file
120
Kernel/FileSystem/FileDescriptor.h
Normal file
|
@ -0,0 +1,120 @@
|
|||
#pragma once
|
||||
|
||||
#include <Kernel/FileSystem/VirtualFileSystem.h>
|
||||
#include <Kernel/FileSystem/InodeMetadata.h>
|
||||
#include <Kernel/FileSystem/FIFO.h>
|
||||
#include <Kernel/LinearAddress.h>
|
||||
#include <AK/ByteBuffer.h>
|
||||
#include <AK/CircularQueue.h>
|
||||
#include <AK/Retainable.h>
|
||||
#include <AK/Badge.h>
|
||||
#include <Kernel/Net/Socket.h>
|
||||
|
||||
class TTY;
|
||||
class MasterPTY;
|
||||
class Process;
|
||||
class Region;
|
||||
class CharacterDevice;
|
||||
|
||||
class FileDescriptor : public Retainable<FileDescriptor> {
|
||||
public:
|
||||
|
||||
static Retained<FileDescriptor> create(RetainPtr<Socket>&&, SocketRole = SocketRole::None);
|
||||
static Retained<FileDescriptor> create(RetainPtr<Inode>&&);
|
||||
static Retained<FileDescriptor> create(RetainPtr<Device>&&);
|
||||
static Retained<FileDescriptor> create_pipe_writer(FIFO&);
|
||||
static Retained<FileDescriptor> create_pipe_reader(FIFO&);
|
||||
~FileDescriptor();
|
||||
|
||||
Retained<FileDescriptor> clone();
|
||||
|
||||
int close();
|
||||
|
||||
off_t seek(off_t, int whence);
|
||||
ssize_t read(Process&, byte*, ssize_t);
|
||||
ssize_t write(Process&, const byte* data, ssize_t);
|
||||
KResult fstat(stat&);
|
||||
|
||||
KResult fchmod(mode_t);
|
||||
|
||||
bool can_read(Process&);
|
||||
bool can_write(Process&);
|
||||
|
||||
ssize_t get_dir_entries(byte* buffer, ssize_t);
|
||||
|
||||
ByteBuffer read_entire_file(Process&);
|
||||
|
||||
KResultOr<String> absolute_path();
|
||||
|
||||
bool is_directory() const;
|
||||
|
||||
bool is_device() const { return m_device.ptr(); }
|
||||
Device* device() { return m_device.ptr(); }
|
||||
const Device* device() const { return m_device.ptr(); }
|
||||
|
||||
bool is_block_device() const;
|
||||
bool is_character_device() const;
|
||||
CharacterDevice* character_device();
|
||||
const CharacterDevice* character_device() const;
|
||||
|
||||
bool is_tty() const;
|
||||
const TTY* tty() const;
|
||||
TTY* tty();
|
||||
|
||||
bool is_master_pty() const;
|
||||
const MasterPTY* master_pty() const;
|
||||
MasterPTY* master_pty();
|
||||
|
||||
InodeMetadata metadata() const;
|
||||
Inode* inode() { return m_inode.ptr(); }
|
||||
const Inode* inode() const { return m_inode.ptr(); }
|
||||
|
||||
bool supports_mmap() const;
|
||||
Region* mmap(Process&, LinearAddress, size_t offset, size_t, int prot);
|
||||
|
||||
bool is_blocking() const { return m_is_blocking; }
|
||||
void set_blocking(bool b) { m_is_blocking = b; }
|
||||
|
||||
dword file_flags() const { return m_file_flags; }
|
||||
void set_file_flags(dword flags) { m_file_flags = flags; }
|
||||
|
||||
bool is_socket() const { return m_socket; }
|
||||
Socket* socket() { return m_socket.ptr(); }
|
||||
const Socket* socket() const { return m_socket.ptr(); }
|
||||
|
||||
bool is_fifo() const { return m_fifo; }
|
||||
FIFO::Direction fifo_direction() { return m_fifo_direction; }
|
||||
|
||||
ByteBuffer& generator_cache() { return m_generator_cache; }
|
||||
|
||||
void set_original_inode(Badge<VFS>, Retained<Inode>&& inode) { m_inode = move(inode); }
|
||||
|
||||
SocketRole socket_role() const { return m_socket_role; }
|
||||
void set_socket_role(SocketRole);
|
||||
|
||||
private:
|
||||
friend class VFS;
|
||||
FileDescriptor(RetainPtr<Socket>&&, SocketRole);
|
||||
explicit FileDescriptor(RetainPtr<Inode>&&);
|
||||
explicit FileDescriptor(RetainPtr<Device>&&);
|
||||
FileDescriptor(FIFO&, FIFO::Direction);
|
||||
|
||||
RetainPtr<Inode> m_inode;
|
||||
RetainPtr<Device> m_device;
|
||||
|
||||
off_t m_current_offset { 0 };
|
||||
|
||||
ByteBuffer m_generator_cache;
|
||||
|
||||
bool m_is_blocking { true };
|
||||
dword m_file_flags { 0 };
|
||||
|
||||
RetainPtr<Socket> m_socket;
|
||||
SocketRole m_socket_role { SocketRole::None };
|
||||
|
||||
RetainPtr<FIFO> m_fifo;
|
||||
FIFO::Direction m_fifo_direction { FIFO::Neither };
|
||||
|
||||
bool m_closed { false };
|
||||
};
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
#include <LibC/errno_numbers.h>
|
||||
#include "FileSystem.h"
|
||||
#include <Kernel/VM/MemoryManager.h>
|
||||
#include <Kernel/LocalSocket.h>
|
||||
#include <Kernel/Net/LocalSocket.h>
|
||||
|
||||
static dword s_lastFileSystemID;
|
||||
static HashMap<dword, FS*>* s_fs_map;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include <Kernel/FileSystem/SyntheticFileSystem.h>
|
||||
#include <Kernel/FileDescriptor.h>
|
||||
#include <Kernel/FileSystem/FileDescriptor.h>
|
||||
#include <LibC/errno_numbers.h>
|
||||
#include <AK/StdLibExtras.h>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "VirtualFileSystem.h"
|
||||
#include "FileDescriptor.h"
|
||||
#include <Kernel/FileSystem/FileDescriptor.h>
|
||||
#include "FileSystem.h"
|
||||
#include <AK/FileSystemPath.h>
|
||||
#include <AK/StringBuilder.h>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue