Commit Diff


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);