Kernel: Make OpenFileDescriptorSet thread safe
Also this allows concurrent calling of read/write/send/recv
This commit is contained in:
parent
d54489bbcb
commit
c790bad667
|
@ -51,7 +51,7 @@ namespace Kernel
|
||||||
BAN::ErrorOr<size_t> sendto(int fd, BAN::ConstByteSpan buffer, const sockaddr* address, socklen_t address_len);
|
BAN::ErrorOr<size_t> sendto(int fd, BAN::ConstByteSpan buffer, const sockaddr* address, socklen_t address_len);
|
||||||
|
|
||||||
BAN::ErrorOr<VirtualFileSystem::File> file_of(int) const;
|
BAN::ErrorOr<VirtualFileSystem::File> file_of(int) const;
|
||||||
BAN::ErrorOr<BAN::StringView> path_of(int) const;
|
BAN::ErrorOr<BAN::String> path_of(int) const;
|
||||||
BAN::ErrorOr<BAN::RefPtr<Inode>> inode_of(int);
|
BAN::ErrorOr<BAN::RefPtr<Inode>> inode_of(int);
|
||||||
BAN::ErrorOr<int> status_flags_of(int) const;
|
BAN::ErrorOr<int> status_flags_of(int) const;
|
||||||
|
|
||||||
|
@ -98,6 +98,7 @@ namespace Kernel
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Credentials& m_credentials;
|
const Credentials& m_credentials;
|
||||||
|
mutable Mutex m_mutex;
|
||||||
|
|
||||||
BAN::Array<OpenFile, OPEN_MAX> m_open_files;
|
BAN::Array<OpenFile, OPEN_MAX> m_open_files;
|
||||||
};
|
};
|
||||||
|
|
|
@ -23,6 +23,7 @@ namespace Kernel
|
||||||
|
|
||||||
OpenFileDescriptorSet& OpenFileDescriptorSet::operator=(OpenFileDescriptorSet&& other)
|
OpenFileDescriptorSet& OpenFileDescriptorSet::operator=(OpenFileDescriptorSet&& other)
|
||||||
{
|
{
|
||||||
|
LockGuard _(m_mutex);
|
||||||
for (size_t i = 0; i < m_open_files.size(); i++)
|
for (size_t i = 0; i < m_open_files.size(); i++)
|
||||||
m_open_files[i] = BAN::move(other.m_open_files[i]);
|
m_open_files[i] = BAN::move(other.m_open_files[i]);
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -30,6 +31,8 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<void> OpenFileDescriptorSet::clone_from(const OpenFileDescriptorSet& other)
|
BAN::ErrorOr<void> OpenFileDescriptorSet::clone_from(const OpenFileDescriptorSet& other)
|
||||||
{
|
{
|
||||||
|
LockGuard _(m_mutex);
|
||||||
|
|
||||||
close_all();
|
close_all();
|
||||||
|
|
||||||
for (int fd = 0; fd < (int)other.m_open_files.size(); fd++)
|
for (int fd = 0; fd < (int)other.m_open_files.size(); fd++)
|
||||||
|
@ -67,11 +70,11 @@ namespace Kernel
|
||||||
if ((flags & O_TRUNC) && (flags & O_WRONLY) && file.inode->mode().ifreg())
|
if ((flags & O_TRUNC) && (flags & O_WRONLY) && file.inode->mode().ifreg())
|
||||||
TRY(file.inode->truncate(0));
|
TRY(file.inode->truncate(0));
|
||||||
|
|
||||||
|
LockGuard _(m_mutex);
|
||||||
constexpr int status_mask = O_APPEND | O_DSYNC | O_NONBLOCK | O_RSYNC | O_SYNC | O_ACCMODE;
|
constexpr int status_mask = O_APPEND | O_DSYNC | O_NONBLOCK | O_RSYNC | O_SYNC | O_ACCMODE;
|
||||||
int fd = TRY(get_free_fd());
|
int fd = TRY(get_free_fd());
|
||||||
m_open_files[fd].description = TRY(BAN::RefPtr<OpenFileDescription>::create(BAN::move(file), 0, flags & status_mask));
|
m_open_files[fd].description = TRY(BAN::RefPtr<OpenFileDescription>::create(BAN::move(file), 0, flags & status_mask));
|
||||||
m_open_files[fd].descriptor_flags = flags & O_CLOEXEC;
|
m_open_files[fd].descriptor_flags = flags & O_CLOEXEC;
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -135,6 +138,7 @@ namespace Kernel
|
||||||
|
|
||||||
auto socket = TRY(NetworkManager::get().create_socket(sock_domain, sock_type, 0777, m_credentials.euid(), m_credentials.egid()));
|
auto socket = TRY(NetworkManager::get().create_socket(sock_domain, sock_type, 0777, m_credentials.euid(), m_credentials.egid()));
|
||||||
|
|
||||||
|
LockGuard _(m_mutex);
|
||||||
int fd = TRY(get_free_fd());
|
int fd = TRY(get_free_fd());
|
||||||
m_open_files[fd].description = TRY(BAN::RefPtr<OpenFileDescription>::create(VirtualFileSystem::File(socket, "<socket>"_sv), 0, O_RDWR | status_flags));
|
m_open_files[fd].description = TRY(BAN::RefPtr<OpenFileDescription>::create(VirtualFileSystem::File(socket, "<socket>"_sv), 0, O_RDWR | status_flags));
|
||||||
m_open_files[fd].descriptor_flags = descriptor_flags;
|
m_open_files[fd].descriptor_flags = descriptor_flags;
|
||||||
|
@ -143,6 +147,8 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<void> OpenFileDescriptorSet::pipe(int fds[2])
|
BAN::ErrorOr<void> OpenFileDescriptorSet::pipe(int fds[2])
|
||||||
{
|
{
|
||||||
|
LockGuard _(m_mutex);
|
||||||
|
|
||||||
TRY(get_free_fd_pair(fds));
|
TRY(get_free_fd_pair(fds));
|
||||||
|
|
||||||
auto pipe = TRY(Pipe::create(m_credentials));
|
auto pipe = TRY(Pipe::create(m_credentials));
|
||||||
|
@ -159,6 +165,8 @@ namespace Kernel
|
||||||
if (fildes2 < 0 || fildes2 >= (int)m_open_files.size())
|
if (fildes2 < 0 || fildes2 >= (int)m_open_files.size())
|
||||||
return BAN::Error::from_errno(EBADF);
|
return BAN::Error::from_errno(EBADF);
|
||||||
|
|
||||||
|
LockGuard _(m_mutex);
|
||||||
|
|
||||||
TRY(validate_fd(fildes));
|
TRY(validate_fd(fildes));
|
||||||
if (fildes == fildes2)
|
if (fildes == fildes2)
|
||||||
return fildes;
|
return fildes;
|
||||||
|
@ -179,6 +187,8 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<int> OpenFileDescriptorSet::fcntl(int fd, int cmd, int extra)
|
BAN::ErrorOr<int> OpenFileDescriptorSet::fcntl(int fd, int cmd, int extra)
|
||||||
{
|
{
|
||||||
|
LockGuard _(m_mutex);
|
||||||
|
|
||||||
TRY(validate_fd(fd));
|
TRY(validate_fd(fd));
|
||||||
|
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
|
@ -223,6 +233,8 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<off_t> OpenFileDescriptorSet::seek(int fd, off_t offset, int whence)
|
BAN::ErrorOr<off_t> OpenFileDescriptorSet::seek(int fd, off_t offset, int whence)
|
||||||
{
|
{
|
||||||
|
LockGuard _(m_mutex);
|
||||||
|
|
||||||
TRY(validate_fd(fd));
|
TRY(validate_fd(fd));
|
||||||
|
|
||||||
off_t base_offset;
|
off_t base_offset;
|
||||||
|
@ -252,18 +264,22 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<off_t> OpenFileDescriptorSet::tell(int fd) const
|
BAN::ErrorOr<off_t> OpenFileDescriptorSet::tell(int fd) const
|
||||||
{
|
{
|
||||||
|
LockGuard _(m_mutex);
|
||||||
TRY(validate_fd(fd));
|
TRY(validate_fd(fd));
|
||||||
return m_open_files[fd].offset();
|
return m_open_files[fd].offset();
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<void> OpenFileDescriptorSet::truncate(int fd, off_t length)
|
BAN::ErrorOr<void> OpenFileDescriptorSet::truncate(int fd, off_t length)
|
||||||
{
|
{
|
||||||
|
LockGuard _(m_mutex);
|
||||||
TRY(validate_fd(fd));
|
TRY(validate_fd(fd));
|
||||||
return m_open_files[fd].inode()->truncate(length);
|
return m_open_files[fd].inode()->truncate(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<void> OpenFileDescriptorSet::close(int fd)
|
BAN::ErrorOr<void> OpenFileDescriptorSet::close(int fd)
|
||||||
{
|
{
|
||||||
|
LockGuard _(m_mutex);
|
||||||
|
|
||||||
TRY(validate_fd(fd));
|
TRY(validate_fd(fd));
|
||||||
|
|
||||||
if (m_open_files[fd].path() == "<pipe wr>"_sv)
|
if (m_open_files[fd].path() == "<pipe wr>"_sv)
|
||||||
|
@ -280,12 +296,14 @@ namespace Kernel
|
||||||
|
|
||||||
void OpenFileDescriptorSet::close_all()
|
void OpenFileDescriptorSet::close_all()
|
||||||
{
|
{
|
||||||
|
LockGuard _(m_mutex);
|
||||||
for (int fd = 0; fd < (int)m_open_files.size(); fd++)
|
for (int fd = 0; fd < (int)m_open_files.size(); fd++)
|
||||||
(void)close(fd);
|
(void)close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenFileDescriptorSet::close_cloexec()
|
void OpenFileDescriptorSet::close_cloexec()
|
||||||
{
|
{
|
||||||
|
LockGuard _(m_mutex);
|
||||||
for (int fd = 0; fd < (int)m_open_files.size(); fd++)
|
for (int fd = 0; fd < (int)m_open_files.size(); fd++)
|
||||||
{
|
{
|
||||||
if (validate_fd(fd).is_error())
|
if (validate_fd(fd).is_error())
|
||||||
|
@ -297,83 +315,155 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<size_t> OpenFileDescriptorSet::read(int fd, BAN::ByteSpan buffer)
|
BAN::ErrorOr<size_t> OpenFileDescriptorSet::read(int fd, BAN::ByteSpan buffer)
|
||||||
{
|
{
|
||||||
|
BAN::RefPtr<Inode> inode;
|
||||||
|
bool is_nonblock;
|
||||||
|
off_t offset;
|
||||||
|
|
||||||
|
{
|
||||||
|
LockGuard _(m_mutex);
|
||||||
TRY(validate_fd(fd));
|
TRY(validate_fd(fd));
|
||||||
auto& open_file = m_open_files[fd];
|
auto& open_file = m_open_files[fd];
|
||||||
if (open_file.inode()->mode().ifsock())
|
if (open_file.inode()->mode().ifsock())
|
||||||
return recvfrom(fd, buffer, nullptr, nullptr);
|
return recvfrom(fd, buffer, nullptr, nullptr);
|
||||||
if (!(open_file.status_flags() & O_RDONLY))
|
if (!(open_file.status_flags() & O_RDONLY))
|
||||||
return BAN::Error::from_errno(EBADF);
|
return BAN::Error::from_errno(EBADF);
|
||||||
if ((open_file.status_flags() & O_NONBLOCK) && !open_file.inode()->can_read())
|
inode = open_file.inode();
|
||||||
|
is_nonblock = !!(open_file.status_flags() & O_NONBLOCK);
|
||||||
|
offset = open_file.offset();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inode->mode().ifsock())
|
||||||
|
return recvfrom(fd, buffer, nullptr, nullptr);
|
||||||
|
|
||||||
|
size_t nread;
|
||||||
|
{
|
||||||
|
LockGuard _(inode->m_mutex);
|
||||||
|
if (is_nonblock && !inode->can_read())
|
||||||
return 0;
|
return 0;
|
||||||
const size_t nread = TRY(open_file.inode()->read(open_file.offset(), buffer));
|
nread = TRY(inode->read(offset, buffer));
|
||||||
open_file.offset() += nread;
|
}
|
||||||
|
|
||||||
|
LockGuard _(m_mutex);
|
||||||
|
// NOTE: race condition with offset, its UB per POSIX
|
||||||
|
if (!validate_fd(fd).is_error())
|
||||||
|
m_open_files[fd].offset() = offset + nread;
|
||||||
return nread;
|
return nread;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<size_t> OpenFileDescriptorSet::write(int fd, BAN::ConstByteSpan buffer)
|
BAN::ErrorOr<size_t> OpenFileDescriptorSet::write(int fd, BAN::ConstByteSpan buffer)
|
||||||
{
|
{
|
||||||
|
BAN::RefPtr<Inode> inode;
|
||||||
|
bool is_nonblock;
|
||||||
|
off_t offset;
|
||||||
|
|
||||||
|
{
|
||||||
|
LockGuard _(m_mutex);
|
||||||
TRY(validate_fd(fd));
|
TRY(validate_fd(fd));
|
||||||
auto& open_file = m_open_files[fd];
|
auto& open_file = m_open_files[fd];
|
||||||
if (open_file.inode()->mode().ifsock())
|
|
||||||
return sendto(fd, buffer, nullptr, 0);
|
|
||||||
if (!(open_file.status_flags() & O_WRONLY))
|
if (!(open_file.status_flags() & O_WRONLY))
|
||||||
return BAN::Error::from_errno(EBADF);
|
return BAN::Error::from_errno(EBADF);
|
||||||
if ((open_file.status_flags() & O_NONBLOCK) && !open_file.inode()->can_write())
|
inode = open_file.inode();
|
||||||
|
is_nonblock = !!(open_file.status_flags() & O_NONBLOCK);
|
||||||
|
offset = (open_file.status_flags() & O_APPEND) ? inode->size() : open_file.offset();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inode->mode().ifsock())
|
||||||
|
return sendto(fd, buffer, nullptr, 0);
|
||||||
|
|
||||||
|
size_t nwrite;
|
||||||
|
{
|
||||||
|
LockGuard _(inode->m_mutex);
|
||||||
|
if (is_nonblock && !inode->can_write())
|
||||||
return BAN::Error::from_errno(EWOULDBLOCK);
|
return BAN::Error::from_errno(EWOULDBLOCK);
|
||||||
if (open_file.status_flags() & O_APPEND)
|
nwrite = TRY(inode->write(offset, buffer));
|
||||||
open_file.offset() = open_file.inode()->size();
|
}
|
||||||
const size_t nwrite = TRY(open_file.inode()->write(open_file.offset(), buffer));
|
|
||||||
open_file.offset() += nwrite;
|
LockGuard _(m_mutex);
|
||||||
|
// NOTE: race condition with offset, its UB per POSIX
|
||||||
|
if (!validate_fd(fd).is_error())
|
||||||
|
m_open_files[fd].offset() = offset + nwrite;
|
||||||
return nwrite;
|
return nwrite;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<size_t> OpenFileDescriptorSet::read_dir_entries(int fd, struct dirent* list, size_t list_len)
|
BAN::ErrorOr<size_t> OpenFileDescriptorSet::read_dir_entries(int fd, struct dirent* list, size_t list_len)
|
||||||
{
|
{
|
||||||
|
BAN::RefPtr<Inode> inode;
|
||||||
|
off_t offset;
|
||||||
|
|
||||||
|
{
|
||||||
|
LockGuard _(m_mutex);
|
||||||
TRY(validate_fd(fd));
|
TRY(validate_fd(fd));
|
||||||
auto& open_file = m_open_files[fd];
|
auto& open_file = m_open_files[fd];
|
||||||
if (!(open_file.status_flags() & O_RDONLY))
|
if (!(open_file.status_flags() & O_RDONLY))
|
||||||
return BAN::Error::from_errno(EACCES);
|
return BAN::Error::from_errno(EACCES);
|
||||||
|
inode = open_file.inode();
|
||||||
|
offset = open_file.offset();
|
||||||
|
}
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
auto ret = open_file.inode()->list_next_inodes(open_file.offset(), list, list_len);
|
auto ret = inode->list_next_inodes(offset, list, list_len);
|
||||||
if (ret.is_error() && ret.error().get_error_code() != ENODATA)
|
if (ret.is_error() && ret.error().get_error_code() != ENODATA)
|
||||||
return ret;
|
return ret;
|
||||||
open_file.offset()++;
|
offset++;
|
||||||
if (ret.is_error())
|
if (ret.is_error())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
LockGuard _(m_mutex);
|
||||||
|
// NOTE: race condition with offset, its UB per POSIX
|
||||||
|
if (!validate_fd(fd).is_error())
|
||||||
|
m_open_files[fd].offset() = offset;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<size_t> OpenFileDescriptorSet::recvfrom(int fd, BAN::ByteSpan buffer, sockaddr* address, socklen_t* address_len)
|
BAN::ErrorOr<size_t> OpenFileDescriptorSet::recvfrom(int fd, BAN::ByteSpan buffer, sockaddr* address, socklen_t* address_len)
|
||||||
{
|
{
|
||||||
|
BAN::RefPtr<Inode> inode;
|
||||||
|
bool is_nonblock;
|
||||||
|
|
||||||
|
{
|
||||||
|
LockGuard _(m_mutex);
|
||||||
TRY(validate_fd(fd));
|
TRY(validate_fd(fd));
|
||||||
auto& open_file = m_open_files[fd];
|
auto& open_file = m_open_files[fd];
|
||||||
if (!open_file.inode()->mode().ifsock())
|
if (!open_file.inode()->mode().ifsock())
|
||||||
return BAN::Error::from_errno(ENOTSOCK);
|
return BAN::Error::from_errno(ENOTSOCK);
|
||||||
LockGuard _(open_file.inode()->m_mutex);
|
inode = open_file.inode();
|
||||||
if ((open_file.status_flags() & O_NONBLOCK) && !open_file.inode()->can_read())
|
is_nonblock = !!(open_file.status_flags() & O_NONBLOCK);
|
||||||
|
}
|
||||||
|
|
||||||
|
LockGuard _(inode->m_mutex);
|
||||||
|
if (is_nonblock && !inode->can_read())
|
||||||
return BAN::Error::from_errno(EWOULDBLOCK);
|
return BAN::Error::from_errno(EWOULDBLOCK);
|
||||||
return open_file.inode()->recvfrom(buffer, address, address_len);
|
return inode->recvfrom(buffer, address, address_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<size_t> OpenFileDescriptorSet::sendto(int fd, BAN::ConstByteSpan buffer, const sockaddr* address, socklen_t address_len)
|
BAN::ErrorOr<size_t> OpenFileDescriptorSet::sendto(int fd, BAN::ConstByteSpan buffer, const sockaddr* address, socklen_t address_len)
|
||||||
{
|
{
|
||||||
|
BAN::RefPtr<Inode> inode;
|
||||||
|
bool is_nonblock;
|
||||||
|
|
||||||
|
{
|
||||||
|
LockGuard _(m_mutex);
|
||||||
TRY(validate_fd(fd));
|
TRY(validate_fd(fd));
|
||||||
auto& open_file = m_open_files[fd];
|
auto& open_file = m_open_files[fd];
|
||||||
if (!open_file.inode()->mode().ifsock())
|
if (!open_file.inode()->mode().ifsock())
|
||||||
return BAN::Error::from_errno(ENOTSOCK);
|
return BAN::Error::from_errno(ENOTSOCK);
|
||||||
if ((open_file.status_flags() & O_NONBLOCK) && !open_file.inode()->can_write())
|
inode = open_file.inode();
|
||||||
return BAN::Error::from_errno(EWOULDBLOCK);
|
is_nonblock = !!(open_file.status_flags() & O_NONBLOCK);
|
||||||
|
}
|
||||||
|
|
||||||
LockGuard _(open_file.inode()->m_mutex);
|
LockGuard _(inode->m_mutex);
|
||||||
|
|
||||||
|
if (is_nonblock && !inode->can_write())
|
||||||
|
return BAN::Error::from_errno(EWOULDBLOCK);
|
||||||
|
|
||||||
size_t total_sent = 0;
|
size_t total_sent = 0;
|
||||||
while (total_sent < buffer.size())
|
while (total_sent < buffer.size())
|
||||||
{
|
{
|
||||||
if ((open_file.status_flags() & O_NONBLOCK) && !open_file.inode()->can_write())
|
if (is_nonblock && !inode->can_write())
|
||||||
return total_sent;
|
return total_sent;
|
||||||
const size_t nsend = TRY(open_file.inode()->sendto(buffer.slice(total_sent), address, address_len));
|
const size_t nsend = TRY(inode->sendto(buffer.slice(total_sent), address, address_len));
|
||||||
if (nsend == 0)
|
if (nsend == 0)
|
||||||
return 0;
|
return 0;
|
||||||
total_sent += nsend;
|
total_sent += nsend;
|
||||||
|
@ -384,30 +474,37 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<VirtualFileSystem::File> OpenFileDescriptorSet::file_of(int fd) const
|
BAN::ErrorOr<VirtualFileSystem::File> OpenFileDescriptorSet::file_of(int fd) const
|
||||||
{
|
{
|
||||||
|
LockGuard _(m_mutex);
|
||||||
TRY(validate_fd(fd));
|
TRY(validate_fd(fd));
|
||||||
return TRY(m_open_files[fd].description->file.clone());
|
return TRY(m_open_files[fd].description->file.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<BAN::StringView> OpenFileDescriptorSet::path_of(int fd) const
|
BAN::ErrorOr<BAN::String> OpenFileDescriptorSet::path_of(int fd) const
|
||||||
{
|
{
|
||||||
|
LockGuard _(m_mutex);
|
||||||
TRY(validate_fd(fd));
|
TRY(validate_fd(fd));
|
||||||
return m_open_files[fd].path();
|
BAN::String path;
|
||||||
|
TRY(path.append(m_open_files[fd].path()));
|
||||||
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<BAN::RefPtr<Inode>> OpenFileDescriptorSet::inode_of(int fd)
|
BAN::ErrorOr<BAN::RefPtr<Inode>> OpenFileDescriptorSet::inode_of(int fd)
|
||||||
{
|
{
|
||||||
|
LockGuard _(m_mutex);
|
||||||
TRY(validate_fd(fd));
|
TRY(validate_fd(fd));
|
||||||
return m_open_files[fd].inode();
|
return m_open_files[fd].inode();
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<int> OpenFileDescriptorSet::status_flags_of(int fd) const
|
BAN::ErrorOr<int> OpenFileDescriptorSet::status_flags_of(int fd) const
|
||||||
{
|
{
|
||||||
|
LockGuard _(m_mutex);
|
||||||
TRY(validate_fd(fd));
|
TRY(validate_fd(fd));
|
||||||
return m_open_files[fd].status_flags();
|
return m_open_files[fd].status_flags();
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<void> OpenFileDescriptorSet::validate_fd(int fd) const
|
BAN::ErrorOr<void> OpenFileDescriptorSet::validate_fd(int fd) const
|
||||||
{
|
{
|
||||||
|
LockGuard _(m_mutex);
|
||||||
if (fd < 0 || fd >= (int)m_open_files.size())
|
if (fd < 0 || fd >= (int)m_open_files.size())
|
||||||
return BAN::Error::from_errno(EBADF);
|
return BAN::Error::from_errno(EBADF);
|
||||||
if (!m_open_files[fd].description)
|
if (!m_open_files[fd].description)
|
||||||
|
@ -417,6 +514,7 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<int> OpenFileDescriptorSet::get_free_fd() const
|
BAN::ErrorOr<int> OpenFileDescriptorSet::get_free_fd() const
|
||||||
{
|
{
|
||||||
|
LockGuard _(m_mutex);
|
||||||
for (int fd = 0; fd < (int)m_open_files.size(); fd++)
|
for (int fd = 0; fd < (int)m_open_files.size(); fd++)
|
||||||
if (!m_open_files[fd].description)
|
if (!m_open_files[fd].description)
|
||||||
return fd;
|
return fd;
|
||||||
|
@ -425,6 +523,7 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<void> OpenFileDescriptorSet::get_free_fd_pair(int fds[2]) const
|
BAN::ErrorOr<void> OpenFileDescriptorSet::get_free_fd_pair(int fds[2]) const
|
||||||
{
|
{
|
||||||
|
LockGuard _(m_mutex);
|
||||||
size_t found = 0;
|
size_t found = 0;
|
||||||
for (int fd = 0; fd < (int)m_open_files.size(); fd++)
|
for (int fd = 0; fd < (int)m_open_files.size(); fd++)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue