Is there any way to capture the stdout & stderr output of the current process?

From memory, this can be done using a pipe. Something like (not tested):

let saved_stdout =
  Unix.dup Unix.stdout (* save current stdout to restore it later *)

let stdout_read =
  let pipe_read, pipe_write = Unix.pipe () in
  Unix.dup2 pipe_write Unix.stdout; (* Unix.stdout now points to pipe_write *)
  Unix.close pipe_write;
  pipe_read

Now you can read from stdout_read in order to “read the stdout” of the current program. If you ever want to restore the “old” stdout you do so by

let () =
  Unix.dup2 saved_stdout Unix.stdout;
  Unix.close saved_stdout

Cheers,
Nicolas