Add getsockopt(2) and setsockopt(2).
This commit is contained in:
parent
708bcb4735
commit
a24ecf4b83
|
@ -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);
|
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
|
} // 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 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,
|
virtual ssize_t send(ioctx_t* ctx, const uint8_t* buf, size_t count,
|
||||||
int flags);
|
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:
|
private:
|
||||||
bool SendMessage(Channel* channel, size_t type, void* ptr, size_t size,
|
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;
|
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.
|
// Initialization.
|
||||||
//
|
//
|
||||||
|
|
|
@ -96,6 +96,10 @@ public:
|
||||||
int listen(ioctx_t* ctx, int backlog);
|
int listen(ioctx_t* ctx, int backlog);
|
||||||
ssize_t recv(ioctx_t* ctx, uint8_t* buf, size_t count, int flags);
|
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);
|
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:
|
private:
|
||||||
Ref<Descriptor> open_elem(ioctx_t* ctx, const char* filename, int flags,
|
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 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,
|
virtual ssize_t send(ioctx_t* ctx, const uint8_t* buf, size_t count,
|
||||||
int flags) = 0;
|
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 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,
|
virtual ssize_t send(ioctx_t* ctx, const uint8_t* buf, size_t count,
|
||||||
int flags);
|
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);
|
int listen(ioctx_t* ctx, int backlog);
|
||||||
ssize_t recv(ioctx_t* ctx, uint8_t* buf, size_t count, int flags);
|
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);
|
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*/:
|
public /*TODO: private*/:
|
||||||
Ref<Inode> inode;
|
Ref<Inode> inode;
|
||||||
|
|
|
@ -165,6 +165,8 @@
|
||||||
#define SYSCALL_SIGSUSPEND 137
|
#define SYSCALL_SIGSUSPEND 137
|
||||||
#define SYSCALL_SENDMSG 138
|
#define SYSCALL_SENDMSG 138
|
||||||
#define SYSCALL_RECVMSG 139
|
#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
|
#endif
|
||||||
|
|
|
@ -384,4 +384,16 @@ ssize_t AbstractInode::send(ioctx_t* /*ctx*/, const uint8_t* /*buf*/,
|
||||||
return errno = ENOTSOCK, -1;
|
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
|
} // namespace Sortix
|
||||||
|
|
|
@ -1010,6 +1010,28 @@ static ssize_t sys_recvmsg(int fd, struct msghdr* user_msg, int flags)
|
||||||
return result;
|
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()
|
void Init()
|
||||||
{
|
{
|
||||||
Syscall::Register(SYSCALL_ACCEPT4, (void*) sys_accept4);
|
Syscall::Register(SYSCALL_ACCEPT4, (void*) sys_accept4);
|
||||||
|
@ -1036,6 +1058,7 @@ void Init()
|
||||||
Syscall::Register(SYSCALL_FSYNC, (void*) sys_fsync);
|
Syscall::Register(SYSCALL_FSYNC, (void*) sys_fsync);
|
||||||
Syscall::Register(SYSCALL_FTRUNCATE, (void*) sys_ftruncate);
|
Syscall::Register(SYSCALL_FTRUNCATE, (void*) sys_ftruncate);
|
||||||
Syscall::Register(SYSCALL_FUTIMENS, (void*) sys_futimens);
|
Syscall::Register(SYSCALL_FUTIMENS, (void*) sys_futimens);
|
||||||
|
Syscall::Register(SYSCALL_GETSOCKOPT, (void*) sys_getsockopt);
|
||||||
Syscall::Register(SYSCALL_GETTERMMODE, (void*) sys_gettermmode);
|
Syscall::Register(SYSCALL_GETTERMMODE, (void*) sys_gettermmode);
|
||||||
Syscall::Register(SYSCALL_IOCTL, (void*) sys_ioctl);
|
Syscall::Register(SYSCALL_IOCTL, (void*) sys_ioctl);
|
||||||
Syscall::Register(SYSCALL_ISATTY, (void*) sys_isatty);
|
Syscall::Register(SYSCALL_ISATTY, (void*) sys_isatty);
|
||||||
|
@ -1058,6 +1081,7 @@ void Init()
|
||||||
Syscall::Register(SYSCALL_RENAMEAT, (void*) sys_renameat);
|
Syscall::Register(SYSCALL_RENAMEAT, (void*) sys_renameat);
|
||||||
Syscall::Register(SYSCALL_SENDMSG, (void*) sys_sendmsg);
|
Syscall::Register(SYSCALL_SENDMSG, (void*) sys_sendmsg);
|
||||||
Syscall::Register(SYSCALL_SEND, (void*) sys_send);
|
Syscall::Register(SYSCALL_SEND, (void*) sys_send);
|
||||||
|
Syscall::Register(SYSCALL_SETSOCKOPT, (void*) sys_setsockopt);
|
||||||
Syscall::Register(SYSCALL_SETTERMMODE, (void*) sys_settermmode);
|
Syscall::Register(SYSCALL_SETTERMMODE, (void*) sys_settermmode);
|
||||||
Syscall::Register(SYSCALL_SYMLINKAT, (void*) sys_symlinkat);
|
Syscall::Register(SYSCALL_SYMLINKAT, (void*) sys_symlinkat);
|
||||||
Syscall::Register(SYSCALL_TCGETPGRP, (void*) sys_tcgetpgrp);
|
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);
|
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
|
} // namespace Sortix
|
||||||
|
|
|
@ -368,7 +368,33 @@ struct fsm_resp_statvfs
|
||||||
struct statvfs stvfs;
|
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)
|
#if defined(__cplusplus)
|
||||||
} /* extern "C" */
|
} /* 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.
|
This file is part of the Sortix C Library.
|
||||||
|
|
||||||
|
@ -23,12 +23,13 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
|
||||||
#include <errno.h>
|
DEFN_SYSCALL5(int, sys_getsockopt, SYSCALL_GETSOCKOPT, int, int, int, const void*, size_t*);
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
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 sys_getsockopt(fd, level, option_name, option_value, option_size);
|
||||||
return errno = ENOSYS, -1;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
This file is part of the Sortix C Library.
|
||||||
|
|
||||||
|
@ -23,12 +23,13 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
|
||||||
#include <errno.h>
|
DEFN_SYSCALL5(int, sys_setsockopt, SYSCALL_SETSOCKOPT, int, int, int, const void*, size_t);
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
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 sys_setsockopt(fd, level, option_name, option_value, option_size);
|
||||||
return errno = ENOSYS, -1;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue