(* Lorsqu'un Zombie est finalement libéré *)
let remove_process process processes =
  (* Il rattacher ses fils aux processus 0.
     ---XXX ce n'est pas ce qui est fait. *)

  let update_ppid ppid pid pid2 process2 =
    if process2.ppid = pid then (* c'est donc un fils *)
      match process2.state with
      | Zombie i -> Hashtbl.remove processes process2.pid
      | _ -> process2.ppid <- 0 in
  Hashtbl.iter (update_ppid process.ppid process.pidprocesses;
  Hashtbl.remove processes process.pid;;

let waitpid system_state =
  let p = system_state.current in
  if !verbose then Printf.eprintf "Waitpid\n%!";
  let rec is_child process =
    process.ppid = p.pid ||
    process.ppid <> 0 &&
    is_child (Hashtbl.find system_state.processes process.ppid)
  in
  let error () = p.preg.(v0) <- -1; run system_state in
  let pid = p.preg.(a0in
  try
    (* on cherche le processus dans la table des processus *)
    let process = Hashtbl.find system_state.processes pid in
    if not (is_child processthen error ()
    else
      begin
        (* retour normal *)
        p.preg.(v0) <- 0;
        match process.state with
        | Zombie ret ->
            p.preg.(v1) <- ret;
            remove_process process system_state.processes;
            run system_state
        | _ ->
            p.state <- Waitpid p.preg.(a0);
            system_state.active_processes :=
              List.filter ((<>) p) !(system_state.active_processes);
            schedule system_state
      end
  with Not_found -> error () in
system_traps.(sys_Waitpid) <- waitpid;;