diff options
author | Anton Kling <anton@kling.gg> | 2024-12-14 15:13:01 +0100 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2024-12-14 15:13:01 +0100 |
commit | 6179308e3f6e4c64013e5db5da9b30a22abca704 (patch) | |
tree | 5586ba39441bc86d015a7894400fa854bcc676a4 | |
parent | b033314bf1901d436dc71d41d5e1f37dda47e511 (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.c | 23 | ||||
-rw-r--r-- | kernel/lib/sb.c | 32 | ||||
-rw-r--r-- | kernel/lib/sb.h | 2 | ||||
-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 |