Version française
Home     About     Download     Resources     Contact us    
Browse thread
Strange buffering interaction: stdout / file_descr
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Gerd Stolpmann <gerd@g...>
Subject: Re: [Caml-list] Strange buffering interaction: stdout / file_descr
This is the somewhat expected behavior, although a bit surprising at the
first glance. create_process isn't an atomic operation. Actually, it
forks the process (and thus implicitly duplicates the stdout buffer). In
the forked child it tries to exec the new executable. If this fails, it
does a regular exit(), and the buffers are flushed.

One can argue that this is wrong - the implementation should better do
an _exit (i.e. immediately exit the child process without doing any sort
of "cleanup"). AFAIK, system() implementations do this.

The standard way of checking for exec errors is to test the exit code,
and if it is 127, exec or the code immediately before exec failed.
That's a convention only, i.e. nothing enforces this.

Gerd

Am Samstag, den 23.05.2009, 16:17 -0500 schrieb Alexander Fuchs:
> let () =
>   print_string "main";
> 
>   let (stdout_r, stdout_w) = Unix.socketpair Unix.PF_UNIX
> Unix.SOCK_STREAM 0 in
>   let (stdin_r, stdin_w) = Unix.socketpair Unix.PF_UNIX
> Unix.SOCK_STREAM
> 0 in
> 
>   let cmd = "none" in
> 
>   (* without flush reading from stdout_r yields "main" *)
>   (* flush stdout; *)
>   let pid = Unix.create_process cmd [| cmd; "-version" |] stdin_r
> stdout_w stdout_w in
> 
>   Unix.close stdin_r;
>   Unix.close stdout_w;
> 
>   begin
> 
>     let (outs, _, _) = Unix.select [stdout_r] [] [] (-1.0) in
> 
>     match outs with
>     | [out] ->
>         let buffer = String.make 100 ' ' in
>         let size =  Unix.read out buffer 0 100 in
> 
>         if size > 0 then begin
>           print_endline (buffer)
>         end
> 
>         else begin
>           print_endline "create_process failed"
>         end
> 
>     | _ ->
>         assert false;
>   end;
> 
>   Unix.close stdout_r;
>   Unix.close stdin_w;
>   Unix.kill pid Sys.sigkill;
>   let (_, _status) = Unix.waitpid [] pid in
>   ()
> 
-- 
------------------------------------------------------------
Gerd Stolpmann * Viktoriastr. 45 * 64293 Darmstadt * Germany 
gerd@gerd-stolpmann.de          http://www.gerd-stolpmann.de
Phone: +49-6151-153855                  Fax: +49-6151-997714
------------------------------------------------------------