Tue, 25 Apr 2023 19:50:35 +0200
9 files changed,
115 insertions(+),
9 deletions(-)
A
include/cedos/pipe.h
@@ -0,0 +1,11 @@
+#ifndef PIPE_H +#define PIPE_H + +#include "cedos/file.h" + +int pipe_read(int fd, char *buffer, uint32_t size); +int pipe_write(int fd, char *buffer, uint32_t size); + +extern file_operations_t pipe_fops; + +#endif
M
include/cedos/sched/process.h
→
include/cedos/sched/process.h
@@ -67,6 +67,12 @@
//! String of arguments for the process char *args; + //! process stdin + int stdin; + + //! process stdout + int stdout; + /* * String buffers for name and args * TODO: eventually move to a malloc solution
M
include/cedos/sched/sched.h
→
include/cedos/sched/sched.h
@@ -32,7 +32,7 @@
/*! * Spawns a new process, loads it from the given ELF file, and returns its process ID. */ -PROCESS_ID sched_spawn(const char *name, char *args); +PROCESS_ID sched_spawn(const char *name, char *args, int flags); /*! * Return the ID of the current process.
M
src/kernel/file.c
→
src/kernel/file.c
@@ -1,8 +1,12 @@
#include "cedos/file.h" #include "cedos/fat.h" +#include "cedos/pipe.h" #include "cedos/drivers/tty.h" #include "cedos/core.h" + +#include "cedos/sched/sched.h" +#include "cedos/sched/process.h" #ifdef DEBUG #define PRINT_DBG(...) printk("[" __FILE__ "] " __VA_ARGS__)@@ -15,7 +19,7 @@
file_t file_table[256]; int next_free = 0; -int stdin, stdout, fat_root; +int stdin, stdout, fat_root, pipe; int file_init() { file_table[next_free].fops = &tty_fops;@@ -34,6 +38,10 @@ file_table[next_free].stdio_id = 0;
file_table[next_free].fat_cluster = 0; fat_root = next_free++; + // pipe + file_table[next_free].fops = &pipe_fops; + pipe = next_free++; + return 0; }@@ -45,13 +53,26 @@
return file_openat(fat_root, pathname, flags); } +file_t *get_process_local_file(int fd) { + if (fd > 1) { return &file_table[fd]; } + + PROCESS_ID pid = get_current_process(); + PRINT_DBG("pid: %i\n", pid); + PROCESS *p = get_process(pid); + + if (fd == 0) { return &file_table[p->stdin]; } + if (fd == 1) { return &file_table[p->stdout]; } + + return NULL; +} + int file_openat(int fd, const char *fname, int flags) { int new_fd = next_free++; PRINT_DBG("Given fd: %i\n", fd); PRINT_DBG("New fd: %i\n", new_fd); - file_t *root = &file_table[fd]; + file_t *root = get_process_local_file(fd); file_t *handle = &file_table[new_fd]; if (root->fops->openat == NULL) { return -1; }@@ -62,7 +83,7 @@ return new_fd;
} int file_read(int fd, char *buffer, uint32_t size) { - file_t *file = &file_table[fd]; + file_t *file = get_process_local_file(fd); if (file->fops->read == NULL) { return -1; }@@ -70,7 +91,7 @@ file->fops->read(file, buffer, size);
} int file_write(int fd, char *buffer, uint32_t size) { - file_t *file = &file_table[fd]; + file_t *file = get_process_local_file(fd); if (file->fops->write == NULL) { return -1; }@@ -78,7 +99,7 @@ file->fops->write(file, buffer, size);
} int file_dir_next(int fd, int index, char *fname_buffer) { - file_t *file = &file_table[fd]; + file_t *file = get_process_local_file(fd); if (file->fops->dir_next == NULL) { return -1; }
M
src/kernel/main.c
→
src/kernel/main.c
@@ -128,7 +128,7 @@ // create test tasks
printk("Creating tasks.\n"); - int pid = sched_spawn("shelf", "Hello World!"); + int pid = sched_spawn("shelf", "Hello World!", 0); assert(pid != -1); //sched_spawn("fibonacci.o", "Hello World!"); //sched_spawn("fibonacci.o", "Hello World!");
A
src/kernel/pipe.c
@@ -0,0 +1,49 @@
+#include "cedos/file.h" +#include "cedos/pipe.h" +#include "cedos/sched/sched.h" + +file_operations_t pipe_fops = { + NULL, /* open */ + NULL, /* openat */ + pipe_read, /* read */ + pipe_write, /* write */ + NULL /* dir_next */ +}; + +#define PIPE_BUFFER_SIZE 512 + +uint8_t pipe_buffer[PIPE_BUFFER_SIZE]; +int read_head = 0; +int write_head = 0; + +uint8_t pipe_readc() { + while (write_head == read_head) { + sched_yield(); + } + + int rh_next = (read_head + 1) % PIPE_BUFFER_SIZE; + uint8_t res = pipe_buffer[read_head]; + read_head = rh_next; + return res; +} + +void pipe_writec(uint8_t c) { + int wh_next = (write_head + 1) % PIPE_BUFFER_SIZE; + while (wh_next == read_head) { + sched_yield(); + } + pipe_buffer[write_head] = c; + write_head = wh_next; +} + +int pipe_read(int fd, char *buffer, uint32_t size) { + for (int i = 0; i < size; i++) { + buffer[i] = pipe_readc(); + } +} + +int pipe_write(int fd, char *buffer, uint32_t size) { + for (int i = 0; i < size; i++) { + pipe_writec(buffer[i]); + } +}
M
src/kernel/sched/sched.c
→
src/kernel/sched/sched.c
@@ -52,8 +52,12 @@
/*! * Spawn a new process and returns its process ID. */ -PROCESS_ID sched_spawn(const char *name, char *args) { +PROCESS_ID sched_spawn(const char *name, char *args, int flags) { crit_enter(); + + PRINT_DBG("process name: %s\n", name); + PRINT_DBG("process args: %s\n", args); + PRINT_DBG("process flags: %i\n", flags); if (name != NULL) { int fd = file_open(name, 0);@@ -70,6 +74,14 @@ p->ebp = USER_STACK;
p->esp = USER_STACK - sizeof(SCHED_FRAME); p->eflags = PROCESS_STD_EFLAGS; p->entry = (PROCESS_MAIN*)(0xDEADBEEF); + + if (flags != 0) { + p->stdin = (int)(flags & 0xFF); + p->stdout = (int)(flags >> 8); + } else { + p->stdin = 0; + p->stdout = 1; + } // TODO: implement with malloc strcpy(p->name_buf, name);@@ -185,7 +197,7 @@
current_pid = 0; // create idle process - PROCESS_ID idle = sched_spawn(NULL, NULL); + PROCESS_ID idle = sched_spawn(NULL, NULL, 0); assert(idle != -1); return 1;
M
src/libcedos/cedos.c
→
src/libcedos/cedos.c
@@ -38,6 +38,12 @@ interrupt(0x30, res, 4, fname, args, 0);
return res; } +int process_spawn_pipe(const char *fname, const char *args, int stdin, int stdout) { + volatile uint32_t res = 0; + interrupt(0x30, res, 4, fname, args, stdin | (stdout << 8)); + return res; +} + void process_wait(int pid) { volatile uint32_t res = 0; interrupt(0x30, res, 5, pid, 0, 0);
M
src/libcedos/include/cedos.h
→
src/libcedos/include/cedos.h
@@ -9,6 +9,7 @@ int sysprint(const char *fmt, int arg1, int arg2);
int yield(); int get_pid(); int process_spawn(const char *fname, const char *args); +int process_spawn_pipe(const char *fname, const char *args, int stdin, int stdout); void process_wait(int pid); void graphics_set_mode(int mode);