commit ace583b69a3b05ca805707befbc795a4db603773 from: int16h date: Thu Dec 4 23:18:35 2025 UTC Fix: added per-task stdin spill buffer so partial reads pull from saved input instead of requeueing leftover bytes back into the mailbox - prevents dropped chars when mailbox is under pressure; introduced scheduler helpers to manage spill buffer and clear it on task takedown, keeping stdin attached to owning task commit - 0b2bb3ee51023cbb01c53c7358550324c16c5d21 commit + ace583b69a3b05ca805707befbc795a4db603773 blob - 93b811dc2513ec261aa295210a7eb5167edf7e17 blob + 110f5b299de9fb14e191a84e2644ef652084048f --- kernel/include/sched/task.h +++ kernel/include/sched/task.h @@ -148,6 +148,11 @@ enum sched_task_state { enum sched_task_state sched_task_get_state(const struct sched_task *); ipc_portal_handle_t sched_task_stdio_portal(const struct sched_task *); void sched_task_set_stdio_portal(struct sched_task *, ipc_portal_handle_t); +const uint8_t *sched_task_stdin_spill(const struct sched_task *, size_t *); +void sched_task_stdin_spill_consume(struct sched_task *, size_t); +int sched_task_stdin_spill_save(struct sched_task *, const uint8_t *, + size_t); +void sched_task_stdin_spill_clear(struct sched_task *); void *sched_task_sys_private(const struct sched_task *); void sched_task_sys_private_set(struct sched_task *, void *, void (*)(void *)); blob - e54e7b1630be5ae6733b3f5c617b303662168be7 blob + e6901397160b25456a90ad6fb7921363705ae7ea --- kernel/kmain.c +++ kernel/kmain.c @@ -224,14 +224,6 @@ kmain_post_mm(void) rc = user_namesvc_server_launch(); boot_log_result("namesvc", rc == 0); } - // printk("* About to prepare pci-daemon\n"); - // if (user_pci_server_prepare() != 0) { - // printk("* pci-daemon: failed to prepare PCI service\n"); - // } else { - // printk("* pci-daemon: prepare succeeded, launching...\n"); - // if (user_pci_server_launch() != 0) - // printk("* pci-daemon: failed to launch PCI service\n"); - // } /* Launch block daemon (blockd) first, before backend drivers. * Backend drivers (ramdiskd, virtio-blk) need blockd to be available @@ -255,23 +247,23 @@ kmain_post_mm(void) boot_log_result("ramdiskd", rc == 0); } - rc = user_pci_server_prepare(); - #ifdef LENIX_DEBUG - boot_log_result("Preparing pci-daemon...", rc == 0); - #endif - if (rc == 0) { - rc = user_pci_server_launch(); - boot_log_result("pci-server", rc == 0); - } + // rc = user_pci_server_prepare(); + // #ifdef LENIX_DEBUG + // boot_log_result("Preparing pci-daemon...", rc == 0); + // #endif + // if (rc == 0) { + // rc = user_pci_server_launch(); + // boot_log_result("pci-server", rc == 0); + // } - rc = user_virtio_blk_server_prepare(); - #ifdef LENIX_DEBUG - boot_log_result("Preparing virtio-blk driver...", rc == 0); - #endif - if (rc == 0) { - rc = user_virtio_blk_server_launch(); - boot_log_result("virtio-blk driver", rc == 0); - } + // rc = user_virtio_blk_server_prepare(); + // #ifdef LENIX_DEBUG + // boot_log_result("Preparing virtio-blk driver...", rc == 0); + // #endif + // if (rc == 0) { + // rc = user_virtio_blk_server_launch(); + // boot_log_result("virtio-blk driver", rc == 0); + // } rc = user_fs_server_prepare(); #ifdef LENIX_DEBUG @@ -300,32 +292,32 @@ kmain_post_mm(void) boot_log_result("vfs", rc == 0); } - rc = user_netd_server_prepare(); - #ifdef LENIX_DEBUG - boot_log_result("Preparing netd...", rc == 0); - #endif - if (rc == 0) { - rc = user_netd_server_launch(); - boot_log_result("netd", rc == 0); - } + // rc = user_netd_server_prepare(); + // #ifdef LENIX_DEBUG + // boot_log_result("Preparing netd...", rc == 0); + // #endif + // if (rc == 0) { + // rc = user_netd_server_launch(); + // boot_log_result("netd", rc == 0); + // } - rc = user_sock_udp_server_prepare(); - #ifdef LENIX_DEBUG - boot_log_result("Preparing sock.udp...", rc == 0); - #endif - if (rc == 0) { - rc = user_sock_udp_server_launch(); - boot_log_result("sock.udp", rc == 0); - } + // rc = user_sock_udp_server_prepare(); + // #ifdef LENIX_DEBUG + // boot_log_result("Preparing sock.udp...", rc == 0); + // #endif + // if (rc == 0) { + // rc = user_sock_udp_server_launch(); + // boot_log_result("sock.udp", rc == 0); + // } - rc = user_sock_tcp_server_prepare(); - #ifdef LENIX_DEBUG - boot_log_result("Preparing sock.tcp...", rc == 0); - #endif - if (rc == 0) { - rc = user_sock_tcp_server_launch(); - boot_log_result("sock.tcp", rc == 0); - } + // rc = user_sock_tcp_server_prepare(); + // #ifdef LENIX_DEBUG + // boot_log_result("Preparing sock.tcp...", rc == 0); + // #endif + // if (rc == 0) { + // rc = user_sock_tcp_server_launch(); + // boot_log_result("sock.tcp", rc == 0); + // } rc = user_tty_server_prepare(); #ifdef LENIX_DEBUG blob - ec9ca0551e543f1cd9bfc30c54a55ec0dd74b4e1 blob + c70f34d454452e243e82515ff0ab386f67fb9db5 --- kernel/sched/task.c +++ kernel/sched/task.c @@ -92,6 +92,9 @@ struct sched_task { bool bootstrap_ready; ipc_portal_handle_t stdio_portal; bool stdio_portal_ready; + uint8_t *stdin_spill; + size_t stdin_spill_len; + size_t stdin_spill_off; struct signal_state signals; bool exit_status_set; int exit_status; @@ -1820,6 +1823,7 @@ sched_exit_current(void) task->sys_private_dtor(task->sys_private); task->sys_private = NULL; task->sys_private_dtor = NULL; + sched_task_stdin_spill_clear(task); if (task->stdio_portal_ready) { #ifdef LENIX_DEBUG_EXIT @@ -2497,6 +2501,71 @@ sched_task_set_stdio_portal(struct sched_task *task, (handle != IPC_PORTAL_INVALID_HANDLE); } +const uint8_t * +sched_task_stdin_spill(const struct sched_task *task, size_t *len_out) +{ + size_t len = 0; + + if (task != NULL && task->stdin_spill != NULL && + task->stdin_spill_off < task->stdin_spill_len) + len = task->stdin_spill_len - task->stdin_spill_off; + if (len_out != NULL) + *len_out = len; + if (len == 0) + return NULL; + return task->stdin_spill + task->stdin_spill_off; +} + +void +sched_task_stdin_spill_consume(struct sched_task *task, size_t bytes) +{ + if (task == NULL || task->stdin_spill == NULL) + return; + if (task->stdin_spill_off >= task->stdin_spill_len) + return; + if (bytes > task->stdin_spill_len - task->stdin_spill_off) + bytes = task->stdin_spill_len - task->stdin_spill_off; + task->stdin_spill_off += bytes; + if (task->stdin_spill_off >= task->stdin_spill_len) { + kmem_free(task->stdin_spill); + task->stdin_spill = NULL; + task->stdin_spill_len = 0; + task->stdin_spill_off = 0; + } +} + +int +sched_task_stdin_spill_save(struct sched_task *task, const uint8_t *data, + size_t len) +{ + uint8_t *buf; + + if (task == NULL || data == NULL || len == 0) + return -1; + buf = kmem_alloc(len); + if (buf == NULL) + return -1; + for (size_t i = 0; i < len; i++) + buf[i] = data[i]; + if (task->stdin_spill != NULL) + kmem_free(task->stdin_spill); + task->stdin_spill = buf; + task->stdin_spill_len = len; + task->stdin_spill_off = 0; + return 0; +} + +void +sched_task_stdin_spill_clear(struct sched_task *task) +{ + if (task == NULL || task->stdin_spill == NULL) + return; + kmem_free(task->stdin_spill); + task->stdin_spill = NULL; + task->stdin_spill_len = 0; + task->stdin_spill_off = 0; +} + void * sched_task_sys_private(const struct sched_task *task) { blob - b5178db6a14be3b563df9512d35cdc9fc32dec17 blob + 693388275d6526807f6a750396ed81a993f8182e --- kernel/sys/syscall.c +++ kernel/sys/syscall.c @@ -1350,7 +1350,20 @@ sys_read_impl(uint64_t fd, uint64_t buf_addr, uint64_t struct sched_task *task = sched_current_task(); struct ipc_mailbox *mbox = sched_task_mailbox(NULL); struct ipc_message *msg; + const uint8_t *spill; + size_t spill_len = 0; + spill = sched_task_stdin_spill(task, &spill_len); + if (spill_len > 0) { + copied = spill_len; + if (copied > n) + copied = n; + if (syscall_copy_to_user(buf_addr, spill, copied) != 0) + return syscall_make_result(-SYSCALL_EFAULT, 0); + sched_task_stdin_spill_consume(task, copied); + return syscall_make_result(copied, 0); + } + if (mbox == NULL) return syscall_make_result(-SYSCALL_EBADF, 0); deadlock_recv_start(task, 5000); @@ -1374,7 +1387,12 @@ sys_read_impl(uint64_t fd, uint64_t buf_addr, uint64_t if (msg->payload_len > copied) { size_t remaining = msg->payload_len - copied; const uint8_t *payload_bytes = (const uint8_t *)payload; - ipc_mailbox_send(mbox, payload_bytes + copied, remaining); + + if (sched_task_stdin_spill_save(task, + payload_bytes + copied, remaining) != 0) { + (void)ipc_mailbox_send(mbox, + payload_bytes + copied, remaining); + } } ipc_mailbox_free(msg); return syscall_make_result(copied, 0);