2023-07-27 16:37:10 +02:00
|
|
|
#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));
|
|
|
|
|
2023-07-27 19:21:23 +02:00
|
|
|
current->fd_table[fd] = FileDescriptor { TRY(make_shared<OpenFileDescription>(socket, O_RDWR)), 0 };
|
2023-07-27 16:37:10 +02:00
|
|
|
|
|
|
|
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();
|
|
|
|
|
2023-07-27 19:21:23 +02:00
|
|
|
auto inode = TRY(current->resolve_fd(sockfd))->inode();
|
2023-07-27 16:37:10 +02:00
|
|
|
|
|
|
|
if (inode->type() != VFS::InodeType::Socket) return err(ENOTSOCK);
|
|
|
|
|
|
|
|
auto socket = (SharedPtr<Socket>)inode;
|
|
|
|
|
|
|
|
TRY(socket->bind(socket, (struct sockaddr*)&storage, addrlen));
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|