return NULL;
}
+static int process_is_current_somewhere(struct process* p) {
+ if (!p) return 0;
+#ifdef __i386__
+ uint32_t cpu = p->cpu_id < SCHED_MAX_CPUS ? p->cpu_id : 0;
+ struct percpu_data* pcpu = percpu_get_ptr(cpu);
+ return pcpu && *(struct process**)((uint8_t*)pcpu + 12) == p;
+#else
+ return current_process == p;
+#endif
+}
+
static void process_reap_locked(struct process* p) {
if (!p) return;
if (p->pid == 0) return;
struct process* it = ready_queue_head;
struct process* start = it;
int found_child = 0;
+ int retry_reap = 0;
if (it) {
do {
found_child = 1;
if (pid == -1 || (int)it->pid == pid) {
if (it->state == PROCESS_ZOMBIE) {
+ if (process_is_current_somewhere(it)) {
+ retry_reap = 1;
+ break;
+ }
int retpid = (int)it->pid;
int st = it->exit_status;
process_reap_locked(it);
} while (it && it != start);
}
+ if (retry_reap) {
+ spin_unlock_irqrestore(&sched_lock, flags);
+ if ((options & WNOHANG) != 0) {
+ return 0;
+ }
+ process_sleep(1);
+ continue;
+ }
+
if (!found_child) {
spin_unlock_irqrestore(&sched_lock, flags);
return -ECHILD;
hal_cpu_enable_interrupts();
schedule();
- if (current_process->wait_result_pid != -1) {
- int rp = current_process->wait_result_pid;
- int st = current_process->wait_result_status;
-
- uintptr_t flags2 = spin_lock_irqsave(&sched_lock);
- struct process* child = process_find_locked((uint32_t)rp);
- if (child && child->parent_pid == current_process->pid && child->state == PROCESS_ZOMBIE) {
- process_reap_locked(child);
- }
- spin_unlock_irqrestore(&sched_lock, flags2);
-
- current_process->waiting = 0;
- current_process->wait_pid = -1;
- current_process->wait_result_pid = -1;
- if (status_out) *status_out = st;
- return rp;
- }
+ current_process->waiting = 0;
+ current_process->wait_pid = -1;
+ current_process->wait_result_pid = -1;
}
}
if (!sn) { ksocket_close(sid); sc_ret(regs) = (uint32_t)-ENOMEM; return; }
struct file* f = (struct file*)kmalloc(sizeof(struct file));
if (!f) { sock_node_close(sn); sc_ret(regs) = (uint32_t)-ENOMEM; return; }
+ memset(f, 0, sizeof(*f));
f->node = sn;
f->offset = 0;
f->flags = 2; /* O_RDWR — sockets are bidirectional */
if (!sn) { ksocket_close(new_sid); sc_ret(regs) = (uint32_t)-ENOMEM; return; }
struct file* f = (struct file*)kmalloc(sizeof(struct file));
if (!f) { sock_node_close(sn); sc_ret(regs) = (uint32_t)-ENOMEM; return; }
+ memset(f, 0, sizeof(*f));
f->node = sn;
f->offset = 0;
f->flags = 2; /* O_RDWR — sockets are bidirectional */