mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 20:58:22 +00:00
syscalls: shutdown
This commit is contained in:
@@ -91,6 +91,7 @@ extern syscall_sigsuspend
|
||||
extern syscall_sigtimedwait
|
||||
extern syscall_sigpending
|
||||
extern syscall_killthread
|
||||
extern syscall_shutdown
|
||||
syscalltab:
|
||||
dq syscall_print
|
||||
dq syscall_mmap
|
||||
@@ -184,7 +185,8 @@ dq syscall_sigsuspend
|
||||
dq syscall_sigtimedwait
|
||||
dq syscall_sigpending
|
||||
dq syscall_killthread
|
||||
syscallcount equ 92
|
||||
dq syscall_shutdown
|
||||
syscallcount equ 93
|
||||
section .text
|
||||
global arch_syscall_entry
|
||||
; on entry:
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
#ifdef SYSCALL_LOGGING
|
||||
|
||||
#define SYSCALL_COUNT 92
|
||||
#define SYSCALL_COUNT 93
|
||||
#define LOGSTR(x) arch_e9_puts(x)
|
||||
|
||||
static char *name[] = {
|
||||
@@ -100,7 +100,8 @@ static char *name[] = {
|
||||
"sigsuspend",
|
||||
"sigtimedwait",
|
||||
"sigpending",
|
||||
"killthread"
|
||||
"killthread",
|
||||
"shutdown"
|
||||
};
|
||||
|
||||
static char *args[] = {
|
||||
@@ -195,7 +196,8 @@ static char *args[] = {
|
||||
"sigset %p", // sigsuspend
|
||||
"sigset %p info %p, timespec %p", // sigtimedwait
|
||||
"sigset %p\n", // sigpending
|
||||
"pid %d tid %d signal %d" // killthread
|
||||
"pid %d tid %d signal %d", // killthread
|
||||
"how %d" // shutdown
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -13,6 +13,10 @@
|
||||
#define SOCKET_STATE_CONNECTED 2
|
||||
#define SOCKET_STATE_LISTENING 3
|
||||
|
||||
#define SOCKET_SHUTDOWN_READ 1
|
||||
#define SOCKET_SHUTDOWN_WRITE 2
|
||||
#define SOCKET_SHUTDOWN_RW 3
|
||||
|
||||
typedef struct {
|
||||
struct socketops_t *ops;
|
||||
mutex_t mutex;
|
||||
@@ -21,6 +25,7 @@ typedef struct {
|
||||
netdev_t *netdev;
|
||||
pollheader_t pollheader;
|
||||
int type;
|
||||
int shutdown;
|
||||
} socket_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -67,6 +72,7 @@ typedef struct socketops_t {
|
||||
size_t (*datacount)(socket_t *socket);
|
||||
void (*destroy)(socket_t *socket);
|
||||
int (*setopt)(socket_t *socket, int optname, void *buffer, size_t len, cred_t *cred);
|
||||
int (*shutdown)(socket_t *socket, int how);
|
||||
} socketops_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
struct localpair_t;
|
||||
struct binding_t;
|
||||
typedef struct {
|
||||
socket_t socket;
|
||||
socket_t socket; // shutdown state is shared with pair
|
||||
ringbuffer_t ringbuffer; // shared with pair
|
||||
// client/connected server
|
||||
struct localpair_t *pair;
|
||||
@@ -1003,6 +1003,47 @@ static int localsock_getpeername(socket_t *socket, sockaddr_t *addr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int localsock_shutdown(socket_t *socket, int how) {
|
||||
localsocket_t *localsocket = (localsocket_t *)socket;
|
||||
MUTEX_ACQUIRE(&socket->mutex);
|
||||
int error;
|
||||
|
||||
localpair_t *pair = localsocket->pair;
|
||||
// socket not connected
|
||||
if (pair == NULL) {
|
||||
error = ENOTCONN;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
MUTEX_ACQUIRE(&pair->mutex);
|
||||
|
||||
localsocket_t *peer = localsocket->pair->client == localsocket ? localsocket->pair->server : localsocket->pair->client;
|
||||
|
||||
socket->shutdown |= how;
|
||||
|
||||
int poll_events = 0;
|
||||
|
||||
// XXX is this the correct behaviour?
|
||||
if (how & SOCKET_SHUTDOWN_READ)
|
||||
poll_events |= POLLHUP;
|
||||
|
||||
if (how & SOCKET_SHUTDOWN_WRITE)
|
||||
poll_events |= POLLIN;
|
||||
|
||||
if (peer)
|
||||
poll_event(&peer->socket.pollheader, poll_events);
|
||||
|
||||
error = 0;
|
||||
|
||||
leave:
|
||||
if (pair)
|
||||
MUTEX_RELEASE(&pair->mutex);
|
||||
|
||||
MUTEX_RELEASE(&socket->mutex);
|
||||
return error;
|
||||
|
||||
}
|
||||
|
||||
static socketops_t socketops = {
|
||||
.bind = localsock_bind,
|
||||
.listen = localsock_listen,
|
||||
@@ -1014,7 +1055,8 @@ static socketops_t socketops = {
|
||||
.poll = localsock_poll,
|
||||
.datacount = localsocket_datacount,
|
||||
.getname = localsock_getname,
|
||||
.getpeername = localsock_getpeername
|
||||
.getpeername = localsock_getpeername,
|
||||
.shutdown = localsock_shutdown
|
||||
};
|
||||
|
||||
socket_t *localsock_createsocket() {
|
||||
|
||||
@@ -1832,6 +1832,11 @@ static int tcp_setopt(socket_t *socket, int optname, void *buffer, size_t len, c
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tcp_shutdown(socket_t *socket, int how) {
|
||||
printf("tcp: shutdown is not implemented\n");
|
||||
return ENOSYS;
|
||||
}
|
||||
|
||||
static socketops_t socketops = {
|
||||
.bind = tcp_bind,
|
||||
.send = tcp_send,
|
||||
@@ -1844,7 +1849,8 @@ static socketops_t socketops = {
|
||||
.destroy = tcp_destroy,
|
||||
.getname = tcp_getname,
|
||||
.getpeername = tcp_getpeername,
|
||||
.setopt = tcp_setopt
|
||||
.setopt = tcp_setopt,
|
||||
.shutdown = tcp_shutdown
|
||||
};
|
||||
|
||||
socket_t *tcp_createsocket() {
|
||||
|
||||
+23
-3
@@ -109,7 +109,7 @@ void udp_process(netdev_t *netdev, void *buffer, uint32_t peer) {
|
||||
|
||||
spinlock_release(&portlock);
|
||||
|
||||
if (socket == NULL) // drop packet if no socket listening on port
|
||||
if (socket == NULL || (socket->socket.shutdown & SOCKET_SHUTDOWN_READ)) // drop packet if no socket listening on port or its not accepting incoming data
|
||||
return;
|
||||
|
||||
dataheader_t header = {
|
||||
@@ -185,7 +185,14 @@ static int udp_send(socket_t *socket, sockdesc_t *sockdesc) {
|
||||
int e;
|
||||
MUTEX_ACQUIRE(&socket->mutex);
|
||||
|
||||
if (sockdesc->addr == NULL && socket->state != SOCKET_STATE_CONNECTED) {
|
||||
if (socket->shutdown & SOCKET_SHUTDOWN_WRITE) {
|
||||
// XXX should SIGPIPE be sent in this case?
|
||||
e = 0;
|
||||
sockdesc->donecount = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sockdesc->addr == NULL) {
|
||||
e = ENOTCONN;
|
||||
goto cleanup;
|
||||
}
|
||||
@@ -337,6 +344,18 @@ static int udp_poll(socket_t *socket, polldata_t *data, int events) {
|
||||
return revents;
|
||||
}
|
||||
|
||||
static int udp_shutdown(socket_t *socket, int how) {
|
||||
if (how > SOCKET_SHUTDOWN_RW)
|
||||
return EINVAL;
|
||||
|
||||
MUTEX_ACQUIRE(&socket->mutex);
|
||||
|
||||
socket->shutdown |= how;
|
||||
|
||||
MUTEX_RELEASE(&socket->mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static socketops_t socketops = {
|
||||
.bind = udp_bind,
|
||||
.send = udp_send,
|
||||
@@ -344,7 +363,8 @@ static socketops_t socketops = {
|
||||
.destroy = udp_destroy,
|
||||
.poll = udp_poll,
|
||||
.getname = udp_getname,
|
||||
.getpeername = udp_getpeername
|
||||
.getpeername = udp_getpeername,
|
||||
.shutdown = udp_shutdown
|
||||
};
|
||||
|
||||
socket_t *udp_createsocket() {
|
||||
|
||||
@@ -12,6 +12,18 @@ index 87bc25f..d7370d0 100644
|
||||
#define IPPROTO_IP 0
|
||||
#define IPPROTO_HOPOPTS 0
|
||||
#define IPPROTO_ICMP 1
|
||||
diff --git mlibc-clean/meson.build mlibc-workdir/meson.build
|
||||
index 39796b5..7d671fc 100644
|
||||
--- mlibc-clean/meson.build
|
||||
+++ mlibc-workdir/meson.build
|
||||
@@ -268,6 +268,7 @@ elif host_machine.system() == 'astral'
|
||||
libc_include_dirs += include_directories('sysdeps/astral/include')
|
||||
internal_conf.set10('MLIBC_MAP_DSO_SEGMENTS', true)
|
||||
internal_conf.set10('MLIBC_MAP_FILE_WINDOWS', true)
|
||||
+ internal_conf.set10('MLIBC_MMAP_ALLOCATE_DSO', true)
|
||||
subdir('sysdeps/astral')
|
||||
else
|
||||
error('No sysdeps defined for OS: ' + host_machine.system())
|
||||
diff --git mlibc-clean/options/ansi/generic/environment.cpp mlibc-workdir/options/ansi/generic/environment.cpp
|
||||
index 5625592..36b42ee 100644
|
||||
--- mlibc-clean/options/ansi/generic/environment.cpp
|
||||
@@ -111,8 +123,21 @@ index 9219ef0..1ff679c 100644
|
||||
#if __MLIBC_POSIX_OPTION
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
diff --git mlibc-clean/sysdeps/astral/generic/astral.cpp mlibc-workdir/sysdeps/astral/generic/astral.cpp
|
||||
index d5ba7b2..a86353f 100644
|
||||
--- mlibc-clean/sysdeps/astral/generic/astral.cpp
|
||||
+++ mlibc-workdir/sysdeps/astral/generic/astral.cpp
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#ifndef MLIBC_BUILDING_RTLD
|
||||
|
||||
-int syscall_archctl(int func, void *arg) {
|
||||
+int arch_ctl(int func, void *arg) {
|
||||
long ret;
|
||||
long error = syscall(SYSCALL_ARCHCTL, &ret, func, (uint64_t)arg);
|
||||
if(error)
|
||||
diff --git mlibc-clean/sysdeps/astral/generic/generic.cpp mlibc-workdir/sysdeps/astral/generic/generic.cpp
|
||||
index 2a504ab..61c3bf0 100644
|
||||
index 2a504ab..3c46318 100644
|
||||
--- mlibc-clean/sysdeps/astral/generic/generic.cpp
|
||||
+++ mlibc-workdir/sysdeps/astral/generic/generic.cpp
|
||||
@@ -31,6 +31,12 @@ namespace mlibc {
|
||||
@@ -128,7 +153,19 @@ index 2a504ab..61c3bf0 100644
|
||||
int sys_getsockopt(int fd, int layer, int number,
|
||||
void *__restrict buffer, socklen_t *__restrict size) {
|
||||
(void)size;
|
||||
@@ -161,7 +167,18 @@ namespace mlibc {
|
||||
@@ -40,6 +46,11 @@ namespace mlibc {
|
||||
return 0;
|
||||
}
|
||||
|
||||
+ int sys_shutdown(int sockfd, int how) {
|
||||
+ long ret;
|
||||
+ return syscall(SYSCALL_SHUTDOWN, &ret, sockfd, how);
|
||||
+ }
|
||||
+
|
||||
int sys_tgkill(int pid, int tid, int sig) {
|
||||
long ret;
|
||||
return syscall(SYSCALL_KILLTHREAD, &ret, pid, tid, sig);
|
||||
@@ -161,7 +172,18 @@ namespace mlibc {
|
||||
*bytes_written = writec;
|
||||
return error;
|
||||
}
|
||||
@@ -148,7 +185,7 @@ index 2a504ab..61c3bf0 100644
|
||||
#ifndef MLIBC_BUILDING_RTLD
|
||||
|
||||
typedef struct {
|
||||
@@ -487,6 +504,12 @@ namespace mlibc {
|
||||
@@ -487,6 +509,12 @@ namespace mlibc {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -161,3 +198,58 @@ index 2a504ab..61c3bf0 100644
|
||||
#ifndef MLIBC_BUILDING_RTLD
|
||||
|
||||
[[noreturn]] void sys_thread_exit() {
|
||||
@@ -882,7 +910,7 @@ namespace mlibc {
|
||||
|
||||
int sys_tcb_set(void *pointer) {
|
||||
long r;
|
||||
- return syscall(SYSCALL_ARCHCTL, &r, ARCH_CTL_FSBASE, (uint64_t)pointer);
|
||||
+ return syscall(SYSCALL_ARCHCTL, &r, ARCH_CTL_SET_FSBASE, (uint64_t)pointer);
|
||||
}
|
||||
|
||||
#define FUTEX_WAIT 0
|
||||
diff --git mlibc-clean/sysdeps/astral/include/astral/archctl.h mlibc-workdir/sysdeps/astral/include/astral/archctl.h
|
||||
index d738e02..7e4f2a1 100644
|
||||
--- mlibc-clean/sysdeps/astral/include/astral/archctl.h
|
||||
+++ mlibc-workdir/sysdeps/astral/include/astral/archctl.h
|
||||
@@ -1,8 +1,10 @@
|
||||
#ifndef _ASTRAL_ARCHCTL_H
|
||||
#define _ASTRAL_ARCHCTL_H
|
||||
|
||||
-#define ARCH_CTL_GSBASE 0
|
||||
-#define ARCH_CTL_FSBASE 1
|
||||
+#define ARCH_CTL_SET_GSBASE 0
|
||||
+#define ARCH_CTL_SET_FSBASE 1
|
||||
+#define ARCH_CTL_GET_GSBASE 2
|
||||
+#define ARCH_CTL_GET_FSBASE 3
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
diff --git mlibc-clean/sysdeps/astral/include/astral/syscall.h mlibc-workdir/sysdeps/astral/include/astral/syscall.h
|
||||
index 5f42d62..852f9ff 100644
|
||||
--- mlibc-clean/sysdeps/astral/include/astral/syscall.h
|
||||
+++ mlibc-workdir/sysdeps/astral/include/astral/syscall.h
|
||||
@@ -96,6 +96,7 @@
|
||||
#define SYSCALL_SIGTIMEDWAIT 89
|
||||
#define SYSCALL_SIGPENDING 90
|
||||
#define SYSCALL_KILLTHREAD 91
|
||||
+#define SYSCALL_SHUTDOWN 92
|
||||
|
||||
#ifndef __MLIBC_ABI_ONLY
|
||||
|
||||
diff --git mlibc-clean/sysdeps/astral/meson.build mlibc-workdir/sysdeps/astral/meson.build
|
||||
index a5ede46..e198d2e 100644
|
||||
--- mlibc-clean/sysdeps/astral/meson.build
|
||||
+++ mlibc-workdir/sysdeps/astral/meson.build
|
||||
@@ -63,6 +63,12 @@ if not no_headers
|
||||
subdir: 'abi-bits',
|
||||
follow_symlinks: true,
|
||||
)
|
||||
+ install_headers(
|
||||
+ 'include/astral/syscall.h',
|
||||
+ 'include/astral/archctl.h',
|
||||
+ subdir: 'astral',
|
||||
+ follow_symlinks: true,
|
||||
+ )
|
||||
endif
|
||||
|
||||
if not headers_only
|
||||
|
||||
Reference in New Issue
Block a user