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=AWL autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from discorde.inria.fr (discorde.inria.fr [192.93.2.38]) by yquem.inria.fr (Postfix) with ESMTP id 689FEBC69 for ; Thu, 2 Aug 2007 18:21:09 +0200 (CEST) Received: from ipmail01.adl2.internode.on.net (ipmail01.adl2.internode.on.net [203.16.214.140]) by discorde.inria.fr (8.13.6/8.13.6) with ESMTP id l72GL7Iw002842 for ; Thu, 2 Aug 2007 18:21:08 +0200 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgAAAMedsUZ5LGJp/2dsb2JhbAAN X-IronPort-AV: E=Sophos;i="4.19,213,1183300200"; d="scan'208";a="166205692" Received: from ppp121-44-98-105.lns10.syd6.internode.on.net (HELO [192.168.1.201]) ([121.44.98.105]) by ipmail01.adl2.internode.on.net with ESMTP; 03 Aug 2007 01:51:00 +0930 Subject: Re: [Caml-list] absolute_name ? From: skaller To: Christophe Raffalli Cc: Correnson =?ISO-8859-1?Q?Lo=EFc?= , caml-list@inria.fr In-Reply-To: <46B1EC05.9060508@univ-savoie.fr> References: <46A0E915.1000903@univ-savoie.fr> <46B1BCD1.9030004@trusted-labs.fr> <46B1EC05.9060508@univ-savoie.fr> Content-Type: text/plain Date: Fri, 03 Aug 2007 02:21:04 +1000 Message-Id: <1186071664.6017.50.camel@rosella.wigram> Mime-Version: 1.0 X-Mailer: Evolution 2.10.1 Content-Transfer-Encoding: 7bit X-Miltered: at discorde with ID 46B20473.000 by Joe's j-chkmail (http://j-chkmail . ensmp . fr)! X-Spam: no; 0.00; 0200,:01 christophe:01 raffalli:01 basename:01 dirname:01 getcwd:01 chdir:01 getcwd:01 chdir:01 basename:01 dirname:01 sourceforge:01 wrote:01 caml-list:01 match:02 On Thu, 2007-08-02 at 16:36 +0200, Christophe Raffalli wrote: > So my original code is not so bad: yes it is: > let absolute_name str = > let base = Filename.basename str in > let dir = Filename.dirname str in > let saved_dir = Sys.getcwd () in > try Sys.chdir dir; > let res = Filename.concat (Sys.getcwd ()) base in > Sys.chdir saved_dir; > res > with > | Sys_error _ -> str > NEVER change the current directory in a program (unless the program is specifically designed to do that, eg 'chdir' program .. :) Doing so creates a side-effect, which will interfere with multi-threading. Even worse .. your error recovery routine forgets to reset the current directory. You would have to be very sure that the only failure possible is in the first Sys.chdir and it results in Sys_error without changing the current directory .. At least, you should write: let absolute_name str = let base = Filename.basename str in let dir = Filename.dirname str in let saved_dir = Sys.getcwd () in let res = try Sys.chdir dir; `Some (Filename.concat (Sys.getcwd ()) base) with | Sys_error _ -> `Some str | x -> `Error x in begin try Sys.chdir saved_dir with _ -> () end; match res with | `Error x -> raise x | `Some filename -> filename The guarantees the current directory is at least attempted to be reset. The result is still quite suspicious! For a start Windows does not HAVE a current directory! In fact it has a current directory for EVERY drive letter, independently, and it isn't only possible for two letters to map the same drive: it is stock standard practice to do that with shared drives (a shared global letter and a local one). Secondly, it doesn't account for LAN manager network mounts on Windows, or just plain old mounts on Linux. So what is the answer? There is one: let absolute_name str = str Simple. Two files are the same if, and only if, the user spelled their names the same. You cannot solve the problem: throw the responsibility back on the user. -- John Skaller Felix, successor to C++: http://felix.sf.net