summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2024-12-14 15:13:01 +0100
committerAnton Kling <anton@kling.gg>2024-12-14 15:13:01 +0100
commit6179308e3f6e4c64013e5db5da9b30a22abca704 (patch)
tree5586ba39441bc86d015a7894400fa854bcc676a4
parentb033314bf1901d436dc71d41d5e1f37dda47e511 (diff)
sb: Allow input to be "ignored"
This removes edge cases from read calls and makes bugs harder to introduce.
-rw-r--r--kernel/fs/procfs.c23
-rw-r--r--kernel/lib/sb.c32
-rw-r--r--kernel/lib/sb.h2
-rw-r--r--userland/libc/crt1.s (renamed from userland/libc/crt0.s)0
4 files changed, 42 insertions, 15 deletions
diff --git a/kernel/fs/procfs.c b/kernel/fs/procfs.c
index 69022d4..bfe3aac 100644
--- a/kernel/fs/procfs.c
+++ b/kernel/fs/procfs.c
@@ -23,8 +23,7 @@ void process_close(vfs_fd_t *fd) {
int procfs_read(u8 *buffer, u64 offset, u64 len, vfs_fd_t *fd) {
struct sb builder;
sb_init_buffer(&builder, buffer, len);
-
- size_t read_amount = 0;
+ sb_set_ignore(&builder, offset);
process_t *p = ready_queue;
for (; p; p = p->next) {
@@ -32,13 +31,11 @@ int procfs_read(u8 *buffer, u64 offset, u64 len, vfs_fd_t *fd) {
entry.d_ino = p->pid;
ksnprintf(entry.d_name, sizeof(entry.d_name), "%u", p->pid);
- if (read_amount >= offset) {
- if (0 == sb_append_buffer(&builder, (u8 *)&entry, sizeof(entry))) {
- break;
- }
+ if (0 == sb_append_buffer(&builder, (u8 *)&entry, sizeof(entry))) {
+ break;
}
- read_amount += sizeof(struct dirent);
}
+
return sv_length(SB_TO_SV(builder));
}
@@ -70,27 +67,23 @@ int process_read(u8 *buffer, u64 offset, u64 len, vfs_fd_t *fd) {
struct sb builder;
sb_init_buffer(&builder, buffer, len);
+ sb_set_ignore(&builder, offset);
int id = fd->inode->inode_num;
if (PROCESS_ROOT == id) {
- size_t read_amount = 0;
for (size_t i = 0; i < ARRAY_LENGTH(process_entries); i++) {
if (0 == strlen(process_entries[i].d_name)) {
continue;
}
- if (read_amount >= offset) {
- if (0 == sb_append_buffer(&builder, (u8 *)&process_entries[i],
- sizeof(struct dirent))) {
- break;
- }
+ if (0 == sb_append_buffer(&builder, (u8 *)&process_entries[i],
+ sizeof(struct dirent))) {
+ break;
}
- read_amount += sizeof(struct dirent);
}
return sv_length(SB_TO_SV(builder));
}
if (PROCESS_NAME == id) {
struct sv program_name = C_TO_SV(p->program_name);
- sv_take(program_name, &program_name, offset);
sb_append_sv(&builder, program_name);
return sv_length(SB_TO_SV(builder));
}
diff --git a/kernel/lib/sb.c b/kernel/lib/sb.c
index 6f716ac..ca302f7 100644
--- a/kernel/lib/sb.c
+++ b/kernel/lib/sb.c
@@ -11,6 +11,7 @@ void sb_init(struct sb *ctx) {
}
int sb_init_capacity(struct sb *ctx, size_t starting_capacity) {
+ ctx->to_ignore = 0;
ctx->length = 0;
ctx->prebuffer = 0;
ctx->string = kmalloc(starting_capacity);
@@ -27,6 +28,7 @@ void sb_init_buffer(struct sb *ctx, char *buffer, size_t size) {
ctx->capacity = size;
ctx->length = 0;
ctx->prebuffer = 1;
+ ctx->to_ignore = 0;
}
void sb_free(struct sb *ctx) {
@@ -40,8 +42,13 @@ void sb_free(struct sb *ctx) {
ctx->string = NULL;
}
+void sb_set_ignore(struct sb *ctx, size_t n) {
+ ctx->to_ignore = n;
+}
+
void sb_reset(struct sb *ctx) {
ctx->length = 0;
+ ctx->to_ignore = 0;
}
int sb_isempty(const struct sb *ctx) {
@@ -64,6 +71,10 @@ int sb_increase_buffer(struct sb *ctx, size_t min) {
}
int sb_append_char(struct sb *ctx, char c) {
+ if (ctx->to_ignore > 0) {
+ ctx->to_ignore--;
+ return 1;
+ }
if (1 > ctx->capacity - ctx->length) {
if (!sb_increase_buffer(ctx, 1)) {
return 0;
@@ -82,6 +93,13 @@ int sb_delete_right(struct sb *ctx, size_t n) {
int sb_append(struct sb *ctx, const char *s) {
size_t l = strlen(s);
+ if (ctx->to_ignore >= l) {
+ ctx->to_ignore -= l;
+ return 1;
+ }
+ l -= ctx->to_ignore;
+ s += ctx->to_ignore;
+ ctx->to_ignore = 0;
if (l > ctx->capacity - ctx->length) {
if (!sb_increase_buffer(ctx, l)) {
return 0;
@@ -97,6 +115,13 @@ int sb_prepend_sv(struct sb *ctx, struct sv sv) {
}
int sb_prepend_buffer(struct sb *ctx, const char *buffer, size_t length) {
+ if (ctx->to_ignore >= length) {
+ ctx->to_ignore -= length;
+ return 1;
+ }
+ length -= ctx->to_ignore;
+ buffer += ctx->to_ignore;
+ ctx->to_ignore = 0;
if (length > ctx->capacity - ctx->length) {
if (!sb_increase_buffer(ctx, length)) {
return 0;
@@ -109,6 +134,13 @@ int sb_prepend_buffer(struct sb *ctx, const char *buffer, size_t length) {
}
int sb_append_buffer(struct sb *ctx, const char *buffer, size_t length) {
+ if (ctx->to_ignore >= length) {
+ ctx->to_ignore -= length;
+ return 1;
+ }
+ length -= ctx->to_ignore;
+ buffer += ctx->to_ignore;
+ ctx->to_ignore = 0;
if (length > ctx->capacity - ctx->length) {
if (!sb_increase_buffer(ctx, length)) {
return 0;
diff --git a/kernel/lib/sb.h b/kernel/lib/sb.h
index 7832015..4d910e3 100644
--- a/kernel/lib/sb.h
+++ b/kernel/lib/sb.h
@@ -8,12 +8,14 @@ struct sb {
char *string;
size_t length;
size_t capacity;
+ size_t to_ignore;
uint8_t prebuffer;
};
struct sv;
void sb_init(struct sb *ctx);
+void sb_set_ignore(struct sb *ctx, size_t n);
int sb_init_capacity(struct sb *ctx, size_t starting_capacity);
void sb_init_buffer(struct sb *ctx, char *buffer, size_t size);
void sb_free(struct sb *ctx);
diff --git a/userland/libc/crt0.s b/userland/libc/crt1.s
index c950949..c950949 100644
--- a/userland/libc/crt0.s
+++ b/userland/libc/crt1.s