summaryrefslogtreecommitdiff
path: root/kernel/syscalls
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2023-11-16 15:24:45 +0100
committerAnton Kling <anton@kling.gg>2023-11-16 15:24:45 +0100
commita288258785bac3c2000227532f4a17210813c506 (patch)
tree450f6e9afdb961728f4ecbc89a91f9782e3aa4c6 /kernel/syscalls
parent6164f8564e94ffa7ee8fbfcc82f4350a35ab08a5 (diff)
Kernel: Change how syscalls are built and implemented.
Diffstat (limited to 'kernel/syscalls')
-rw-r--r--kernel/syscalls/accept.c5
-rw-r--r--kernel/syscalls/bind.c5
-rw-r--r--kernel/syscalls/chdir.c6
-rw-r--r--kernel/syscalls/clock_gettime.c10
-rw-r--r--kernel/syscalls/ftruncate.c6
-rw-r--r--kernel/syscalls/getcwd.c11
-rw-r--r--kernel/syscalls/kill.c5
-rw-r--r--kernel/syscalls/mkdir.c5
-rw-r--r--kernel/syscalls/mmap.c7
-rw-r--r--kernel/syscalls/msleep.c9
-rw-r--r--kernel/syscalls/ppoll.c11
-rw-r--r--kernel/syscalls/recvfrom.c59
-rw-r--r--kernel/syscalls/sendto.c23
-rw-r--r--kernel/syscalls/shm.c6
-rw-r--r--kernel/syscalls/sigaction.c9
-rw-r--r--kernel/syscalls/socket.c5
-rw-r--r--kernel/syscalls/stat.c12
-rw-r--r--kernel/syscalls/uptime.c4
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(); }