aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorMarvin Borner2021-02-09 23:57:01 +0100
committerMarvin Borner2021-02-09 23:57:01 +0100
commitedc570a3552a7fdaaf89962e5374d98c2b3dfaa0 (patch)
treef8ad7ec20425b7e3a1d9df07429609e9f608bc19 /kernel
parent58b4e00736c0f2f13a3e96b5fcb3c00623ed35be (diff)
Added basic streams
Diffstat (limited to 'kernel')
-rw-r--r--kernel/features/proc.c55
-rw-r--r--kernel/inc/proc.h12
2 files changed, 64 insertions, 3 deletions
diff --git a/kernel/features/proc.c b/kernel/features/proc.c
index 5c2fab1..0f88e60 100644
--- a/kernel/features/proc.c
+++ b/kernel/features/proc.c
@@ -215,12 +215,11 @@ void proc_wait_for(u32 id, enum proc_wait_type type, s32 (*func)())
struct proc *proc_make(void)
{
struct proc *proc = malloc(sizeof(*proc));
+ memset(proc, 0, sizeof(*proc));
proc->pid = current_pid++;
proc->super = 0;
proc->messages = stack_new();
proc->state = PROC_RUNNING;
- proc->wait.id_cnt = 0;
- proc->wait.func = NULL;
if (current)
list_add(proc_list, proc);
@@ -228,6 +227,9 @@ struct proc *proc_make(void)
return proc;
}
+// TODO: Procfs needs a simpler interface structure (memcmp and everything sucks)
+// TODO: Handle stream overflows
+
const char *procfs_parse_path(const char **path, u32 *pid)
{
while (**path == '/')
@@ -246,6 +248,21 @@ const char *procfs_parse_path(const char **path, u32 *pid)
return *path;
}
+struct stream *procfs_get_stream(const char *path, struct proc *proc)
+{
+ struct stream *stream = NULL;
+ if (!memcmp(path, "in", 3)) {
+ stream = &proc->streams[STREAM_IN];
+ } else if (!memcmp(path, "out", 4)) {
+ stream = &proc->streams[STREAM_IN];
+ } else if (!memcmp(path, "err", 4)) {
+ stream = &proc->streams[STREAM_IN];
+ } else if (!memcmp(path, "log", 4)) {
+ stream = &proc->streams[STREAM_LOG];
+ }
+ return stream;
+}
+
s32 procfs_write(const char *path, void *buf, u32 offset, u32 count, struct device *dev)
{
u32 pid = 0;
@@ -260,6 +277,17 @@ s32 procfs_write(const char *path, void *buf, u32 offset, u32 count, struct devi
stack_push_bot(p->messages, buf); // TODO: Use offset and count
proc_enable_waiting(dev->id, PROC_WAIT_DEV); // TODO: Better wakeup solution
return count;
+ } else if (!memcmp(path, "io/", 3)) {
+ path += 3;
+ struct stream *stream = procfs_get_stream(path, p);
+ if (stream) {
+ memcpy((char *)(stream->data + stream->pos), buf, count);
+ stream->pos += count;
+ proc_enable_waiting(dev->id, PROC_WAIT_DEV);
+ return count;
+ } else {
+ return -1;
+ }
}
}
@@ -299,6 +327,17 @@ s32 procfs_read(const char *path, void *buf, u32 offset, u32 count, struct devic
memcpy(buf, msg + offset, count);
return count;
}
+ } else if (!memcmp(path, "io/", 3)) {
+ path += 3;
+ struct stream *stream = procfs_get_stream(path, p);
+
+ if (stream) {
+ memcpy(buf, stream->data + stream->offset, count);
+ stream->offset += count;
+ return count;
+ } else {
+ return -1;
+ }
}
}
@@ -329,8 +368,18 @@ u8 procfs_ready(const char *path, struct device *dev)
return -1;
path++;
- if (!memcmp(path, "msg", 4))
+ if (!memcmp(path, "msg", 4)) {
return stack_empty(p->messages) == 0;
+ } else if (!memcmp(path, "io/", 3)) {
+ path += 3;
+ struct stream *stream = procfs_get_stream(path, p);
+
+ if (stream) {
+ return stream->data[stream->offset] != 0;
+ } else {
+ return -1;
+ }
+ }
}
return 1;
diff --git a/kernel/inc/proc.h b/kernel/inc/proc.h
index 0007744..9f78a3e 100644
--- a/kernel/inc/proc.h
+++ b/kernel/inc/proc.h
@@ -19,6 +19,11 @@
#define PROC_MAX_WAIT_IDS 16
+#define STREAM_IN 0
+#define STREAM_OUT 1
+#define STREAM_ERR 2
+#define STREAM_LOG 3
+
enum proc_state { PROC_RUNNING, PROC_SLEEPING };
enum proc_wait_type { PROC_WAIT_DEV };
@@ -29,10 +34,17 @@ struct proc_wait {
s32 (*func)();
};
+struct stream {
+ u32 offset;
+ u32 pos;
+ char data[4096];
+};
+
struct proc {
u32 pid;
u8 super;
char name[32];
+ struct stream streams[4];
struct regs regs;
struct proc_wait wait; // dev_id
enum proc_state state;