Kernel/LibC: Implement {get,set}sockopt()

These are pretty much dummy functions in the kernel side. Only case that
is handled is SOL_SOCKET with SO_ERROR. This is hard coded to return no
error. Network stack is currently synchronous, so all errors are already
reported through synchronous network functions.
This commit is contained in:
Bananymous 2024-06-17 20:56:48 +03:00
parent 78bcb85679
commit be7ed8e74a
4 changed files with 50 additions and 0 deletions

View File

@ -120,6 +120,8 @@ namespace Kernel
BAN::ErrorOr<long> sys_socket(int domain, int type, int protocol);
BAN::ErrorOr<long> sys_getsockname(int socket, sockaddr* address, socklen_t* address_len);
BAN::ErrorOr<long> sys_getsockopt(int socket, int level, int option_name, void* option_value, socklen_t* option_len);
BAN::ErrorOr<long> sys_setsockopt(int socket, int level, int option_name, const void* option_value, socklen_t option_len);
BAN::ErrorOr<long> sys_accept(int socket, sockaddr* address, socklen_t* address_len);
BAN::ErrorOr<long> sys_bind(int socket, const sockaddr* address, socklen_t address_len);

View File

@ -925,6 +925,42 @@ namespace Kernel
return 0;
}
BAN::ErrorOr<long> Process::sys_getsockopt(int socket, int level, int option_name, void* option_value, socklen_t* option_len)
{
LockGuard _(m_process_lock);
TRY(validate_pointer_access(option_len, sizeof(option_len)));
TRY(validate_pointer_access(option_value, *option_len));
auto inode = TRY(m_open_file_descriptors.inode_of(socket));
if (!inode->mode().ifsock())
return BAN::Error::from_errno(ENOTSOCK);
// Because all networking is synchronous, there can not be errors to report
if (level == SOL_SOCKET && option_name == SO_ERROR)
{
if (*option_len)
*reinterpret_cast<uint8_t*>(option_value) = 0;
*option_len = BAN::Math::min<socklen_t>(*option_len, sizeof(int));
return 0;
}
dprintln("SYS_GETSOCKOPT {}, {}, {}, {}, {}", socket, level, option_name, option_value, option_len);
return BAN::Error::from_errno(ENOTSUP);
}
BAN::ErrorOr<long> Process::sys_setsockopt(int socket, int level, int option_name, const void* option_value, socklen_t option_len)
{
LockGuard _(m_process_lock);
TRY(validate_pointer_access(option_value, option_len));
auto inode = TRY(m_open_file_descriptors.inode_of(socket));
if (!inode->mode().ifsock())
return BAN::Error::from_errno(ENOTSOCK);
dprintln("SYS_GETSOCKOPT {}, {}, {}, {}, {}", socket, level, option_name, option_value, option_len);
return BAN::Error::from_errno(ENOTSUP);
}
BAN::ErrorOr<long> Process::sys_accept(int socket, sockaddr* address, socklen_t* address_len)
{
if (address && !address_len)

View File

@ -79,6 +79,8 @@ __BEGIN_DECLS
O(SYS_SMO_MAP, smo_map) \
O(SYS_ISATTY, isatty) \
O(SYS_GETSOCKNAME, getsockname) \
O(SYS_GETSOCKOPT, getsockopt) \
O(SYS_SETSOCKOPT, setsockopt) \
enum Syscall
{

View File

@ -67,3 +67,13 @@ int getsockname(int socket, struct sockaddr* __restrict address, socklen_t* __re
{
return syscall(SYS_GETSOCKNAME, socket, address, address_len);
}
int getsockopt(int socket, int level, int option_name, void* __restrict option_value, socklen_t* __restrict option_len)
{
return syscall(SYS_GETSOCKOPT, socket, level, option_name, option_value, option_len);
}
int setsockopt(int socket, int level, int option_name, const void* option_value, socklen_t option_len)
{
return syscall(SYS_SETSOCKOPT, socket, level, option_name, option_value, option_len);
}