50 lines
1.3 KiB
C++
50 lines
1.3 KiB
C++
|
#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 { socket, 0, O_RDWR };
|
||
|
|
||
|
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;
|
||
|
}
|