mirror of
				https://gitlab.com/sortix/sortix.git
				synced 2023-02-13 20:55:38 -05:00 
			
		
		
		
	Add getsockopt(2) and setsockopt(2).
This commit is contained in:
		
							parent
							
								
									708bcb4735
								
							
						
					
					
						commit
						a24ecf4b83
					
				
					 12 changed files with 174 additions and 14 deletions
				
			
		| 
						 | 
				
			
			@ -628,4 +628,16 @@ ssize_t Descriptor::send(ioctx_t* ctx, const uint8_t* buf, size_t count, int fla
 | 
			
		|||
	return vnode->send(ctx, buf, count, flags);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int Descriptor::getsockopt(ioctx_t* ctx, int level, int option_name,
 | 
			
		||||
                           void* option_value, size_t* option_size_ptr)
 | 
			
		||||
{
 | 
			
		||||
	return vnode->getsockopt(ctx, level, option_name, option_value, option_size_ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int Descriptor::setsockopt(ioctx_t* ctx, int level, int option_name,
 | 
			
		||||
                           const void* option_value, size_t option_size)
 | 
			
		||||
{
 | 
			
		||||
	return vnode->setsockopt(ctx, level, option_name, option_value, option_size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace Sortix
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -232,6 +232,10 @@ public:
 | 
			
		|||
	virtual ssize_t recv(ioctx_t* ctx, uint8_t* buf, size_t count, int flags);
 | 
			
		||||
	virtual ssize_t send(ioctx_t* ctx, const uint8_t* buf, size_t count,
 | 
			
		||||
	                     int flags);
 | 
			
		||||
	virtual int getsockopt(ioctx_t* ctx, int level, int option_name,
 | 
			
		||||
	                       void* option_value, size_t* option_size_ptr);
 | 
			
		||||
	virtual int setsockopt(ioctx_t* ctx, int level, int option_name,
 | 
			
		||||
	                       const void* option_value, size_t option_size);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	bool SendMessage(Channel* channel, size_t type, void* ptr, size_t size,
 | 
			
		||||
| 
						 | 
				
			
			@ -1294,6 +1298,56 @@ ssize_t Unode::send(ioctx_t* /*ctx*/, const uint8_t* /*buf*/, size_t /*count*/,
 | 
			
		|||
	return errno = ENOTSOCK, -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int Unode::getsockopt(ioctx_t* ctx, int level, int option_name,
 | 
			
		||||
                      void* option_value, size_t* option_size_ptr)
 | 
			
		||||
{
 | 
			
		||||
	size_t option_size;
 | 
			
		||||
	if ( !ctx->copy_from_src(&option_size, option_size_ptr, sizeof(option_size)) )
 | 
			
		||||
		return -1;
 | 
			
		||||
	Channel* channel = server->Connect();
 | 
			
		||||
	if ( !channel )
 | 
			
		||||
		return -1;
 | 
			
		||||
	int ret = -1;
 | 
			
		||||
	struct fsm_req_getsockopt msg;
 | 
			
		||||
	struct fsm_resp_getsockopt resp;
 | 
			
		||||
	msg.ino = ino;
 | 
			
		||||
	msg.level = level;
 | 
			
		||||
	msg.option_name = option_name;
 | 
			
		||||
	msg.max_option_size = option_size;
 | 
			
		||||
	if ( SendMessage(channel, FSM_REQ_GETSOCKOPT, &msg, sizeof(msg)) &&
 | 
			
		||||
	     RecvMessage(channel, FSM_RESP_GETSOCKOPT, &resp, sizeof(resp)) )
 | 
			
		||||
	{
 | 
			
		||||
		if ( resp.option_size < option_size )
 | 
			
		||||
			option_size = resp.option_size;
 | 
			
		||||
		if ( channel->KernelRecv(ctx, option_value, option_size) )
 | 
			
		||||
			ret = 0;
 | 
			
		||||
		if ( !ctx->copy_to_dest(option_size_ptr, &option_size, sizeof(option_size)) )
 | 
			
		||||
			ret = -1;
 | 
			
		||||
	}
 | 
			
		||||
	channel->KernelClose();
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int Unode::setsockopt(ioctx_t* ctx, int level, int option_name,
 | 
			
		||||
                      const void* option_value, size_t option_size)
 | 
			
		||||
{
 | 
			
		||||
	Channel* channel = server->Connect();
 | 
			
		||||
	if ( !channel )
 | 
			
		||||
		return -1;
 | 
			
		||||
	int ret = -1;
 | 
			
		||||
	struct fsm_req_setsockopt msg;
 | 
			
		||||
	msg.ino = ino;
 | 
			
		||||
	msg.level = level;
 | 
			
		||||
	msg.option_name = option_name;
 | 
			
		||||
	msg.option_size = option_size;
 | 
			
		||||
	if ( SendMessage(channel, FSM_REQ_SETSOCKOPT, &msg, sizeof(msg)) &&
 | 
			
		||||
	     channel->KernelSend(ctx, option_value, option_size) &&
 | 
			
		||||
	     RecvMessage(channel, FSM_RESP_SUCCESS, NULL, 0) )
 | 
			
		||||
		ret = 0;
 | 
			
		||||
	channel->KernelClose();
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// Initialization.
 | 
			
		||||
//
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -96,6 +96,10 @@ public:
 | 
			
		|||
	int listen(ioctx_t* ctx, int backlog);
 | 
			
		||||
	ssize_t recv(ioctx_t* ctx, uint8_t* buf, size_t count, int flags);
 | 
			
		||||
	ssize_t send(ioctx_t* ctx, const uint8_t* buf, size_t count, int flags);
 | 
			
		||||
	int getsockopt(ioctx_t* ctx, int level, int option_name,
 | 
			
		||||
	               void* option_value, size_t* option_size_ptr);
 | 
			
		||||
	int setsockopt(ioctx_t* ctx, int level, int option_name,
 | 
			
		||||
	               const void* option_value, size_t option_size);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	Ref<Descriptor> open_elem(ioctx_t* ctx, const char* filename, int flags,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -106,6 +106,10 @@ public:
 | 
			
		|||
	virtual ssize_t recv(ioctx_t* ctx, uint8_t* buf, size_t count, int flags) = 0;
 | 
			
		||||
	virtual ssize_t send(ioctx_t* ctx, const uint8_t* buf, size_t count,
 | 
			
		||||
	                     int flags) = 0;
 | 
			
		||||
	virtual int getsockopt(ioctx_t* ctx, int level, int option_name,
 | 
			
		||||
	                       void* option_value, size_t* option_size_ptr) = 0;
 | 
			
		||||
	virtual int setsockopt(ioctx_t* ctx, int level, int option_name,
 | 
			
		||||
	                       const void* option_value, size_t option_size) = 0;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -186,6 +190,10 @@ public:
 | 
			
		|||
	virtual ssize_t recv(ioctx_t* ctx, uint8_t* buf, size_t count, int flags);
 | 
			
		||||
	virtual ssize_t send(ioctx_t* ctx, const uint8_t* buf, size_t count,
 | 
			
		||||
	                     int flags);
 | 
			
		||||
	virtual int getsockopt(ioctx_t* ctx, int level, int option_name,
 | 
			
		||||
	                       void* option_value, size_t* option_size_ptr);
 | 
			
		||||
	virtual int setsockopt(ioctx_t* ctx, int level, int option_name,
 | 
			
		||||
	                       const void* option_value, size_t option_size);
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -96,6 +96,10 @@ public:
 | 
			
		|||
	int listen(ioctx_t* ctx, int backlog);
 | 
			
		||||
	ssize_t recv(ioctx_t* ctx, uint8_t* buf, size_t count, int flags);
 | 
			
		||||
	ssize_t send(ioctx_t* ctx, const uint8_t* buf, size_t count, int flags);
 | 
			
		||||
	int getsockopt(ioctx_t* ctx, int level, int option_name,
 | 
			
		||||
	               void* option_value, size_t* option_size_ptr);
 | 
			
		||||
	int setsockopt(ioctx_t* ctx, int level, int option_name,
 | 
			
		||||
	               const void* option_value, size_t option_size);
 | 
			
		||||
 | 
			
		||||
public /*TODO: private*/:
 | 
			
		||||
	Ref<Inode> inode;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -165,6 +165,8 @@
 | 
			
		|||
#define SYSCALL_SIGSUSPEND 137
 | 
			
		||||
#define SYSCALL_SENDMSG 138
 | 
			
		||||
#define SYSCALL_RECVMSG 139
 | 
			
		||||
#define SYSCALL_MAX_NUM 140 /* index of highest constant + 1 */
 | 
			
		||||
#define SYSCALL_GETSOCKOPT 140
 | 
			
		||||
#define SYSCALL_SETSOCKOPT 141
 | 
			
		||||
#define SYSCALL_MAX_NUM 142 /* index of highest constant + 1 */
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -384,4 +384,16 @@ ssize_t AbstractInode::send(ioctx_t* /*ctx*/, const uint8_t* /*buf*/,
 | 
			
		|||
	return errno = ENOTSOCK, -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int AbstractInode::getsockopt(ioctx_t* /*ctx*/, int /*level*/, int /*option_name*/,
 | 
			
		||||
                              void* /*option_value*/, size_t* /*option_size_ptr*/)
 | 
			
		||||
{
 | 
			
		||||
	return errno = ENOTSOCK, -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int AbstractInode::setsockopt(ioctx_t* /*ctx*/, int /*level*/, int /*option_name*/,
 | 
			
		||||
                              const void* /*option_value*/, size_t /*option_size*/)
 | 
			
		||||
{
 | 
			
		||||
	return errno = ENOTSOCK, -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace Sortix
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1010,6 +1010,28 @@ static ssize_t sys_recvmsg(int fd, struct msghdr* user_msg, int flags)
 | 
			
		|||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int sys_getsockopt(int fd, int level, int option_name,
 | 
			
		||||
                          void* option_value, size_t* option_size_ptr)
 | 
			
		||||
{
 | 
			
		||||
	Ref<Descriptor> desc = CurrentProcess()->GetDescriptor(fd);
 | 
			
		||||
	if ( !desc )
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	ioctx_t ctx; SetupUserIOCtx(&ctx);
 | 
			
		||||
	return desc->getsockopt(&ctx, level, option_name, option_value, option_size_ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int sys_setsockopt(int fd, int level, int option_name,
 | 
			
		||||
                          const void* option_value, size_t option_size)
 | 
			
		||||
{
 | 
			
		||||
	Ref<Descriptor> desc = CurrentProcess()->GetDescriptor(fd);
 | 
			
		||||
	if ( !desc )
 | 
			
		||||
		return -1;
 | 
			
		||||
 | 
			
		||||
	ioctx_t ctx; SetupUserIOCtx(&ctx);
 | 
			
		||||
	return desc->setsockopt(&ctx, level, option_name, option_value, option_size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Init()
 | 
			
		||||
{
 | 
			
		||||
	Syscall::Register(SYSCALL_ACCEPT4, (void*) sys_accept4);
 | 
			
		||||
| 
						 | 
				
			
			@ -1036,6 +1058,7 @@ void Init()
 | 
			
		|||
	Syscall::Register(SYSCALL_FSYNC, (void*) sys_fsync);
 | 
			
		||||
	Syscall::Register(SYSCALL_FTRUNCATE, (void*) sys_ftruncate);
 | 
			
		||||
	Syscall::Register(SYSCALL_FUTIMENS, (void*) sys_futimens);
 | 
			
		||||
	Syscall::Register(SYSCALL_GETSOCKOPT, (void*) sys_getsockopt);
 | 
			
		||||
	Syscall::Register(SYSCALL_GETTERMMODE, (void*) sys_gettermmode);
 | 
			
		||||
	Syscall::Register(SYSCALL_IOCTL, (void*) sys_ioctl);
 | 
			
		||||
	Syscall::Register(SYSCALL_ISATTY, (void*) sys_isatty);
 | 
			
		||||
| 
						 | 
				
			
			@ -1058,6 +1081,7 @@ void Init()
 | 
			
		|||
	Syscall::Register(SYSCALL_RENAMEAT, (void*) sys_renameat);
 | 
			
		||||
	Syscall::Register(SYSCALL_SENDMSG, (void*) sys_sendmsg);
 | 
			
		||||
	Syscall::Register(SYSCALL_SEND, (void*) sys_send);
 | 
			
		||||
	Syscall::Register(SYSCALL_SETSOCKOPT, (void*) sys_setsockopt);
 | 
			
		||||
	Syscall::Register(SYSCALL_SETTERMMODE, (void*) sys_settermmode);
 | 
			
		||||
	Syscall::Register(SYSCALL_SYMLINKAT, (void*) sys_symlinkat);
 | 
			
		||||
	Syscall::Register(SYSCALL_TCGETPGRP, (void*) sys_tcgetpgrp);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -294,4 +294,16 @@ ssize_t Vnode::send(ioctx_t* ctx, const uint8_t* buf, size_t count, int flags)
 | 
			
		|||
	return inode->send(ctx, buf, count, flags);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int Vnode::getsockopt(ioctx_t* ctx, int level, int option_name,
 | 
			
		||||
                      void* option_value, size_t* option_size_ptr)
 | 
			
		||||
{
 | 
			
		||||
	return inode->getsockopt(ctx, level, option_name, option_value, option_size_ptr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int Vnode::setsockopt(ioctx_t* ctx, int level, int option_name,
 | 
			
		||||
                      const void* option_value, size_t option_size)
 | 
			
		||||
{
 | 
			
		||||
	return inode->setsockopt(ctx, level, option_name, option_value, option_size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace Sortix
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -368,7 +368,33 @@ struct fsm_resp_statvfs
 | 
			
		|||
	struct statvfs stvfs;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define FSM_MSG_NUM 45
 | 
			
		||||
#define FSM_REQ_SETSOCKOPT 46
 | 
			
		||||
struct fsm_req_setsockopt
 | 
			
		||||
{
 | 
			
		||||
	ino_t ino;
 | 
			
		||||
	int level;
 | 
			
		||||
	int option_name;
 | 
			
		||||
	size_t option_size;
 | 
			
		||||
	/*uint8_t option[option_size];*/
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define FSM_REQ_GETSOCKOPT 47
 | 
			
		||||
struct fsm_req_getsockopt
 | 
			
		||||
{
 | 
			
		||||
	ino_t ino;
 | 
			
		||||
	int level;
 | 
			
		||||
	int option_name;
 | 
			
		||||
	size_t max_option_size;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define FSM_RESP_GETSOCKOPT 48
 | 
			
		||||
struct fsm_resp_getsockopt
 | 
			
		||||
{
 | 
			
		||||
	size_t option_size;
 | 
			
		||||
	/*uint8_t option[option_size];*/
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define FSM_MSG_NUM 49
 | 
			
		||||
 | 
			
		||||
#if defined(__cplusplus)
 | 
			
		||||
} /* extern "C" */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
/*******************************************************************************
 | 
			
		||||
 | 
			
		||||
    Copyright(C) Jonas 'Sortie' Termansen 2013.
 | 
			
		||||
    Copyright(C) Jonas 'Sortie' Termansen 2013, 2014.
 | 
			
		||||
 | 
			
		||||
    This file is part of the Sortix C Library.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -23,12 +23,13 @@
 | 
			
		|||
*******************************************************************************/
 | 
			
		||||
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <sys/syscall.h>
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
DEFN_SYSCALL5(int, sys_getsockopt, SYSCALL_GETSOCKOPT, int, int, int, const void*, size_t*);
 | 
			
		||||
 | 
			
		||||
extern "C" int getsockopt(int, int, int, void* restrict, socklen_t* restrict)
 | 
			
		||||
extern "C"
 | 
			
		||||
int getsockopt(int fd, int level, int option_name, void* restrict option_value,
 | 
			
		||||
               socklen_t* restrict option_size)
 | 
			
		||||
{
 | 
			
		||||
	fprintf(stderr, "%s is not implemented yet.\n", __func__);
 | 
			
		||||
	return errno = ENOSYS, -1;
 | 
			
		||||
	return sys_getsockopt(fd, level, option_name, option_value, option_size);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
/*******************************************************************************
 | 
			
		||||
 | 
			
		||||
    Copyright(C) Jonas 'Sortie' Termansen 2013.
 | 
			
		||||
    Copyright(C) Jonas 'Sortie' Termansen 2013, 2014.
 | 
			
		||||
 | 
			
		||||
    This file is part of the Sortix C Library.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -23,12 +23,13 @@
 | 
			
		|||
*******************************************************************************/
 | 
			
		||||
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <sys/syscall.h>
 | 
			
		||||
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
DEFN_SYSCALL5(int, sys_setsockopt, SYSCALL_SETSOCKOPT, int, int, int, const void*, size_t);
 | 
			
		||||
 | 
			
		||||
extern "C" int setsockopt(int, int, int, const void*, socklen_t)
 | 
			
		||||
extern "C"
 | 
			
		||||
int setsockopt(int fd, int level, int option_name, const void* option_value,
 | 
			
		||||
               socklen_t option_size)
 | 
			
		||||
{
 | 
			
		||||
	fprintf(stderr, "%s is not implemented yet.\n", __func__);
 | 
			
		||||
	return errno = ENOSYS, -1;
 | 
			
		||||
	return sys_setsockopt(fd, level, option_name, option_value, option_size);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue