From ea2428e3da03ae78ac088f46961f80439a433348 Mon Sep 17 00:00:00 2001 From: Jeremy Dubreil Date: Sat, 22 Oct 2016 22:02:53 -0700 Subject: [PATCH] [infer][config] fix resolution of symbolic links Summary: Fix the resolution of symbolic links. The previous version did not work if the path itself was not a symbolic link, but there was a symbolic link somewhere up in the path tree. For example: `path/to/file` where `file` is not a symbolic link, but `to` is a symbolic link. Reviewed By: jberdine Differential Revision: D4062947 fbshipit-source-id: 394221d --- infer/src/base/Config.ml | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml index bea1acfa9..932c1d646 100644 --- a/infer/src/base/Config.ml +++ b/infer/src/base/Config.ml @@ -241,20 +241,33 @@ let version_string = Unix.time *) let initial_analysis_time = Unix.time () +(* Splits a path into its parts. For example: + - (split "path/to/file") is [".", "path"; "to"; "file"] + - (split "/path/to/file") is ["/", "path"; "to"; "file"] *) +let split path = + let rec loop accu p = + match Filename.dirname p with + | d when d = p -> d :: accu + | d -> loop ((Filename.basename p) :: accu) d in + loop [] path + (* Recursively resolve symlinks until we get something that is not a link. Executables may be (multiple levels of) symbolic links to the real binary directory, eg after `make install` or packaging. *) -let rec real_path path = - match Unix.readlink path with - | link when Filename.is_relative link -> - (* [path] is a relative symbolic link *) - real_path ((Filename.dirname path) // link) - | link -> - (* [path] is an absolute symbolic link *) - real_path link - | exception Unix.Unix_error(Unix.EINVAL, _, _) -> - (* [path] is not a symbolic link *) - path +let real_path path = + let rec resolve p = + match Unix.readlink p with + | link when Filename.is_relative link -> + (* [p] is a relative symbolic link *) + resolve ((Filename.dirname p) // link) + | link -> + (* [p] is an absolute symbolic link *) + resolve link + | exception Unix.Unix_error(Unix.EINVAL, _, _) -> + (* [p] is not a symbolic link *) + p in + IList.fold_left + (fun resolved_path p -> resolve (resolved_path // p)) "" (split path) (* Resolve symlinks to get to the real executable. The real executable is located in [bin_dir] below, which allows us to find [lib_dir], [models_dir], etc., relative to it. *)