From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=disabled version=3.1.3 Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by yquem.inria.fr (Postfix) with ESMTP id 9D761BC37 for ; Sun, 24 May 2009 12:53:08 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AsACAHPDGErU436xlGdsb2JhbACBT5YUAQEBAQkLCAkRA7dxAoQJBYg7 X-IronPort-AV: E=Sophos;i="4.41,239,1241388000"; d="scan'208";a="28202092" Received: from moutng.kundenserver.de ([212.227.126.177]) by mail3-smtp-sop.national.inria.fr with ESMTP; 24 May 2009 12:53:08 +0200 Received: from office1.lan.sumadev.de (dslb-094-219-210-005.pools.arcor-ip.net [94.219.210.5]) by mrelayeu.kundenserver.de (node=mreu1) with ESMTP (Nemesis) id 0MKv1o-1M8BKF0y6S-000jN7; Sun, 24 May 2009 12:53:07 +0200 Received: from [192.168.5.104] (dslb-094-219-210-005.pools.arcor-ip.net [94.219.210.5]) by office1.lan.sumadev.de (Postfix) with ESMTPSA id 080A4C0F06; Sun, 24 May 2009 12:53:07 +0200 (CEST) Subject: Re: [Caml-list] Strange buffering interaction: stdout / file_descr From: Gerd Stolpmann To: fuchs@cs.uiowa.edu Cc: caml-list@inria.fr In-Reply-To: <1243113461.18993.34.camel@Knecht> References: <1243113461.18993.34.camel@Knecht> Content-Type: text/plain Date: Sun, 24 May 2009 12:55:56 +0200 Message-Id: <1243162556.11739.7.camel@flake.lan.gerd-stolpmann.de> Mime-Version: 1.0 X-Mailer: Evolution 2.12.1 Content-Transfer-Encoding: 7bit X-Provags-ID: V01U2FsdGVkX18xGef74OMlqXrrTaaUApT+ImeBRY+Qd+AUal1 b5nATgqmIGbK/j2YRSn6cbV+7Mk7WMPxllrALIKBxFQWWYMXcl ZrMPuR1stWpfgKKEE1v7w== X-Spam: no; 0.00; stdout:01 gerd:01 stolpmann:01 gerd:01 forks:01 stdout:01 buffer:01 afaik:01 enforces:01 stdin:01 stdin:01 -version:01 buffer:01 endline:01 endline:01 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 ------------------------------------------------------------