diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml index 770233583..3268b2146 100644 --- a/.github/workflows/style.yml +++ b/.github/workflows/style.yml @@ -10,7 +10,7 @@ on: push: branches: ["main"] pull_request: - branches: ["main"] + branches: ["main", "144-support-musl"] jobs: formatting-check: diff --git a/so3/arch/arm32/include/asm/syscall_number.h b/so3/arch/arm32/include/asm/syscall_number.h index 7474f8f2e..1da6a2f71 100644 --- a/so3/arch/arm32/include/asm/syscall_number.h +++ b/so3/arch/arm32/include/asm/syscall_number.h @@ -78,4 +78,7 @@ #define SYSCALL_SETSOCKOPT 110 #define SYSCALL_RECVFROM 111 +#define SYSCALL_READV 145 +#define SYSCALL_WRITEV 146 + #endif /* ARCH_ARM32_SYSCALL_NUMBER_H */ diff --git a/so3/arch/arm64/include/asm/syscall_number.h b/so3/arch/arm64/include/asm/syscall_number.h index d81a0858a..2cbbea82d 100644 --- a/so3/arch/arm64/include/asm/syscall_number.h +++ b/so3/arch/arm64/include/asm/syscall_number.h @@ -71,6 +71,9 @@ #define SYSCALL_MUTEX_LOCK 60 #define SYSCALL_MUTEX_UNLOCK 61 +#define SYSCALL_READV 65 +#define SYSCALL_WRITEV 66 + #define SYSCALL_NANOSLEEP 70 #define SYSCALL_SYSINFO 99 diff --git a/so3/devices/serial/pl011.c b/so3/devices/serial/pl011.c index 6bd6bee18..601be88f2 100644 --- a/so3/devices/serial/pl011.c +++ b/so3/devices/serial/pl011.c @@ -119,7 +119,7 @@ static irq_return_t pl011_int(int irq, void *dummy) #ifdef CONFIG_IPC_SIGNAL if (current()->pcb != NULL) - do_kill(current()->pcb->pid, SIGINT); + sys_do_kill(current()->pcb->pid, SIGINT); #endif } diff --git a/so3/fs/elf.c b/so3/fs/elf.c index dce824587..0489e7de5 100644 --- a/so3/fs/elf.c +++ b/so3/fs/elf.c @@ -35,12 +35,12 @@ uint8_t *elf_load_buffer(const char *filename) struct stat st; /* open and read file */ - fd = do_open(filename, O_RDONLY); + fd = sys_do_open(filename, O_RDONLY); if (fd < 0) return NULL; - if (do_stat(filename, &st)) + if (sys_do_stat(filename, &st)) return NULL; if (!st.st_size) @@ -52,9 +52,9 @@ uint8_t *elf_load_buffer(const char *filename) return NULL; } - do_read(fd, buffer, st.st_size); + sys_do_read(fd, buffer, st.st_size); - do_close(fd); + sys_do_close(fd); return buffer; } diff --git a/so3/fs/vfs.c b/so3/fs/vfs.c index 3f1ac96a2..1ba8de20f 100644 --- a/so3/fs/vfs.c +++ b/so3/fs/vfs.c @@ -380,7 +380,8 @@ int vfs_clone_fd(int *fd_src, int *fd_dst) /**************************** Syscall implementation ****************************/ -SYSCALL_DEFINE3(read, int, fd, void *, buffer, int, count) +/* Low Level read */ +static int do_read(int fd, void *buffer, int count) { int gfd; int ret; @@ -421,10 +422,8 @@ SYSCALL_DEFINE3(read, int, fd, void *, buffer, int, count) return ret; } -/** - * @brief This function writes a REGULAR FILE/FOLDER. It only support regular file, dirs and pipes - */ -SYSCALL_DEFINE3(write, int, fd, const void *, buffer, int, count) +/* Low Level write */ +static int do_write(int fd, const void *buffer, int count) { int gfd; int ret; @@ -464,6 +463,19 @@ SYSCALL_DEFINE3(write, int, fd, const void *, buffer, int, count) return ret; } +SYSCALL_DEFINE3(read, int, fd, void *, buffer, int, count) +{ + return do_read(fd, buffer, count); +} + +/** + * @brief This function writes a REGULAR FILE/FOLDER. It only support regular file, dirs and pipes + */ +SYSCALL_DEFINE3(write, int, fd, const void *, buffer, int, count) +{ + return do_write(fd, buffer, count); +} + /** * @brief This function opens a file. Not all file types are supported. */ @@ -655,7 +667,7 @@ SYSCALL_DEFINE2(dup2, int, oldfd, int, newfd) } if (vfs_get_gfd(oldfd) != vfs_get_gfd(newfd)) - do_close(newfd); + sys_do_close(newfd); vfs_link_fd(newfd, vfs_get_gfd(oldfd)); @@ -824,6 +836,57 @@ SYSCALL_DEFINE3(fcntl, int, fd, unsigned long, cmd, unsigned long, args) return 0; } +/* + * Implementation of the writev syscall + */ +SYSCALL_DEFINE3(writev, unsigned long, fd, const struct iovec *, vec, unsigned long, vlen) +{ + int i; + int ret = 0; + int total = 0; + + for (i = 0; i < vlen; i++) { + ret = do_write(fd, (const void *) vec[i].iov_base, vec[i].iov_len); + if (ret < 0) { + break; + } else if ((ret >= 0) && (ret < vec[i].iov_len)) { + total += ret; + break; + } + + total += ret; + } + + if (total == 0) + return ret; + else + return total; +} + +SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec *, vec, unsigned long, vlen) +{ + int i; + int ret = 0; + int total = 0; + + for (i = 0; i < vlen; i++) { + ret = do_read(fd, vec[i].iov_base, vec[i].iov_len); + if (ret < 0) { + break; + } else if ((ret >= 0) && (ret < vec[i].iov_len)) { + total += ret; + break; + } + + total += ret; + } + + if (total == 0) + return ret; + else + return total; +} + static void vfs_gfd_init(void) { memset(open_fds, 0, MAX_FDS * sizeof(struct fd *)); diff --git a/so3/include/syscall.h b/so3/include/syscall.h index eaf3ed73b..1c1031576 100644 --- a/so3/include/syscall.h +++ b/so3/include/syscall.h @@ -84,20 +84,20 @@ * __sys_SYSCALL_NAME taking syscall_args_t as arguments allowing for * a common interface between all syscall to put them in an array. * - * do_SYSCALL_NAME actual function with the syscall implementation with + * sys_do_SYSCALL_NAME actual function with the syscall implementation with * arguments define like a normal function. That function is automatically * called by __sys_SYCALL_NAME with the correct argument number and cast. */ #define SYSCALL_DECLARE(name, ...) \ long __sys_##name(syscall_args_t *args); \ - inline long do_##name(__VA_ARGS__); + inline long sys_do_##name(__VA_ARGS__); #define SYSCALL_DEFINE0(name) \ long __sys_##name(syscall_args_t *unused) \ { \ - return do_##name(); \ + return sys_do_##name(); \ } \ - inline long do_##name(void) + inline long sys_do_##name(void) #define SYSCALL_DEFINE1(...) __SYSCALL_DEFINEx(1, __VA_ARGS__) #define SYSCALL_DEFINE2(...) __SYSCALL_DEFINEx(2, __VA_ARGS__) #define SYSCALL_DEFINE3(...) __SYSCALL_DEFINEx(3, __VA_ARGS__) @@ -105,12 +105,12 @@ #define SYSCALL_DEFINE5(...) __SYSCALL_DEFINEx(5, __VA_ARGS__) #define SYSCALL_DEFINE6(...) __SYSCALL_DEFINEx(6, __VA_ARGS__) -#define __SYSCALL_DEFINEx(x, name, ...) \ - long __sys_##name(syscall_args_t *args) \ - { \ - return do_##name(__MAP_ARGS(x, args->args, __VA_ARGS__)); \ - } \ - inline long do_##name(__MAP(x, __M_DECL, __VA_ARGS__)) +#define __SYSCALL_DEFINEx(x, name, ...) \ + long __sys_##name(syscall_args_t *args) \ + { \ + return sys_do_##name(__MAP_ARGS(x, args->args, __VA_ARGS__)); \ + } \ + inline long sys_do_##name(__MAP(x, __M_DECL, __VA_ARGS__)) typedef struct { unsigned long args[6]; diff --git a/so3/include/vfs.h b/so3/include/vfs.h index a6956db23..b75836586 100644 --- a/so3/include/vfs.h +++ b/so3/include/vfs.h @@ -103,6 +103,13 @@ #include +struct iovec { + void *iov_base; + size_t iov_len; +}; + +#define iovec iovec + struct file_operations { int (*open)(int fd, const char *path); int (*close)(int fd); @@ -162,6 +169,8 @@ SYSCALL_DECLARE(mmap, addr_t start, size_t length, int prot, int fd, off_t offse SYSCALL_DECLARE(ioctl, int fd, unsigned long cmd, unsigned long args); SYSCALL_DECLARE(fcntl, int fd, unsigned long cmd, unsigned long args); SYSCALL_DECLARE(lseek, int fd, off_t off, int whence); +SYSCALL_DECLARE(writev, unsigned long fd, const struct iovec *vec, unsigned long vlen); +SYSCALL_DECLARE(readv, unsigned long fd, const struct iovec *vec, unsigned long vlen); /* VFS common interface */ diff --git a/so3/kernel/process.c b/so3/kernel/process.c index bc065224a..ff283bc79 100644 --- a/so3/kernel/process.c +++ b/so3/kernel/process.c @@ -925,7 +925,7 @@ SYSCALL_DEFINE1(exit, int, exit_status) * locking in the low layers. */ for (i = 0; i < FD_MAX; i++) - do_close(i); + sys_do_close(i); local_irq_disable(); @@ -944,7 +944,7 @@ SYSCALL_DEFINE1(exit, int, exit_status) #ifdef CONFIG_IPC_SIGNAL /* Send the SIGCHLD signal to the parent */ - do_kill(pcb->parent->pid, SIGCHLD); + sys_do_kill(pcb->parent->pid, SIGCHLD); #endif /* CONFIG_IPC_SIGNAL */ diff --git a/so3/kernel/syscalls.c b/so3/kernel/syscalls.c index 4c61b0b16..68e15083f 100644 --- a/so3/kernel/syscalls.c +++ b/so3/kernel/syscalls.c @@ -60,6 +60,8 @@ static const syscall_fn_t syscall_table[NR_SYSCALLS] = { [SYSCALL_IOCTL] = __sys_ioctl, [SYSCALL_FCNTL] = __sys_fcntl, [SYSCALL_LSEEK] = __sys_lseek, + [SYSCALL_READV] = __sys_readv, + [SYSCALL_WRITEV] = __sys_writev, #ifdef CONFIG_IPC_PIPE [SYSCALL_PIPE] = __sys_pipe, #endif diff --git a/so3/kernel/thread.c b/so3/kernel/thread.c index 868c31835..363ec1520 100644 --- a/so3/kernel/thread.c +++ b/so3/kernel/thread.c @@ -272,7 +272,7 @@ void thread_exit(int *exit_status) remove_tcb_from_pcb(current()); #ifdef CONFIG_PROC_ENV - do_exit(0); + sys_do_exit(0); #endif } else { diff --git a/so3/net/net.c b/so3/net/net.c index 7ca28cb3f..d638f0797 100644 --- a/so3/net/net.c +++ b/so3/net/net.c @@ -413,7 +413,7 @@ SYSCALL_DEFINE3(socket, int, domain, int, type, int, protocol) lwip_fd = lwip_socket(domain, type, protocol); if (lwip_fd < 0) { - do_close(fd); + sys_do_close(fd); return lwip_return(lwip_fd); } @@ -505,7 +505,7 @@ SYSCALL_DEFINE3(accept, int, sockfd, struct sockaddr *, addr, socklen_t *, addrl lwip_bind_fd = lwip_accept(lwip_fd, addr_ptr, addrlen); if (lwip_bind_fd < 0) { - do_close(fd); + sys_do_close(fd); return lwip_return(lwip_bind_fd); }