Add getsockopt(2) and setsockopt(2).

This commit is contained in:
Jonas 'Sortie' Termansen 2014-02-28 17:10:08 +01:00
parent 708bcb4735
commit a24ecf4b83
12 changed files with 174 additions and 14 deletions

View File

@ -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

View File

@ -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.
//

View File

@ -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,

View File

@ -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);
};

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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" */

View File

@ -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);
}

View File

@ -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);
}