diff options
Diffstat (limited to 'kernel/scalls')
30 files changed, 312 insertions, 0 deletions
diff --git a/kernel/scalls/accept.c b/kernel/scalls/accept.c new file mode 100644 index 0000000..3c3f5ad --- /dev/null +++ b/kernel/scalls/accept.c @@ -0,0 +1,5 @@ +#include "accept.h" + +int syscall_accept(SYS_ACCEPT_PARAMS *args) { + return accept(args->socket, args->address, args->address_len); +} diff --git a/kernel/scalls/accept.h b/kernel/scalls/accept.h new file mode 100644 index 0000000..d022999 --- /dev/null +++ b/kernel/scalls/accept.h @@ -0,0 +1,9 @@ +#include "../socket.h" + +typedef struct SYS_ACCEPT_PARAMS { + int socket; + struct sockaddr *address; + socklen_t *address_len; +} __attribute__((packed)) SYS_ACCEPT_PARAMS; + +int syscall_accept(SYS_ACCEPT_PARAMS *args); diff --git a/kernel/scalls/bind.c b/kernel/scalls/bind.c new file mode 100644 index 0000000..76e36ab --- /dev/null +++ b/kernel/scalls/bind.c @@ -0,0 +1,5 @@ +#include "bind.h" + +int syscall_bind(SYS_BIND_PARAMS *args) { + return bind(args->sockfd, args->addr, args->addrlen); +} diff --git a/kernel/scalls/bind.h b/kernel/scalls/bind.h new file mode 100644 index 0000000..5661ad0 --- /dev/null +++ b/kernel/scalls/bind.h @@ -0,0 +1,9 @@ +#include "../socket.h" + +typedef struct SYS_BIND_PARAMS { + int sockfd; + const struct sockaddr *addr; + socklen_t addrlen; +} __attribute__((packed)) SYS_BIND_PARAMS; + +int syscall_bind(SYS_BIND_PARAMS *args); diff --git a/kernel/scalls/clock_gettime.c b/kernel/scalls/clock_gettime.c new file mode 100644 index 0000000..632ea08 --- /dev/null +++ b/kernel/scalls/clock_gettime.c @@ -0,0 +1,10 @@ +#include <scalls/clock_gettime.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/scalls/clock_gettime.h b/kernel/scalls/clock_gettime.h new file mode 100644 index 0000000..145aa24 --- /dev/null +++ b/kernel/scalls/clock_gettime.h @@ -0,0 +1,8 @@ +#include <time.h> + +typedef struct SYS_CLOCK_GETTIME_PARAMS { + clockid_t clk; + struct timespec *ts; +} __attribute__((packed)) SYS_CLOCK_GETTIME_PARAMS; + +int syscall_clock_gettime(SYS_CLOCK_GETTIME_PARAMS *args); diff --git a/kernel/scalls/ftruncate.c b/kernel/scalls/ftruncate.c new file mode 100644 index 0000000..6bc1170 --- /dev/null +++ b/kernel/scalls/ftruncate.c @@ -0,0 +1,6 @@ +#include <fs/vfs.h> +#include <scalls/ftruncate.h> + +int syscall_ftruncate(int fd, size_t length) { + return vfs_ftruncate(fd, length); +} diff --git a/kernel/scalls/ftruncate.h b/kernel/scalls/ftruncate.h new file mode 100644 index 0000000..9213e85 --- /dev/null +++ b/kernel/scalls/ftruncate.h @@ -0,0 +1,2 @@ +#include <stddef.h> +int syscall_ftruncate(int fd, size_t length); diff --git a/kernel/scalls/kill.c b/kernel/scalls/kill.c new file mode 100644 index 0000000..d5b7445 --- /dev/null +++ b/kernel/scalls/kill.c @@ -0,0 +1,5 @@ +#include <scalls/kill.h> +#include <sched/scheduler.h> +#include <signal.h> + +int syscall_kill(pid_t pid, int sig) {return kill(pid, sig);} diff --git a/kernel/scalls/kill.h b/kernel/scalls/kill.h new file mode 100644 index 0000000..acf5f30 --- /dev/null +++ b/kernel/scalls/kill.h @@ -0,0 +1,2 @@ +#include <signal.h> +int syscall_kill(pid_t pid, int sig); diff --git a/kernel/scalls/mkdir.c b/kernel/scalls/mkdir.c new file mode 100644 index 0000000..43f2424 --- /dev/null +++ b/kernel/scalls/mkdir.c @@ -0,0 +1,5 @@ +#include <scalls/mkdir.h> + +int syscall_mkdir(const char *path, int mode) { + return vfs_mkdir(path, mode); +} diff --git a/kernel/scalls/mkdir.h b/kernel/scalls/mkdir.h new file mode 100644 index 0000000..0bf0043 --- /dev/null +++ b/kernel/scalls/mkdir.h @@ -0,0 +1,2 @@ +#include <fs/vfs.h> +int syscall_mkdir(const char *path, int mode); diff --git a/kernel/scalls/mmap.c b/kernel/scalls/mmap.c new file mode 100644 index 0000000..83fff6a --- /dev/null +++ b/kernel/scalls/mmap.c @@ -0,0 +1,7 @@ +#include <scalls/mmap.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/scalls/mmap.h b/kernel/scalls/mmap.h new file mode 100644 index 0000000..f5e121e --- /dev/null +++ b/kernel/scalls/mmap.h @@ -0,0 +1,13 @@ +#include <stddef.h> +#include <stdint.h> + +typedef struct SYS_MMAP_PARAMS { + void *addr; + size_t length; + int prot; + int flags; + int fd; + size_t offset; +} __attribute__((packed)) SYS_MMAP_PARAMS; + +void *syscall_mmap(SYS_MMAP_PARAMS *args); diff --git a/kernel/scalls/msleep.c b/kernel/scalls/msleep.c new file mode 100644 index 0000000..0120f08 --- /dev/null +++ b/kernel/scalls/msleep.c @@ -0,0 +1,9 @@ +#include <drivers/pit.h> +#include <scalls/msleep.h> +#include <sched/scheduler.h> +#include <stdio.h> + +void syscall_msleep(uint32_t ms) { + get_current_task()->sleep_until = pit_num_ms() + ms; + switch_task(); +} diff --git a/kernel/scalls/msleep.h b/kernel/scalls/msleep.h new file mode 100644 index 0000000..71bf269 --- /dev/null +++ b/kernel/scalls/msleep.h @@ -0,0 +1,5 @@ +#ifndef MSLEEP_H +#define MSLEEP_H +#include <stdint.h> +void syscall_msleep(uint32_t ms); +#endif diff --git a/kernel/scalls/ppoll.c b/kernel/scalls/ppoll.c new file mode 100644 index 0000000..8feb35c --- /dev/null +++ b/kernel/scalls/ppoll.c @@ -0,0 +1,11 @@ +#include <scalls/ppoll.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/scalls/ppoll.h b/kernel/scalls/ppoll.h new file mode 100644 index 0000000..13700b5 --- /dev/null +++ b/kernel/scalls/ppoll.h @@ -0,0 +1,9 @@ +#include <stddef.h> + +typedef struct SYS_POLL_PARAMS { + struct pollfd *fds; + size_t nfds; + int timeout; +} __attribute__((packed)) SYS_POLL_PARAMS; + +int syscall_poll(SYS_POLL_PARAMS *args); diff --git a/kernel/scalls/recvfrom.c b/kernel/scalls/recvfrom.c new file mode 100644 index 0000000..1770fa1 --- /dev/null +++ b/kernel/scalls/recvfrom.c @@ -0,0 +1,59 @@ +#include <assert.h> +#include <fs/vfs.h> +#include <math.h> +#include <poll.h> +#include <scalls/recvfrom.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); + } + + uint16_t 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/scalls/recvfrom.h b/kernel/scalls/recvfrom.h new file mode 100644 index 0000000..d81a1e0 --- /dev/null +++ b/kernel/scalls/recvfrom.h @@ -0,0 +1,11 @@ +#include <socket.h> + +struct two_args { + uint32_t a; + uint32_t b; +}; + +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*/); diff --git a/kernel/scalls/sendto.c b/kernel/scalls/sendto.c new file mode 100644 index 0000000..48c4020 --- /dev/null +++ b/kernel/scalls/sendto.c @@ -0,0 +1,23 @@ +#include <assert.h> +#include <network/bytes.h> +#include <network/udp.h> +#include <scalls/sendto.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/scalls/sendto.h b/kernel/scalls/sendto.h new file mode 100644 index 0000000..0f852de --- /dev/null +++ b/kernel/scalls/sendto.h @@ -0,0 +1,11 @@ +#include <socket.h> +#include <stdint.h> + +struct t_two_args { + uint32_t a; + uint32_t b; +}; +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*/); diff --git a/kernel/scalls/shm.c b/kernel/scalls/shm.c new file mode 100644 index 0000000..979084a --- /dev/null +++ b/kernel/scalls/shm.c @@ -0,0 +1,6 @@ +#include "shm.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/scalls/shm.h b/kernel/scalls/shm.h new file mode 100644 index 0000000..80e4366 --- /dev/null +++ b/kernel/scalls/shm.h @@ -0,0 +1,14 @@ +#ifndef SYS_SHM_H +#define SYS_SHM_H +#include <stddef.h> +#include <stdint.h> +typedef int mode_t; + +typedef struct SYS_SHM_OPEN_PARAMS { + const char *name; + int oflag; + mode_t mode; +} __attribute__((packed)) SYS_SHM_OPEN_PARAMS; + +int syscall_shm_open(SYS_SHM_OPEN_PARAMS *args); +#endif diff --git a/kernel/scalls/socket.c b/kernel/scalls/socket.c new file mode 100644 index 0000000..594c745 --- /dev/null +++ b/kernel/scalls/socket.c @@ -0,0 +1,5 @@ +#include "socket.h" + +int syscall_socket(SYS_SOCKET_PARAMS *args) { + return socket(args->domain, args->type, args->protocol); +} diff --git a/kernel/scalls/socket.h b/kernel/scalls/socket.h new file mode 100644 index 0000000..6540b0f --- /dev/null +++ b/kernel/scalls/socket.h @@ -0,0 +1,9 @@ +#include "../socket.h" + +typedef struct SYS_SOCKET_PARAMS { + int domain; + int type; + int protocol; +} __attribute__((packed)) SYS_SOCKET_PARAMS; + +int syscall_socket(SYS_SOCKET_PARAMS *args); diff --git a/kernel/scalls/stat.c b/kernel/scalls/stat.c new file mode 100644 index 0000000..0850151 --- /dev/null +++ b/kernel/scalls/stat.c @@ -0,0 +1,13 @@ +#include <errno.h> +#include <fs/vfs.h> +#include <scalls/stat.h> + +int syscall_stat(SYS_STAT_PARAMS *args) { + const char *pathname = copy_and_allocate_user_string(args->pathname); + struct stat *statbuf = args->statbuf; + vfs_inode_t *i = vfs_internal_open(pathname); + if (!i) + return -ENOENT; + statbuf->st_size = i->file_size; + return 0; +} diff --git a/kernel/scalls/stat.h b/kernel/scalls/stat.h new file mode 100644 index 0000000..78e8c45 --- /dev/null +++ b/kernel/scalls/stat.h @@ -0,0 +1,33 @@ +#include <types.h> +#include <time.h> + +typedef struct SYS_STAT_PARAMS { + const char *pathname; + struct stat *statbuf; +} __attribute__((packed)) SYS_STAT_PARAMS; + +struct stat { + dev_t st_dev; // Device ID of device containing file. + ino_t st_ino; // File serial number. + mode_t st_mode; // Mode of file (see below). + nlink_t st_nlink; // Number of hard links to the file. + uid_t st_uid; // User ID of file. + gid_t st_gid; // Group ID of file. + dev_t st_rdev; // Device ID (if file is character or block special). + off_t st_size; // For regular files, the file size in bytes. + // For symbolic links, the length in bytes of the + // pathname contained in the symbolic link. + // For a shared memory object, the length in bytes. + // For a typed memory object, the length in bytes. + // For other file types, the use of this field is + // unspecified. + struct timespec st_atim; // Last data access timestamp. + struct timespec st_mtim; // Last data modification timestamp. + struct timespec st_ctim; // Last file status change timestamp. + blksize_t st_blksize; // A file system-specific preferred I/O block size + // for this object. In some file system types, this + // may vary from file to file. + blkcnt_t st_blocks; // Number of blocks allocated for this object. +}; + +int syscall_stat(SYS_STAT_PARAMS *args); diff --git a/kernel/scalls/uptime.c b/kernel/scalls/uptime.c new file mode 100644 index 0000000..866c7e5 --- /dev/null +++ b/kernel/scalls/uptime.c @@ -0,0 +1,4 @@ +#include <scalls/uptime.h> +#include <drivers/pit.h> + +uint32_t syscall_uptime(void) { return (uint32_t)pit_num_ms(); } diff --git a/kernel/scalls/uptime.h b/kernel/scalls/uptime.h new file mode 100644 index 0000000..2b5b0c9 --- /dev/null +++ b/kernel/scalls/uptime.h @@ -0,0 +1,2 @@ +#include <stdint.h> +uint32_t syscall_uptime(void); |