mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 05:17:35 +00:00
LibCore: Use Core::System and Error::from_syscall in Stream classes
This makes what caused a failure more obvious. The use of Core::System additionally allows us to remove a lot of boilerplate code from Stream classes.
This commit is contained in:
parent
301f4c469f
commit
ab36fb7a23
1 changed files with 33 additions and 102 deletions
|
@ -141,18 +141,7 @@ ErrorOr<void> File::open_path(StringView const& filename, mode_t permissions)
|
||||||
if (!has_flag(m_mode, OpenMode::Nonblocking))
|
if (!has_flag(m_mode, OpenMode::Nonblocking))
|
||||||
flags |= O_NONBLOCK;
|
flags |= O_NONBLOCK;
|
||||||
|
|
||||||
#ifdef __serenity__
|
m_fd = TRY(System::open(filename.characters_without_null_termination(), flags, permissions));
|
||||||
int fd = ::serenity_open(filename.characters_without_null_termination(), filename.length(), flags, permissions);
|
|
||||||
#else
|
|
||||||
String filename_with_null_terminator { filename };
|
|
||||||
int fd = ::open(filename_with_null_terminator.characters(), flags, permissions);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (fd < 0) {
|
|
||||||
return Error::from_errno(errno);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_fd = fd;
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,13 +157,9 @@ ErrorOr<size_t> File::read(Bytes buffer)
|
||||||
return Error::from_errno(EBADF);
|
return Error::from_errno(EBADF);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t rc = ::read(m_fd, buffer.data(), buffer.size());
|
ssize_t nread = TRY(System::read(m_fd, buffer));
|
||||||
if (rc < 0) {
|
m_last_read_was_eof = nread == 0;
|
||||||
return Error::from_errno(errno);
|
return nread;
|
||||||
}
|
|
||||||
|
|
||||||
m_last_read_was_eof = rc == 0;
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<size_t> File::write(ReadonlyBytes buffer)
|
ErrorOr<size_t> File::write(ReadonlyBytes buffer)
|
||||||
|
@ -184,16 +169,10 @@ ErrorOr<size_t> File::write(ReadonlyBytes buffer)
|
||||||
return Error::from_errno(EBADF);
|
return Error::from_errno(EBADF);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t rc = ::write(m_fd, buffer.data(), buffer.size());
|
return TRY(System::write(m_fd, buffer));
|
||||||
if (rc < 0) {
|
|
||||||
return Error::from_errno(errno);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool File::is_eof() const { return m_last_read_was_eof; }
|
bool File::is_eof() const { return m_last_read_was_eof; }
|
||||||
|
|
||||||
bool File::is_open() const { return m_fd >= 0; }
|
bool File::is_open() const { return m_fd >= 0; }
|
||||||
|
|
||||||
void File::close()
|
void File::close()
|
||||||
|
@ -205,12 +184,12 @@ void File::close()
|
||||||
// NOTE: The closing of the file can be interrupted by a signal, in which
|
// NOTE: The closing of the file can be interrupted by a signal, in which
|
||||||
// case EINTR will be returned by the close syscall. So let's try closing
|
// case EINTR will be returned by the close syscall. So let's try closing
|
||||||
// the file until we aren't interrupted by rude signals. :^)
|
// the file until we aren't interrupted by rude signals. :^)
|
||||||
int rc;
|
ErrorOr<void> result;
|
||||||
do {
|
do {
|
||||||
rc = ::close(m_fd);
|
result = System::close(m_fd);
|
||||||
} while (rc < 0 && errno == EINTR);
|
} while (result.is_error() && result.error().code() == EINTR);
|
||||||
|
|
||||||
VERIFY(rc == 0);
|
VERIFY(!result.is_error());
|
||||||
m_fd = -1;
|
m_fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,13 +210,9 @@ ErrorOr<off_t> File::seek(i64 offset, SeekMode mode)
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
off_t rc = lseek(m_fd, offset, syscall_mode);
|
off_t seek_result = TRY(System::lseek(m_fd, offset, syscall_mode));
|
||||||
if (rc < 0) {
|
|
||||||
return Error::from_errno(errno);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_last_read_was_eof = false;
|
m_last_read_was_eof = false;
|
||||||
return rc;
|
return seek_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<int> Socket::create_fd(SocketDomain domain, SocketType type)
|
ErrorOr<int> Socket::create_fd(SocketDomain domain, SocketType type)
|
||||||
|
@ -266,12 +241,7 @@ ErrorOr<int> Socket::create_fd(SocketDomain domain, SocketType type)
|
||||||
VERIFY_NOT_REACHED();
|
VERIFY_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
int rc = ::socket(socket_domain, socket_type, 0);
|
return System::socket(socket_domain, socket_type, 0);
|
||||||
if (rc < 0) {
|
|
||||||
return Error::from_errno(errno);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<IPv4Address> Socket::resolve_host(String const& host, SocketType type)
|
ErrorOr<IPv4Address> Socket::resolve_host(String const& host, SocketType type)
|
||||||
|
@ -294,11 +264,12 @@ ErrorOr<IPv4Address> Socket::resolve_host(String const& host, SocketType type)
|
||||||
hints.ai_flags = 0;
|
hints.ai_flags = 0;
|
||||||
hints.ai_protocol = 0;
|
hints.ai_protocol = 0;
|
||||||
|
|
||||||
|
// FIXME: Convert this to Core::System
|
||||||
struct addrinfo* results = nullptr;
|
struct addrinfo* results = nullptr;
|
||||||
int rc = getaddrinfo(host.characters(), nullptr, &hints, &results);
|
int rc = getaddrinfo(host.characters(), nullptr, &hints, &results);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
if (rc == EAI_SYSTEM) {
|
if (rc == EAI_SYSTEM) {
|
||||||
return Error::from_errno(errno);
|
return Error::from_syscall("getaddrinfo", -errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Error::from_string_literal(gai_strerror(rc));
|
return Error::from_string_literal(gai_strerror(rc));
|
||||||
|
@ -322,23 +293,13 @@ ErrorOr<void> Socket::connect_local(int fd, String const& path)
|
||||||
}
|
}
|
||||||
|
|
||||||
auto addr = maybe_sockaddr.release_value();
|
auto addr = maybe_sockaddr.release_value();
|
||||||
int rc = ::connect(fd, bit_cast<struct sockaddr*>(&addr), sizeof(addr));
|
return System::connect(fd, bit_cast<struct sockaddr*>(&addr), sizeof(addr));
|
||||||
if (rc < 0) {
|
|
||||||
return Error::from_errno(errno);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<void> Socket::connect_inet(int fd, SocketAddress const& address)
|
ErrorOr<void> Socket::connect_inet(int fd, SocketAddress const& address)
|
||||||
{
|
{
|
||||||
auto addr = address.to_sockaddr_in();
|
auto addr = address.to_sockaddr_in();
|
||||||
int rc = ::connect(fd, bit_cast<struct sockaddr*>(&addr), sizeof(addr));
|
return System::connect(fd, bit_cast<struct sockaddr*>(&addr), sizeof(addr));
|
||||||
if (rc < 0) {
|
|
||||||
return Error::from_errno(errno);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<size_t> PosixSocketHelper::read(Bytes buffer, int flags)
|
ErrorOr<size_t> PosixSocketHelper::read(Bytes buffer, int flags)
|
||||||
|
@ -347,19 +308,16 @@ ErrorOr<size_t> PosixSocketHelper::read(Bytes buffer, int flags)
|
||||||
return Error::from_errno(ENOTCONN);
|
return Error::from_errno(ENOTCONN);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t rc = ::recv(m_fd, buffer.data(), buffer.size(), flags);
|
ssize_t nread = TRY(System::recv(m_fd, buffer.data(), buffer.size(), flags));
|
||||||
if (rc < 0) {
|
m_last_read_was_eof = nread == 0;
|
||||||
return Error::from_syscall("recv", -errno);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_last_read_was_eof = rc == 0;
|
|
||||||
// If a socket read is EOF, then no more data can be read from it because
|
// If a socket read is EOF, then no more data can be read from it because
|
||||||
// the protocol has disconnected. In this case, we can just disable the
|
// the protocol has disconnected. In this case, we can just disable the
|
||||||
// notifier if we have one.
|
// notifier if we have one.
|
||||||
if (m_last_read_was_eof && m_notifier)
|
if (m_last_read_was_eof && m_notifier)
|
||||||
m_notifier->set_enabled(false);
|
m_notifier->set_enabled(false);
|
||||||
|
|
||||||
return rc;
|
return nread;
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<size_t> PosixSocketHelper::write(ReadonlyBytes buffer)
|
ErrorOr<size_t> PosixSocketHelper::write(ReadonlyBytes buffer)
|
||||||
|
@ -368,12 +326,7 @@ ErrorOr<size_t> PosixSocketHelper::write(ReadonlyBytes buffer)
|
||||||
return Error::from_errno(ENOTCONN);
|
return Error::from_errno(ENOTCONN);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t rc = ::send(m_fd, buffer.data(), buffer.size(), 0);
|
return TRY(System::send(m_fd, buffer.data(), buffer.size(), 0));
|
||||||
if (rc < 0) {
|
|
||||||
return Error::from_errno(errno);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PosixSocketHelper::close()
|
void PosixSocketHelper::close()
|
||||||
|
@ -385,12 +338,12 @@ void PosixSocketHelper::close()
|
||||||
if (m_notifier)
|
if (m_notifier)
|
||||||
m_notifier->set_enabled(false);
|
m_notifier->set_enabled(false);
|
||||||
|
|
||||||
int rc;
|
ErrorOr<void> result;
|
||||||
do {
|
do {
|
||||||
rc = ::close(m_fd);
|
result = System::close(m_fd);
|
||||||
} while (rc < 0 && errno == EINTR);
|
} while (result.is_error() && result.error().code() == EINTR);
|
||||||
|
|
||||||
VERIFY(rc == 0);
|
VERIFY(!result.is_error());
|
||||||
m_fd = -1;
|
m_fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,13 +351,14 @@ ErrorOr<bool> PosixSocketHelper::can_read_without_blocking(int timeout) const
|
||||||
{
|
{
|
||||||
struct pollfd the_fd = { .fd = m_fd, .events = POLLIN, .revents = 0 };
|
struct pollfd the_fd = { .fd = m_fd, .events = POLLIN, .revents = 0 };
|
||||||
|
|
||||||
|
// FIXME: Convert this to Core::System
|
||||||
int rc;
|
int rc;
|
||||||
do {
|
do {
|
||||||
rc = ::poll(&the_fd, 1, timeout);
|
rc = ::poll(&the_fd, 1, timeout);
|
||||||
} while (rc < 0 && errno == EINTR);
|
} while (rc < 0 && errno == EINTR);
|
||||||
|
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
return Error::from_errno(errno);
|
return Error::from_syscall("poll", -errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (the_fd.revents & POLLIN) > 0;
|
return (the_fd.revents & POLLIN) > 0;
|
||||||
|
@ -413,30 +367,19 @@ ErrorOr<bool> PosixSocketHelper::can_read_without_blocking(int timeout) const
|
||||||
ErrorOr<void> PosixSocketHelper::set_blocking(bool enabled)
|
ErrorOr<void> PosixSocketHelper::set_blocking(bool enabled)
|
||||||
{
|
{
|
||||||
int value = enabled ? 0 : 1;
|
int value = enabled ? 0 : 1;
|
||||||
int rc = ::ioctl(m_fd, FIONBIO, &value);
|
return System::ioctl(m_fd, FIONBIO, &value);
|
||||||
|
|
||||||
if (rc < 0) {
|
|
||||||
return Error::from_errno(errno);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorOr<void> PosixSocketHelper::set_close_on_exec(bool enabled)
|
ErrorOr<void> PosixSocketHelper::set_close_on_exec(bool enabled)
|
||||||
{
|
{
|
||||||
int flags = ::fcntl(m_fd, F_GETFD);
|
int flags = TRY(System::fcntl(m_fd, F_GETFD));
|
||||||
if (flags < 0)
|
|
||||||
return Error::from_errno(errno);
|
|
||||||
|
|
||||||
if (enabled)
|
if (enabled)
|
||||||
flags |= FD_CLOEXEC;
|
flags |= FD_CLOEXEC;
|
||||||
else
|
else
|
||||||
flags &= ~FD_CLOEXEC;
|
flags &= ~FD_CLOEXEC;
|
||||||
|
|
||||||
int rc = ::fcntl(m_fd, F_SETFD, flags);
|
TRY(System::fcntl(m_fd, F_SETFD, flags));
|
||||||
if (rc < 0)
|
|
||||||
return Error::from_errno(errno);
|
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,11 +427,7 @@ ErrorOr<size_t> PosixSocketHelper::pending_bytes() const
|
||||||
}
|
}
|
||||||
|
|
||||||
int value;
|
int value;
|
||||||
int rc = ::ioctl(m_fd, FIONREAD, &value);
|
TRY(System::ioctl(m_fd, FIONREAD, &value));
|
||||||
if (rc < 0) {
|
|
||||||
return Error::from_errno(errno);
|
|
||||||
}
|
|
||||||
|
|
||||||
return static_cast<size_t>(value);
|
return static_cast<size_t>(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -573,21 +512,13 @@ ErrorOr<pid_t> LocalSocket::peer_pid() const
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef AK_OS_MACOS
|
#ifdef AK_OS_MACOS
|
||||||
if (getsockopt(m_helper.fd(), SOL_LOCAL, LOCAL_PEERPID, &pid, &pid_size) < 0)
|
TRY(System::getsockopt(m_helper.fd(), SOL_LOCAL, LOCAL_PEERPID, &pid, &pid_size));
|
||||||
#elif defined(__FreeBSD__)
|
|
||||||
if (getsockopt(m_helper.fd(), SOL_LOCAL, LOCAL_PEERCRED, &creds, &creds_size) < 0)
|
|
||||||
#else
|
|
||||||
if (getsockopt(m_helper.fd(), SOL_SOCKET, SO_PEERCRED, &creds, &creds_size) < 0)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
return Error::from_syscall("getsockopt", -errno);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef AK_OS_MACOS
|
|
||||||
return pid;
|
return pid;
|
||||||
#elif defined(__FreeBSD__)
|
#elif defined(__FreeBSD__)
|
||||||
|
TRY(System::getsockopt(m_helper.fd(), SOL_LOCAL, LOCAL_PEERCRED, &creds, &creds_size));
|
||||||
return creds.cr_pid;
|
return creds.cr_pid;
|
||||||
#else
|
#else
|
||||||
|
TRY(System::getsockopt(m_helper.fd(), SOL_SOCKET, SO_PEERCRED, &creds, &creds_size));
|
||||||
return creds.pid;
|
return creds.pid;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue