From 1a10a3725e7bea67e558715f6e9f78abcb415b3a Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Wed, 30 Apr 2025 21:07:46 -0400 Subject: finish syscall impls --- user/include/stdio.h | 6 ++-- user/include/sys/types.h | 15 ++++++++++ user/include/unistd.h | 16 +++++------ user/init.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++ user/lib/entry.S | 5 ++-- user/lib/fclose.c | 10 +++++++ user/lib/fseek.c | 16 +++++++++++ user/lib/syscall.S | 3 ++ 8 files changed, 131 insertions(+), 15 deletions(-) create mode 100644 user/include/sys/types.h create mode 100644 user/init.c create mode 100644 user/lib/fclose.c create mode 100644 user/lib/fseek.c (limited to 'user') diff --git a/user/include/stdio.h b/user/include/stdio.h index fe29c9d..bb57c6d 100644 --- a/user/include/stdio.h +++ b/user/include/stdio.h @@ -252,7 +252,7 @@ extern size_t fwrite(const void *restrict ptr, size_t size, size_t n, * @param stream - the stream to seek * @param off - the offset from whence * @param whence - where to seek from (SEEK_SET, SEEK_CUR, SEEK_END) - * @returns 0 on success, -1 on error setting errno + * @returns new offset on success, -1 on error */ extern int fseek(FILE *stream, long int off, int whence); @@ -260,9 +260,9 @@ extern int fseek(FILE *stream, long int off, int whence); * return the current position of stream * * @param stream - the stream to tell - * @return the position on success, -1 on error setting errno + * @returns new offset on success, -1 on error */ -extern long int ftell(FILE *stream); +extern long ftell(FILE *stream); /** * rewing to the begining of a stream diff --git a/user/include/sys/types.h b/user/include/sys/types.h new file mode 100644 index 0000000..f1b3266 --- /dev/null +++ b/user/include/sys/types.h @@ -0,0 +1,15 @@ +/** + * @file types.h + * + * @author Freya Murphy + * + * System types + */ + +#ifndef _TYPES_H +#define _TYPES_H + +typedef long int off_t; +typedef unsigned short pid_t; + +#endif /* types.h */ diff --git a/user/include/unistd.h b/user/include/unistd.h index cad3a81..4f582d2 100644 --- a/user/include/unistd.h +++ b/user/include/unistd.h @@ -11,11 +11,10 @@ #include #include +#include /* System Call Definitions */ -typedef unsigned short pid_t; - enum { S_SET = 0, S_CUR = 1, @@ -27,7 +26,7 @@ enum { O_RDONLY = 0x02, O_WRONLY = 0x04, O_APPEND = 0x08, - O_RDWR = O_RDONLY | O_WRONLY, + O_RDWR = 0x010, }; /** @@ -67,11 +66,9 @@ extern int fork(void); * * @param prog - program table index of the program to exec * @param args - the command-line argument vector - * - * Does not return if it succeeds; if it returns, something has - * gone wrong. + * @returns error code on failure */ -extern void exec(const char *filename, char **args); +extern int exec(const char *filename, const char **args); /** * open a stream with a given filename @@ -85,8 +82,9 @@ extern int open(const char *filename, int flags); * closes a stream with the given file descriptior * * @param fd - the file descriptior of the open stream + * @returns 0 on success, error code on invalid fd */ -extern void close(int fd); +extern int close(int fd); /** * read into a buffer from a stream @@ -116,7 +114,7 @@ extern int write(int fd, const void *buffer, size_t nbytes); * @param whence - whence to seek * @return 0 on success, or an error code */ -extern int seek(int fd, long int off, int whence); +extern off_t seek(int fd, off_t off, int whence); /** * gets the pid of the calling process diff --git a/user/init.c b/user/init.c new file mode 100644 index 0000000..18e70a2 --- /dev/null +++ b/user/init.c @@ -0,0 +1,75 @@ +#include +#include + +#define MAX_ARGS 4 + +struct proc { + pid_t pid; + const char *filename; + const char *args[MAX_ARGS]; +}; + +static struct proc spawn_table[] = { + // apple + { 0, "bin/apple", { NULL } }, + // end, + { 0, NULL, { NULL } }, +}; + +static int spawn(const char *filename, const char **args) +{ + int ret; + + // fork init + if ((ret = fork()) != 0) + return ret; + + // call exec + if ((ret = exec(filename, args))) + exit(ret); + + // should not happen! + exit(1); +} + +int main(void) +{ + struct proc *proc; + + // spawn our processes + for (proc = spawn_table; proc->filename != NULL; proc++) { + int pid; + pid = spawn(proc->filename, proc->args); + if (pid < 0) + fprintf(stderr, "init: cannot exec '%s': %d\n", proc->filename, + pid); + proc->pid = pid; + } + + // clean up dead on restart ours + while (1) { + int pid, status; + + pid = waitpid(0, &status); + if (pid < 0) + continue; + + printf("init: pid %d exited with %d\n", pid, status); + + // figure out if this is one of ours + for (proc = spawn_table; proc->filename != NULL; proc++) { + if (proc->pid == pid) { + proc->pid = 0; + pid = spawn(proc->filename, proc->args); + if (pid < 0) + fprintf(stderr, "init: cannot exec '%s': %d\n", + proc->filename, pid); + proc->pid = pid; + break; + } + } + } + + // very very bad! + return 1; +} diff --git a/user/lib/entry.S b/user/lib/entry.S index 40570b5..efaa652 100644 --- a/user/lib/entry.S +++ b/user/lib/entry.S @@ -5,7 +5,6 @@ .section .text .code64 _start: - call main - subq $16, %rsp # ??? - pushq %rax + call main + movq %rax, %rdi call exit diff --git a/user/lib/fclose.c b/user/lib/fclose.c new file mode 100644 index 0000000..be31421 --- /dev/null +++ b/user/lib/fclose.c @@ -0,0 +1,10 @@ +#include +#include + +void fclose(FILE *stream) +{ + int fd; + + fd = (uintptr_t)stream; + close(fd); +} diff --git a/user/lib/fseek.c b/user/lib/fseek.c new file mode 100644 index 0000000..a7a3377 --- /dev/null +++ b/user/lib/fseek.c @@ -0,0 +1,16 @@ +#include +#include + +int fseek(FILE *stream, long off, int whence) +{ + int fd; + fd = (uintptr_t)stream; + return seek(fd, off, whence); +} + +long ftell(FILE *stream) +{ + int fd; + fd = (uintptr_t)stream; + return seek(fd, 0, SEEK_CUR); +} diff --git a/user/lib/syscall.S b/user/lib/syscall.S index 2ba4dc0..9f7025e 100644 --- a/user/lib/syscall.S +++ b/user/lib/syscall.S @@ -13,6 +13,8 @@ SYSCALL exit SYS_exit SYSCALL waitpid SYS_waitpid SYSCALL fork SYS_fork SYSCALL exec SYS_exec +SYSCALL open SYS_open +SYSCALL close SYS_close SYSCALL read SYS_read SYSCALL write SYS_write SYSCALL getpid SYS_getpid @@ -27,3 +29,4 @@ SYSCALL sbrk SYS_sbrk SYSCALL poweroff SYS_poweroff SYSCALL drm SYS_drm SYSCALL ticks SYS_ticks +SYSCALL seek SYS_seek -- cgit v1.2.3-freya From 5aee4fa6661fdf76fe8fa47f842468cfca46a860 Mon Sep 17 00:00:00 2001 From: Freya Murphy Date: Tue, 6 May 2025 12:36:47 -0400 Subject: init improvements --- user/init.c | 84 +++++++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 62 insertions(+), 22 deletions(-) (limited to 'user') diff --git a/user/init.c b/user/init.c index 18e70a2..51d8f92 100644 --- a/user/init.c +++ b/user/init.c @@ -3,6 +3,8 @@ #define MAX_ARGS 4 +static long running = 0; + struct proc { pid_t pid; const char *filename; @@ -32,44 +34,82 @@ static int spawn(const char *filename, const char **args) exit(1); } -int main(void) +static void spawn_proc(struct proc *proc) +{ + int ret; + + // update running on respawn + if (proc->pid) + running--; + + // attempt to fork / exec + ret = spawn(proc->filename, proc->args); + + // handle result + if (ret < 0) { + printf("init: cannot exec '%s': %d\n", proc->filename, ret); + proc->pid = 0; + } else { + running++; + proc->pid = ret; + } +} + +static void spawn_proc_loop(struct proc *proc) +{ + while (proc->pid == 0) + spawn_proc(proc); +} + +static void spawn_all(void) { struct proc *proc; + for (proc = spawn_table; proc->filename != NULL; proc++) { + spawn_proc_loop(proc); + } +} - // spawn our processes +static struct proc *get_proc(pid_t pid) +{ + struct proc *proc; for (proc = spawn_table; proc->filename != NULL; proc++) { - int pid; - pid = spawn(proc->filename, proc->args); - if (pid < 0) - fprintf(stderr, "init: cannot exec '%s': %d\n", proc->filename, - pid); - proc->pid = pid; + if (proc->pid == pid) + return proc; } + return NULL; +} + +int main(void) +{ + // spawn our processes + spawn_all(); // clean up dead on restart ours while (1) { + struct proc *proc; int pid, status; - pid = waitpid(0, &status); - if (pid < 0) + // dont wait if nothing running + if (running) { + pid = waitpid(0, &status); + // ??? + if (pid < 0) + continue; + } else { + spawn_all(); continue; + } printf("init: pid %d exited with %d\n", pid, status); // figure out if this is one of ours - for (proc = spawn_table; proc->filename != NULL; proc++) { - if (proc->pid == pid) { - proc->pid = 0; - pid = spawn(proc->filename, proc->args); - if (pid < 0) - fprintf(stderr, "init: cannot exec '%s': %d\n", - proc->filename, pid); - proc->pid = pid; - break; - } - } + proc = get_proc(pid); + if (proc == NULL) + continue; + + spawn_proc_loop(proc); } - // very very bad! + // failed to launch anythingvery very bad! return 1; } -- cgit v1.2.3-freya