forked from Bananymous/banan-os
				
			Kernel/LibC: Implement basic socket binding
This commit is contained in:
		
							parent
							
								
									cf28ecd5a6
								
							
						
					
					
						commit
						ab150b458a
					
				| 
						 | 
					@ -11,6 +11,7 @@
 | 
				
			||||||
#include <kernel/Credentials.h>
 | 
					#include <kernel/Credentials.h>
 | 
				
			||||||
#include <kernel/SpinLock.h>
 | 
					#include <kernel/SpinLock.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sys/socket.h>
 | 
				
			||||||
#include <sys/types.h>
 | 
					#include <sys/types.h>
 | 
				
			||||||
#include <time.h>
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -86,6 +87,8 @@ namespace Kernel
 | 
				
			||||||
		virtual bool is_pipe() const { return false; }
 | 
							virtual bool is_pipe() const { return false; }
 | 
				
			||||||
		virtual bool is_tty() const { return false; }
 | 
							virtual bool is_tty() const { return false; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							void on_close();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Directory API
 | 
							// Directory API
 | 
				
			||||||
		BAN::ErrorOr<BAN::RefPtr<Inode>> find_inode(BAN::StringView);
 | 
							BAN::ErrorOr<BAN::RefPtr<Inode>> find_inode(BAN::StringView);
 | 
				
			||||||
		BAN::ErrorOr<void> list_next_inodes(off_t, DirectoryEntryList*, size_t);
 | 
							BAN::ErrorOr<void> list_next_inodes(off_t, DirectoryEntryList*, size_t);
 | 
				
			||||||
| 
						 | 
					@ -96,6 +99,9 @@ namespace Kernel
 | 
				
			||||||
		// Link API
 | 
							// Link API
 | 
				
			||||||
		BAN::ErrorOr<BAN::String> link_target();
 | 
							BAN::ErrorOr<BAN::String> link_target();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Socket API
 | 
				
			||||||
 | 
							BAN::ErrorOr<void> bind(const sockaddr* address, socklen_t address_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// General API
 | 
							// General API
 | 
				
			||||||
		BAN::ErrorOr<size_t> read(off_t, BAN::ByteSpan buffer);
 | 
							BAN::ErrorOr<size_t> read(off_t, BAN::ByteSpan buffer);
 | 
				
			||||||
		BAN::ErrorOr<size_t> write(off_t, BAN::ConstByteSpan buffer);
 | 
							BAN::ErrorOr<size_t> write(off_t, BAN::ConstByteSpan buffer);
 | 
				
			||||||
| 
						 | 
					@ -105,6 +111,8 @@ namespace Kernel
 | 
				
			||||||
		bool has_data() const;
 | 
							bool has_data() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	protected:
 | 
						protected:
 | 
				
			||||||
 | 
							virtual void on_close_impl() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Directory API
 | 
							// Directory API
 | 
				
			||||||
		virtual BAN::ErrorOr<BAN::RefPtr<Inode>> find_inode_impl(BAN::StringView)				{ return BAN::Error::from_errno(ENOTSUP); }
 | 
							virtual BAN::ErrorOr<BAN::RefPtr<Inode>> find_inode_impl(BAN::StringView)				{ return BAN::Error::from_errno(ENOTSUP); }
 | 
				
			||||||
		virtual BAN::ErrorOr<void> list_next_inodes_impl(off_t, DirectoryEntryList*, size_t)	{ return BAN::Error::from_errno(ENOTSUP); }
 | 
							virtual BAN::ErrorOr<void> list_next_inodes_impl(off_t, DirectoryEntryList*, size_t)	{ return BAN::Error::from_errno(ENOTSUP); }
 | 
				
			||||||
| 
						 | 
					@ -115,6 +123,9 @@ namespace Kernel
 | 
				
			||||||
		// Link API
 | 
							// Link API
 | 
				
			||||||
		virtual BAN::ErrorOr<BAN::String> link_target_impl()				{ return BAN::Error::from_errno(ENOTSUP); }
 | 
							virtual BAN::ErrorOr<BAN::String> link_target_impl()				{ return BAN::Error::from_errno(ENOTSUP); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Socket API
 | 
				
			||||||
 | 
							virtual BAN::ErrorOr<void> bind_impl(const sockaddr*, socklen_t)	{ return BAN::Error::from_errno(ENOTSUP); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// General API
 | 
							// General API
 | 
				
			||||||
		virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan)		{ return BAN::Error::from_errno(ENOTSUP); }
 | 
							virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan)		{ return BAN::Error::from_errno(ENOTSUP); }
 | 
				
			||||||
		virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan)	{ return BAN::Error::from_errno(ENOTSUP); }
 | 
							virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan)	{ return BAN::Error::from_errno(ENOTSUP); }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,6 +35,8 @@ namespace Kernel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		const dev_t m_rdev;
 | 
							const dev_t m_rdev;
 | 
				
			||||||
		char m_name[10];
 | 
							char m_name[10];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							uint32_t m_ipv4_address {};
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,8 @@
 | 
				
			||||||
#include <kernel/Networking/NetworkSocket.h>
 | 
					#include <kernel/Networking/NetworkSocket.h>
 | 
				
			||||||
#include <kernel/PCI.h>
 | 
					#include <kernel/PCI.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <netinet/in.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kernel
 | 
					namespace Kernel
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,7 +26,9 @@ namespace Kernel
 | 
				
			||||||
		static NetworkManager& get();
 | 
							static NetworkManager& get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		BAN::ErrorOr<void> add_interface(PCI::Device& pci_device);
 | 
							BAN::ErrorOr<void> add_interface(PCI::Device& pci_device);
 | 
				
			||||||
		BAN::ErrorOr<void> bind_socket(int port, BAN::RefPtr<NetworkSocket>);
 | 
					
 | 
				
			||||||
 | 
							void unbind_socket(uint16_t port, BAN::RefPtr<NetworkSocket>);
 | 
				
			||||||
 | 
							BAN::ErrorOr<void> bind_socket(uint16_t port, BAN::RefPtr<NetworkSocket>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		BAN::ErrorOr<BAN::RefPtr<NetworkSocket>> create_socket(SocketType, mode_t, uid_t, gid_t);
 | 
							BAN::ErrorOr<BAN::RefPtr<NetworkSocket>> create_socket(SocketType, mode_t, uid_t, gid_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,7 +37,7 @@ namespace Kernel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private:
 | 
						private:
 | 
				
			||||||
		BAN::Vector<BAN::RefPtr<NetworkInterface>>		m_interfaces;
 | 
							BAN::Vector<BAN::RefPtr<NetworkInterface>>		m_interfaces;
 | 
				
			||||||
		BAN::HashMap<int, BAN::RefPtr<NetworkSocket>>	m_bound_sockets;
 | 
							BAN::HashMap<int, BAN::WeakPtr<NetworkSocket>>	m_bound_sockets;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,21 +1,28 @@
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <BAN/WeakPtr.h>
 | 
				
			||||||
#include <kernel/FS/TmpFS/Inode.h>
 | 
					#include <kernel/FS/TmpFS/Inode.h>
 | 
				
			||||||
#include <kernel/Networking/NetworkInterface.h>
 | 
					#include <kernel/Networking/NetworkInterface.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kernel
 | 
					namespace Kernel
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class NetworkSocket : public TmpInode
 | 
						class NetworkSocket : public TmpInode, public BAN::Weakable<NetworkSocket>
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
	public:
 | 
						public:
 | 
				
			||||||
		void bind_interface(NetworkInterface*);
 | 
							void bind_interface_and_port(NetworkInterface*, uint16_t port);
 | 
				
			||||||
 | 
							~NetworkSocket();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	protected:
 | 
						protected:
 | 
				
			||||||
		NetworkSocket(mode_t mode, uid_t uid, gid_t gid);
 | 
							NetworkSocket(mode_t mode, uid_t uid, gid_t gid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							virtual void on_close_impl() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							virtual BAN::ErrorOr<void> bind_impl(const sockaddr* address, socklen_t address_len) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	protected:
 | 
						protected:
 | 
				
			||||||
		NetworkInterface*	m_interface = nullptr;
 | 
							NetworkInterface*	m_interface = nullptr;
 | 
				
			||||||
 | 
							uint16_t			m_port = 0;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,6 +16,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <sys/banan-os.h>
 | 
					#include <sys/banan-os.h>
 | 
				
			||||||
#include <sys/mman.h>
 | 
					#include <sys/mman.h>
 | 
				
			||||||
 | 
					#include <sys/socket.h>
 | 
				
			||||||
#include <termios.h>
 | 
					#include <termios.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace LibELF { class LoadableELF; }
 | 
					namespace LibELF { class LoadableELF; }
 | 
				
			||||||
| 
						 | 
					@ -112,6 +113,7 @@ namespace Kernel
 | 
				
			||||||
		BAN::ErrorOr<long> sys_chown(const char*, uid_t, gid_t);
 | 
							BAN::ErrorOr<long> sys_chown(const char*, uid_t, gid_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		BAN::ErrorOr<long> sys_socket(int domain, int type, int protocol);
 | 
							BAN::ErrorOr<long> sys_socket(int domain, int type, int protocol);
 | 
				
			||||||
 | 
							BAN::ErrorOr<long> sys_bind(int socket, const sockaddr* address, socklen_t address_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		BAN::ErrorOr<long> sys_pipe(int fildes[2]);
 | 
							BAN::ErrorOr<long> sys_pipe(int fildes[2]);
 | 
				
			||||||
		BAN::ErrorOr<long> sys_dup(int fildes);
 | 
							BAN::ErrorOr<long> sys_dup(int fildes);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -56,6 +56,12 @@ namespace Kernel
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void Inode::on_close()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							LockGuard _(m_lock);
 | 
				
			||||||
 | 
							on_close_impl();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BAN::ErrorOr<BAN::RefPtr<Inode>> Inode::find_inode(BAN::StringView name)
 | 
						BAN::ErrorOr<BAN::RefPtr<Inode>> Inode::find_inode(BAN::StringView name)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		LockGuard _(m_lock);
 | 
							LockGuard _(m_lock);
 | 
				
			||||||
| 
						 | 
					@ -110,6 +116,14 @@ namespace Kernel
 | 
				
			||||||
		return link_target_impl();
 | 
							return link_target_impl();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						BAN::ErrorOr<void> Inode::bind(const sockaddr* address, socklen_t address_len)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							LockGuard _(m_lock);
 | 
				
			||||||
 | 
							if (!mode().ifsock())
 | 
				
			||||||
 | 
								return BAN::Error::from_errno(ENOTSOCK);
 | 
				
			||||||
 | 
							return bind_impl(address, address_len);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BAN::ErrorOr<size_t> Inode::read(off_t offset, BAN::ByteSpan buffer)
 | 
						BAN::ErrorOr<size_t> Inode::read(off_t offset, BAN::ByteSpan buffer)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		LockGuard _(m_lock);
 | 
							LockGuard _(m_lock);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -68,11 +68,39 @@ namespace Kernel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BAN::ErrorOr<BAN::RefPtr<NetworkSocket>> NetworkManager::create_socket(SocketType type, mode_t mode, uid_t uid, gid_t gid)
 | 
						BAN::ErrorOr<BAN::RefPtr<NetworkSocket>> NetworkManager::create_socket(SocketType type, mode_t mode, uid_t uid, gid_t gid)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							ASSERT((mode & Inode::Mode::TYPE_MASK) == 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (type != SocketType::DGRAM)
 | 
							if (type != SocketType::DGRAM)
 | 
				
			||||||
			return BAN::Error::from_errno(EPROTOTYPE);
 | 
								return BAN::Error::from_errno(EPROTOTYPE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		auto udp_socket = TRY(UDPSocket::create(mode, uid, gid));
 | 
							auto udp_socket = TRY(UDPSocket::create(mode | Inode::Mode::IFSOCK, uid, gid));
 | 
				
			||||||
		return BAN::RefPtr<NetworkSocket>(udp_socket);
 | 
							return BAN::RefPtr<NetworkSocket>(udp_socket);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void NetworkManager::unbind_socket(uint16_t port, BAN::RefPtr<NetworkSocket> socket)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (m_bound_sockets.contains(port))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								ASSERT(m_bound_sockets[port].valid());
 | 
				
			||||||
 | 
								ASSERT(m_bound_sockets[port].lock() == socket);
 | 
				
			||||||
 | 
								m_bound_sockets.remove(port);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							NetworkManager::get().remove_from_cache(socket);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						BAN::ErrorOr<void> NetworkManager::bind_socket(uint16_t port, BAN::RefPtr<NetworkSocket> socket)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (m_interfaces.empty())
 | 
				
			||||||
 | 
								return BAN::Error::from_errno(EADDRNOTAVAIL);
 | 
				
			||||||
 | 
							if (m_bound_sockets.contains(port))
 | 
				
			||||||
 | 
								return BAN::Error::from_errno(EADDRINUSE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// FIXME: actually determine proper interface
 | 
				
			||||||
 | 
							auto interface = m_interfaces.front();
 | 
				
			||||||
 | 
							TRY(m_bound_sockets.insert(port, socket));
 | 
				
			||||||
 | 
							socket->bind_interface_and_port(interface.ptr(), port);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return {};
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,11 +13,30 @@ namespace Kernel
 | 
				
			||||||
		)
 | 
							)
 | 
				
			||||||
	{ }
 | 
						{ }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void NetworkSocket::bind_interface(NetworkInterface* interface)
 | 
						NetworkSocket::~NetworkSocket()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void NetworkSocket::on_close_impl()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (m_interface)
 | 
				
			||||||
 | 
								NetworkManager::get().unbind_socket(m_port, this);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void NetworkSocket::bind_interface_and_port(NetworkInterface* interface, uint16_t port)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		ASSERT(!m_interface);
 | 
							ASSERT(!m_interface);
 | 
				
			||||||
		ASSERT(interface);
 | 
							ASSERT(interface);
 | 
				
			||||||
		m_interface = interface;
 | 
							m_interface = interface;
 | 
				
			||||||
 | 
							m_port = port;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						BAN::ErrorOr<void> NetworkSocket::bind_impl(const sockaddr* address, socklen_t address_len)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (address_len != sizeof(sockaddr_in))
 | 
				
			||||||
 | 
								return BAN::Error::from_errno(EINVAL);
 | 
				
			||||||
 | 
							auto* addr_in = reinterpret_cast<const sockaddr_in*>(address);
 | 
				
			||||||
 | 
							return NetworkManager::get().bind_socket(addr_in->sin_port, this);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -276,6 +276,8 @@ namespace Kernel
 | 
				
			||||||
		if (m_open_files[fd]->flags & O_WRONLY && m_open_files[fd]->inode->is_pipe())
 | 
							if (m_open_files[fd]->flags & O_WRONLY && m_open_files[fd]->inode->is_pipe())
 | 
				
			||||||
			((Pipe*)m_open_files[fd]->inode.ptr())->close_writing();
 | 
								((Pipe*)m_open_files[fd]->inode.ptr())->close_writing();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							m_open_files[fd]->inode->on_close();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		m_open_files[fd].clear();
 | 
							m_open_files[fd].clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return {};
 | 
							return {};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -901,6 +901,20 @@ namespace Kernel
 | 
				
			||||||
		return TRY(m_open_file_descriptors.socket(domain, type, protocol));
 | 
							return TRY(m_open_file_descriptors.socket(domain, type, protocol));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						BAN::ErrorOr<long> Process::sys_bind(int socket, const sockaddr* address, socklen_t address_len)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							LockGuard _(m_lock);
 | 
				
			||||||
 | 
							TRY(validate_pointer_access(address, address_len));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							auto inode = TRY(m_open_file_descriptors.inode_of(socket));
 | 
				
			||||||
 | 
							if (!inode->mode().ifsock())
 | 
				
			||||||
 | 
								return BAN::Error::from_errno(ENOTSOCK);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							TRY(inode->bind(address, address_len));
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	BAN::ErrorOr<long> Process::sys_pipe(int fildes[2])
 | 
						BAN::ErrorOr<long> Process::sys_pipe(int fildes[2])
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		LockGuard _(m_lock);
 | 
							LockGuard _(m_lock);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -216,6 +216,9 @@ namespace Kernel
 | 
				
			||||||
		case SYS_SOCKET:
 | 
							case SYS_SOCKET:
 | 
				
			||||||
			ret = Process::current().sys_socket((int)arg1, (int)arg2, (int)arg3);
 | 
								ret = Process::current().sys_socket((int)arg1, (int)arg2, (int)arg3);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
							case SYS_BIND:
 | 
				
			||||||
 | 
								ret = Process::current().sys_bind((int)arg1, (const sockaddr*)arg2, (socklen_t)arg3);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			dwarnln("Unknown syscall {}", syscall);
 | 
								dwarnln("Unknown syscall {}", syscall);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -64,6 +64,7 @@ __BEGIN_DECLS
 | 
				
			||||||
#define SYS_CHOWN 63
 | 
					#define SYS_CHOWN 63
 | 
				
			||||||
#define SYS_LOAD_KEYMAP 64
 | 
					#define SYS_LOAD_KEYMAP 64
 | 
				
			||||||
#define SYS_SOCKET 65
 | 
					#define SYS_SOCKET 65
 | 
				
			||||||
 | 
					#define SYS_BIND 66
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__END_DECLS
 | 
					__END_DECLS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,11 @@
 | 
				
			||||||
#include <sys/syscall.h>
 | 
					#include <sys/syscall.h>
 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int bind(int socket, const struct sockaddr* address, socklen_t address_len)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return syscall(SYS_BIND, socket, address, address_len);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int socket(int domain, int type, int protocol)
 | 
					int socket(int domain, int type, int protocol)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return syscall(SYS_SOCKET, domain, type, protocol);
 | 
						return syscall(SYS_SOCKET, domain, type, protocol);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue