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
and receive_fifo_event eventdescriptor outdescriptor =
let (evfname,evfd) = eventdescriptor in
let (fname_other,fd_other) = outdescriptor in
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
let pipe = try Hashtbl.find open_fds evfd with
| Not_found ->
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)->
Hashtbl.add pidmap pid [Infd(script_infd);Outfd(script_outfd);Eventfd(evfd)];
Hashtbl.add open_fds evfd (Process(script_outfd));
Hashtbl.add open_fds script_infd (Fifo(outfd));
Fdwatcher.add_fd (None,script_infd) (None,script_infd) receive_process_event;
(Process(script_outfd))
in
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