Luna/kernel/src/sys/socket.cpp

50 lines
1.3 KiB
C++
Raw Normal View History

#include "net/Socket.h"
#include "memory/MemoryManager.h"
#include "net/UnixSocket.h"
#include "sys/Syscall.h"
#include "thread/Scheduler.h"
#include <bits/open-flags.h>
Result<u64> sys_socket(Registers*, SyscallArgs args)
{
int domain = (int)args[0];
int type = (int)args[1];
// protocol is not used for now.
if (type != SOCK_STREAM) return err(EPROTOTYPE);
if (domain != AF_UNIX) return err(EAFNOSUPPORT);
auto socket = TRY(make_shared<UnixSocket>());
auto* current = Scheduler::current();
int fd = TRY(current->allocate_fd(0));
current->fd_table[fd] = FileDescriptor { TRY(make_shared<OpenFileDescription>(socket, O_RDWR)), 0 };
return fd;
}
Result<u64> sys_bind(Registers*, SyscallArgs args)
{
int sockfd = (int)args[0];
struct sockaddr* addr = (struct sockaddr*)args[1];
socklen_t addrlen = (socklen_t)args[2];
struct sockaddr_storage storage;
if ((usize)addrlen > sizeof(storage)) return err(EINVAL);
if (!MemoryManager::copy_from_user(addr, &storage, addrlen)) return err(EFAULT);
auto* current = Scheduler::current();
auto inode = TRY(current->resolve_fd(sockfd))->inode();
if (inode->type() != VFS::InodeType::Socket) return err(ENOTSOCK);
auto socket = (SharedPtr<Socket>)inode;
TRY(socket->bind(socket, (struct sockaddr*)&storage, addrlen));
return 0;
}