diff options
author | Anton Kling <anton@kling.gg> | 2023-11-16 15:24:45 +0100 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2023-11-16 15:24:45 +0100 |
commit | a288258785bac3c2000227532f4a17210813c506 (patch) | |
tree | 450f6e9afdb961728f4ecbc89a91f9782e3aa4c6 /kernel/syscalls | |
parent | 6164f8564e94ffa7ee8fbfcc82f4350a35ab08a5 (diff) |
Kernel: Change how syscalls are built and implemented.
Diffstat (limited to 'kernel/syscalls')
-rw-r--r-- | kernel/syscalls/accept.c | 5 | ||||
-rw-r--r-- | kernel/syscalls/bind.c | 5 | ||||
-rw-r--r-- | kernel/syscalls/chdir.c | 6 | ||||
-rw-r--r-- | kernel/syscalls/clock_gettime.c | 10 | ||||
-rw-r--r-- | kernel/syscalls/ftruncate.c | 6 | ||||
-rw-r--r-- | kernel/syscalls/getcwd.c | 11 | ||||
-rw-r--r-- | kernel/syscalls/kill.c | 5 | ||||
-rw-r--r-- | kernel/syscalls/mkdir.c | 5 | ||||
-rw-r--r-- | kernel/syscalls/mmap.c | 7 | ||||
-rw-r--r-- | kernel/syscalls/msleep.c | 9 | ||||
-rw-r--r-- | kernel/syscalls/ppoll.c | 11 | ||||
-rw-r--r-- | kernel/syscalls/recvfrom.c | 59 | ||||
-rw-r--r-- | kernel/syscalls/sendto.c | 23 | ||||
-rw-r--r-- | kernel/syscalls/shm.c | 6 | ||||
-rw-r--r-- | kernel/syscalls/sigaction.c | 9 | ||||
-rw-r--r-- | kernel/syscalls/socket.c | 5 | ||||
-rw-r--r-- | kernel/syscalls/stat.c | 12 | ||||
-rw-r--r-- | kernel/syscalls/uptime.c | 4 |
18 files changed, 198 insertions, 0 deletions
diff --git a/kernel/syscalls/accept.c b/kernel/syscalls/accept.c new file mode 100644 index 0000000..0be578c --- /dev/null +++ b/kernel/syscalls/accept.c @@ -0,0 +1,5 @@ +#include <syscalls.h> + +int syscall_accept(SYS_ACCEPT_PARAMS *args) { + return accept(args->socket, args->address, args->address_len); +} diff --git a/kernel/syscalls/bind.c b/kernel/syscalls/bind.c new file mode 100644 index 0000000..53eeb79 --- /dev/null +++ b/kernel/syscalls/bind.c @@ -0,0 +1,5 @@ +#include <syscalls.h> + +int syscall_bind(SYS_BIND_PARAMS *args) { + return bind(args->sockfd, args->addr, args->addrlen); +} diff --git a/kernel/syscalls/chdir.c b/kernel/syscalls/chdir.c new file mode 100644 index 0000000..4b1f714 --- /dev/null +++ b/kernel/syscalls/chdir.c @@ -0,0 +1,6 @@ +#include <fs/vfs.h> +#include <syscalls.h> + +int syscall_chdir(const char *path) { + return vfs_chdir(path); +} diff --git a/kernel/syscalls/clock_gettime.c b/kernel/syscalls/clock_gettime.c new file mode 100644 index 0000000..c0696d7 --- /dev/null +++ b/kernel/syscalls/clock_gettime.c @@ -0,0 +1,10 @@ +#include <syscalls.h> + +int syscall_clock_gettime(SYS_CLOCK_GETTIME_PARAMS *args) { + // FIXME: Actually implement this + if (args->ts) { + args->ts->tv_sec = 0; + args->ts->tv_nsec = 0; + } + return 0; +} diff --git a/kernel/syscalls/ftruncate.c b/kernel/syscalls/ftruncate.c new file mode 100644 index 0000000..2ed5ccc --- /dev/null +++ b/kernel/syscalls/ftruncate.c @@ -0,0 +1,6 @@ +#include <fs/vfs.h> +#include <syscalls.h> + +int syscall_ftruncate(int fd, size_t length) { + return vfs_ftruncate(fd, length); +} diff --git a/kernel/syscalls/getcwd.c b/kernel/syscalls/getcwd.c new file mode 100644 index 0000000..6f35739 --- /dev/null +++ b/kernel/syscalls/getcwd.c @@ -0,0 +1,11 @@ +#include <math.h> +#include <syscalls.h> +#include <sched/scheduler.h> + +char *syscall_getcwd(char *buf, size_t size) { + kprintf("syscall_getcwd\n"); + const char *cwd = get_current_task()->current_working_directory; + size_t len = min(size, strlen(cwd)); + strlcpy(buf, get_current_task()->current_working_directory, len); + return buf; +} diff --git a/kernel/syscalls/kill.c b/kernel/syscalls/kill.c new file mode 100644 index 0000000..6f8c865 --- /dev/null +++ b/kernel/syscalls/kill.c @@ -0,0 +1,5 @@ +#include <syscalls.h> +#include <sched/scheduler.h> +#include <signal.h> + +int syscall_kill(pid_t pid, int sig) {return kill(pid, sig);} diff --git a/kernel/syscalls/mkdir.c b/kernel/syscalls/mkdir.c new file mode 100644 index 0000000..e7dec0b --- /dev/null +++ b/kernel/syscalls/mkdir.c @@ -0,0 +1,5 @@ +#include <syscalls.h> + +int syscall_mkdir(const char *path, int mode) { + return vfs_mkdir(path, mode); +} diff --git a/kernel/syscalls/mmap.c b/kernel/syscalls/mmap.c new file mode 100644 index 0000000..295bc13 --- /dev/null +++ b/kernel/syscalls/mmap.c @@ -0,0 +1,7 @@ +#include <syscalls.h> +#include <sched/scheduler.h> + +void *syscall_mmap(SYS_MMAP_PARAMS *args) { + return mmap(args->addr, args->length, args->prot, args->flags, args->fd, + args->offset); +} diff --git a/kernel/syscalls/msleep.c b/kernel/syscalls/msleep.c new file mode 100644 index 0000000..9880b63 --- /dev/null +++ b/kernel/syscalls/msleep.c @@ -0,0 +1,9 @@ +#include <drivers/pit.h> +#include <syscalls.h> +#include <sched/scheduler.h> +#include <stdio.h> + +void syscall_msleep(u32 ms) { + get_current_task()->sleep_until = pit_num_ms() + ms; + switch_task(); +} diff --git a/kernel/syscalls/ppoll.c b/kernel/syscalls/ppoll.c new file mode 100644 index 0000000..fa85e8c --- /dev/null +++ b/kernel/syscalls/ppoll.c @@ -0,0 +1,11 @@ +#include <syscalls.h> +#include <fs/vfs.h> +#include <poll.h> +#include <sched/scheduler.h> + +int syscall_poll(SYS_POLL_PARAMS *args) { + struct pollfd *fds = args->fds; + size_t nfds = args->nfds; + int timeout = args->timeout; + return poll(fds, nfds, timeout); +} diff --git a/kernel/syscalls/recvfrom.c b/kernel/syscalls/recvfrom.c new file mode 100644 index 0000000..ecc9fdf --- /dev/null +++ b/kernel/syscalls/recvfrom.c @@ -0,0 +1,59 @@ +#include <assert.h> +#include <fs/vfs.h> +#include <math.h> +#include <poll.h> +#include <syscalls.h> + +size_t syscall_recvfrom( + int socket, void *buffer, size_t length, int flags, + struct two_args + *extra_args /*struct sockaddr *address, socklen_t *address_len*/) { + + struct sockaddr *address = (struct sockaddr *)extra_args->a; + socklen_t *address_len = (socklen_t *)extra_args->b; + kprintf("address: %x\n", address); + kprintf("address_len: %x\n", address_len); + + if (flags & MSG_WAITALL) { + struct pollfd fds[1]; + fds[0].fd = socket; + fds[0].events = POLLIN; + poll(fds, 1, 0); + } + + u16 data_length; + socklen_t tmp_socklen; + vfs_pread(socket, &tmp_socklen, sizeof(socklen_t), 0); + if (address_len) + *address_len = tmp_socklen; + if (address) { + vfs_pread(socket, address, tmp_socklen, 0); + } else { + // We still have to throwaway the data. + char devnull[100]; + for (; tmp_socklen;) { + int rc = vfs_pread(socket, devnull, min(tmp_socklen, 100), 0); + assert(rc >= 0); + tmp_socklen -= rc; + } + } + + vfs_pread(socket, &data_length, sizeof(data_length), 0); + // If it is reading less than the packet length that could cause + // problems as the next read will not be put at a new header. Luckily + // it seems as if other UNIX systems can discard the rest of the + // packet if not read. + + // Read in the data requested + int read_len = min(length, data_length); + int rc = vfs_pread(socket, buffer, read_len, 0); + // Discard the rest of the packet + int rest = data_length - read_len; + char devnull[100]; + for (; rest;) { + int rc = vfs_pread(socket, devnull, 100, 0); + assert(rc >= 0); + rest -= rc; + } + return rc; +} diff --git a/kernel/syscalls/sendto.c b/kernel/syscalls/sendto.c new file mode 100644 index 0000000..ffedd75 --- /dev/null +++ b/kernel/syscalls/sendto.c @@ -0,0 +1,23 @@ +#include <assert.h> +#include <network/bytes.h> +#include <network/udp.h> +#include <syscalls.h> + +size_t syscall_sendto(int socket, const void *message, size_t length, + int flags, struct t_two_args *extra_args /* + const struct sockaddr *dest_addr, + socklen_t dest_len*/) { + const struct sockaddr *dest_addr = (const struct sockaddr *)extra_args->a; + socklen_t dest_len = (socklen_t)extra_args->b; + (void)dest_len; + vfs_fd_t *fd = get_vfs_fd(socket); + assert(fd); + SOCKET *s = (SOCKET *)fd->inode->internal_object; + OPEN_INET_SOCKET *inet = s->child; + assert(inet); + struct sockaddr_in in; + in.sin_addr.s_addr = inet->address; + in.sin_port = inet->port; + send_udp_packet(&in, (const struct sockaddr_in *)dest_addr, message, length); + return length; // FIXME: This is probably not true. +} diff --git a/kernel/syscalls/shm.c b/kernel/syscalls/shm.c new file mode 100644 index 0000000..18b672a --- /dev/null +++ b/kernel/syscalls/shm.c @@ -0,0 +1,6 @@ +#include <syscalls.h> +#include <fs/shm.h> + +int syscall_shm_open(SYS_SHM_OPEN_PARAMS *args) { + return shm_open(args->name, args->oflag, args->mode); +} diff --git a/kernel/syscalls/sigaction.c b/kernel/syscalls/sigaction.c new file mode 100644 index 0000000..98024ea --- /dev/null +++ b/kernel/syscalls/sigaction.c @@ -0,0 +1,9 @@ +#include <syscalls.h> +#include <signal.h> +#include <sched/scheduler.h> + +int syscall_sigaction(int sig, const struct sigaction *restrict act, + struct sigaction *restrict oact) { + set_signal_handler(sig, act->sa_handler); + return 0; +} diff --git a/kernel/syscalls/socket.c b/kernel/syscalls/socket.c new file mode 100644 index 0000000..b5c8000 --- /dev/null +++ b/kernel/syscalls/socket.c @@ -0,0 +1,5 @@ +#include <syscalls.h> + +int syscall_socket(SYS_SOCKET_PARAMS *args) { + return socket(args->domain, args->type, args->protocol); +} diff --git a/kernel/syscalls/stat.c b/kernel/syscalls/stat.c new file mode 100644 index 0000000..103ac34 --- /dev/null +++ b/kernel/syscalls/stat.c @@ -0,0 +1,12 @@ +#include <errno.h> +#include <fs/vfs.h> +#include <syscalls.h> + +int syscall_stat(SYS_STAT_PARAMS *args) { + const char *pathname = copy_and_allocate_user_string(args->pathname); + struct stat *statbuf = args->statbuf; + int fd = vfs_open(pathname, O_READ, 0); + int rc = vfs_fstat(fd, statbuf); + vfs_close(fd); + return rc; +} diff --git a/kernel/syscalls/uptime.c b/kernel/syscalls/uptime.c new file mode 100644 index 0000000..3de80ba --- /dev/null +++ b/kernel/syscalls/uptime.c @@ -0,0 +1,4 @@ +#include <syscalls.h> +#include <drivers/pit.h> + +u32 syscall_uptime(void) { return (u32)pit_num_ms(); } |