let rec openentry_int fifoin fifoout (abspath:string*string) =
  let fdin =
    try openfile fifoin [O_RDONLY;O_NONBLOCK] 0o777 with 
        e->fprintf logfd "Error opening and connecting FIFO: %s,%o\n" fifoin 0o777;flush logfd;raise e
  in
    Hashtbl.replace fdmap fdin abspath;
    Fdwatcher.add_fd (Some(fifoin),fdin) (Some(fifoout),stdout) receive_fifo_event
and reopenentry_int fdin fifoin fifoout =
  close fdin;
    Fdwatcher.del_fd fdin;
    let abspath = try 
      Hashtbl.find fdmap fdin with _ -> fprintf logfd "Bug: Phantom pipe\n";flush logfd;raise Bug
    in
      openentry_int fifoin fifoout abspath

(** receive an event from a fifo and connect to the corresponding service, or to create it if it doesn't exit @param eventdescriptor Name of input pipe,in descriptor @param outdescriptor Name of output pipe, out descriptor *)

and receive_fifo_event eventdescriptor outdescriptor =
  let (evfname,evfd) = eventdescriptor in
  let (fname_other,fd_other) = outdescriptor in
  (* Open the output pipe, or use stdout instead *)
  let outfd =
    match (fname_other) with
      | Some(str)->
          (
            try openfile str [O_WRONLY;O_NONBLOCK] 0o777 with
                _->fprintf logfd "Output pipe not open, using stdout in place of %s\n" str;flush logfd;stdout
          )
      | None-> fprintf logfd "Bug, nameless pipe\n";flush logfd;raise Bug
  in
  (* Check if the input descriptor is already registered (=> a session is open).
   If not, register it and start a new session.*)

  let pipe = try Hashtbl.find open_fds evfd with
    | Not_found ->
        (* Ok, need to launch script *)
        let execpath,slice_name = Hashtbl.find fdmap evfd in
        let (script_infd,pout) = Unix.pipe () in
        let (pin,script_outfd) = Unix.pipe () in
          set_nonblock script_infd;
          ignore(sigprocmask SIG_BLOCK [Sys.sigchld]);
          let rpid = try Some(create_process execpath [|execpath;slice_name|] pin pout pout) with e -> fprintf logfd "Error executing service: %s\n" execpath;flush logfd;None
          in
            match rpid with
              | None-> BrokenPipe
              | Some(pid)->
                  (* Register fds associated with pid so that they can be cleaned up
                   * when it dies *)

                  Hashtbl.add pidmap pid [Infd(script_infd);Outfd(script_outfd);Eventfd(evfd)];

                  (* Connect pipe to running script *)
                  Hashtbl.add open_fds evfd (Process(script_outfd));

                  (* Connect the running script to the pipe *)
                  Hashtbl.add open_fds script_infd (Fifo(outfd));

                  (* Activate running script *)
                  Fdwatcher.add_fd (None,script_infd) (None,script_infd) receive_process_event;

                  (Process(script_outfd))
  in
    (* We have the connection to the process - because it was open, or because it
     just got established *)

    match (pipe) with
      | Process(fifo_outfd) -> 
          begin
            try
              let transferred = ref 4096 in
                while (!transferred == 4096) do
                  begin
                  transferred:=tee evfd fifo_outfd 4096;
                                 printf "Transferred: %d\n" !transferred;flush Pervasives.stdout
                  end
                done;
            with Failure(str) ->
              begin
                fprintf logfd "Error connecting user to service: %s\n" str;
                flush logfd
              end;
              ignore(sigprocmask SIG_UNBLOCK [Sys.sigchld]);
                                 printf "Out of the loop\n";flush Pervasives.stdout

          end
      | BrokenPipe -> ()
      | Fifo(_) -> fprintf logfd "BUG! received process event from fifo\n";raise Bug