kfree(p);
}
+static void process_close_all_files_locked(struct process* p) {
+ if (!p) return;
+ for (int fd = 0; fd < PROCESS_MAX_FILES; fd++) {
+ struct file* f = p->files[fd];
+ if (!f) continue;
+ p->files[fd] = NULL;
+
+ if (f->refcount > 0) {
+ f->refcount--;
+ }
+ if (f->refcount == 0) {
+ if (f->node) {
+ vfs_close(f->node);
+ }
+ kfree(f);
+ }
+ }
+}
+
+int process_kill(uint32_t pid, int sig) {
+ // Minimal: support SIGKILL only.
+ const int SIG_KILL = 9;
+ if (pid == 0) return -EINVAL;
+ if (sig != SIG_KILL) return -EINVAL;
+
+ // Killing self: just exit via existing path.
+ if (current_process && current_process->pid == pid) {
+ process_exit_notify(128 + sig);
+ hal_cpu_enable_interrupts();
+ schedule();
+ for (;;) hal_cpu_idle();
+ }
+
+ uintptr_t flags = spin_lock_irqsave(&sched_lock);
+ struct process* p = process_find_locked(pid);
+ if (!p || p->pid == 0) {
+ spin_unlock_irqrestore(&sched_lock, flags);
+ return -ESRCH;
+ }
+
+ if (p->state == PROCESS_ZOMBIE) {
+ spin_unlock_irqrestore(&sched_lock, flags);
+ return 0;
+ }
+
+ process_close_all_files_locked(p);
+ p->exit_status = 128 + sig;
+ p->state = PROCESS_ZOMBIE;
+
+ if (p->pid != 0) {
+ struct process* parent = process_find_locked(p->parent_pid);
+ if (parent && parent->state == PROCESS_BLOCKED && parent->waiting) {
+ if (parent->wait_pid == -1 || parent->wait_pid == (int)p->pid) {
+ parent->wait_result_pid = (int)p->pid;
+ parent->wait_result_status = p->exit_status;
+ parent->state = PROCESS_READY;
+ }
+ }
+ }
+
+ spin_unlock_irqrestore(&sched_lock, flags);
+ return 0;
+}
+
int process_waitpid(int pid, int* status_out, uint32_t options) {
if (!current_process) return -ECHILD;
// Find next READY process
struct process* get_next_ready_process(void) {
+ if (!current_process) return NULL;
+ if (!current_process->next) return current_process;
+
struct process* iterator = current_process->next;
-
- // Safety Break to prevent infinite loop if list broken
- int count = 0;
- while (iterator != current_process && count < 100) {
+
+ // Scan the full circular list for a READY process.
+ while (iterator && iterator != current_process) {
if (iterator->state == PROCESS_READY) {
return iterator;
}
iterator = iterator->next;
- count++;
}
// If current is ready/running, return it.
// Assuming PID 0 is always in the list.
// Search specifically for PID 0
iterator = current_process->next;
- while (iterator->pid != 0) {
+ while (iterator && iterator->pid != 0) {
iterator = iterator->next;
if (iterator == current_process) break; // Should not happen
}
- return iterator; // Return idle task
+ return iterator ? iterator : current_process;
}
void schedule(void) {
SYSCALL_FORK = 16,
SYSCALL_GETPPID = 17,
SYSCALL_POLL = 18,
+ SYSCALL_KILL = 19,
};
struct pollfd {
POLLOUT = 0x0004,
};
+enum {
+ SIGKILL = 9,
+};
+
enum {
WNOHANG = 1,
};
return ret;
}
+static int sys_kill(int pid, int sig) {
+ int ret;
+ __asm__ volatile(
+ "int $0x80"
+ : "=a"(ret)
+ : "a"(SYSCALL_KILL), "b"(pid), "c"(sig)
+ : "memory"
+ );
+ return ret;
+}
+
static int sys_poll(struct pollfd* fds, uint32_t nfds, int32_t timeout) {
int ret;
__asm__ volatile(
(uint32_t)(sizeof("[init] pipe dup2 read failed\n") - 1));
sys_exit(1);
}
+ sys_write(1, "[init] pipe OK\n", (uint32_t)(sizeof("[init] pipe OK\n") - 1));
- (void)sys_close(1);
(void)sys_close(pfds[0]);
(void)sys_close(pfds[1]);
- sys_write(1, "[init] pipe OK\n", (uint32_t)(sizeof("[init] pipe OK\n") - 1));
+ int tfd = sys_open("/dev/tty", 0);
+ if (tfd < 0) {
+ sys_write(1, "[init] /dev/tty open failed\n",
+ (uint32_t)(sizeof("[init] /dev/tty open failed\n") - 1));
+ sys_exit(1);
+ }
+ if (sys_dup2(tfd, 1) != 1) {
+ sys_write(1, "[init] dup2 restore tty failed\n",
+ (uint32_t)(sizeof("[init] dup2 restore tty failed\n") - 1));
+ sys_exit(1);
+ }
+ (void)sys_close(tfd);
+
+ {
+ int pid = sys_fork();
+ if (pid < 0) {
+ sys_write(1, "[init] kill test fork failed\n",
+ (uint32_t)(sizeof("[init] kill test fork failed\n") - 1));
+ sys_exit(1);
+ }
+
+ if (pid == 0) {
+ for (;;) {
+ __asm__ volatile("nop");
+ }
+ }
+
+ if (sys_kill(pid, SIGKILL) < 0) {
+ sys_write(1, "[init] kill(SIGKILL) failed\n",
+ (uint32_t)(sizeof("[init] kill(SIGKILL) failed\n") - 1));
+ sys_exit(1);
+ }
+
+ int st = 0;
+ int rp = sys_waitpid(pid, &st, 0);
+ if (rp != pid || st != (128 + SIGKILL)) {
+ sys_write(1, "[init] kill test waitpid mismatch\n",
+ (uint32_t)(sizeof("[init] kill test waitpid mismatch\n") - 1));
+ sys_exit(1);
+ }
+
+ sys_write(1, "[init] kill(SIGKILL) OK\n",
+ (uint32_t)(sizeof("[init] kill(SIGKILL) OK\n") - 1));
+ }
{
int fds[2];