mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 15:08:21 +00:00
localsocket: implement getopt and setopt
This commit is contained in:
@@ -114,7 +114,9 @@ typedef struct {
|
|||||||
#define SO_RCVBUF 8
|
#define SO_RCVBUF 8
|
||||||
#define SO_KEEPALIVE 9
|
#define SO_KEEPALIVE 9
|
||||||
#define SO_OOBINLINE 10
|
#define SO_OOBINLINE 10
|
||||||
|
#define SO_NO_CHECK 11
|
||||||
#define SO_LINGER 13
|
#define SO_LINGER 13
|
||||||
|
#define SO_PEERCRED 17
|
||||||
#define SO_RCVLOWAT 18
|
#define SO_RCVLOWAT 18
|
||||||
#define SO_SNDLOWAT 19
|
#define SO_SNDLOWAT 19
|
||||||
#define SO_BINDTODEVICE 25
|
#define SO_BINDTODEVICE 25
|
||||||
|
|||||||
@@ -1045,7 +1045,71 @@ static int localsock_shutdown(socket_t *socket, int how) {
|
|||||||
|
|
||||||
MUTEX_RELEASE(&socket->mutex);
|
MUTEX_RELEASE(&socket->mutex);
|
||||||
return error;
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// called with socket locked
|
||||||
|
static int localsock_setopt(socket_t *socket, int layer, int optname, void *buffer, socklen_t len, cred_t *cred) {
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
|
if (layer == SOL_SOCKET) {
|
||||||
|
switch (optname) {
|
||||||
|
case SO_SNDLOWAT:
|
||||||
|
case SO_OOBINLINE:
|
||||||
|
case SO_KEEPALIVE:
|
||||||
|
case SO_SNDBUF:
|
||||||
|
case SO_RCVBUF:
|
||||||
|
case SO_REUSEADDR:
|
||||||
|
case SO_NO_CHECK:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error = ENOPROTOOPT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error == ENOPROTOOPT) {
|
||||||
|
printf("localsock_setopt: unknown %lu %lu called\n", layer, optname);
|
||||||
|
}
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int localsock_getopt(socket_t *socket, int layer, int optname, void *unsafe_buffer, socklen_t *unsafe_len, cred_t *cred) {
|
||||||
|
socklen_t len;
|
||||||
|
int error = USERCOPY_POSSIBLY_FROM_USER(&len, unsafe_len, sizeof(len));
|
||||||
|
if (error)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
if (layer == SOL_SOCKET) {
|
||||||
|
switch (optname) {
|
||||||
|
case SO_SNDLOWAT: {
|
||||||
|
int value = 1;
|
||||||
|
return USERCOPY_POSSIBLY_TO_USER(unsafe_buffer, &value, len);
|
||||||
|
}
|
||||||
|
case SO_TYPE: {
|
||||||
|
if (len != 4)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
int type = SOCK_STREAM;
|
||||||
|
return USERCOPY_POSSIBLY_TO_USER(unsafe_buffer, &type, len);
|
||||||
|
}
|
||||||
|
case SO_OOBINLINE:
|
||||||
|
case SO_KEEPALIVE:
|
||||||
|
case SO_REUSEADDR:
|
||||||
|
case SO_NO_CHECK:
|
||||||
|
return USERCOPY_POSSIBLY_MEMSET_TO_USER(unsafe_buffer, 0, len);
|
||||||
|
case SO_SNDBUF:
|
||||||
|
case SO_RCVBUF: {
|
||||||
|
if (len != 4)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
int value = SOCKET_BUFFER;
|
||||||
|
return USERCOPY_POSSIBLY_TO_USER(unsafe_buffer, &value, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("localsock_getopt unknown %lu %lu\n", layer, optname);
|
||||||
|
return ENOPROTOOPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static socketops_t socketops = {
|
static socketops_t socketops = {
|
||||||
@@ -1060,7 +1124,9 @@ static socketops_t socketops = {
|
|||||||
.datacount = localsocket_datacount,
|
.datacount = localsocket_datacount,
|
||||||
.getname = localsock_getname,
|
.getname = localsock_getname,
|
||||||
.getpeername = localsock_getpeername,
|
.getpeername = localsock_getpeername,
|
||||||
.shutdown = localsock_shutdown
|
.shutdown = localsock_shutdown,
|
||||||
|
.getopt = localsock_getopt,
|
||||||
|
.setopt = localsock_setopt
|
||||||
};
|
};
|
||||||
|
|
||||||
socket_t *localsock_createsocket() {
|
socket_t *localsock_createsocket() {
|
||||||
|
|||||||
Reference in New Issue
Block a user