[Libguestfs] [PATCH 2/3] mlstdutils: allow relative/absolute paths for Std_utils.which

Pino Toscano ptoscano at redhat.com
Fri Jan 11 16:04:14 UTC 2019


Make Std_utils.which behave a bit more like which(1), checking the
existance of relative/absolute paths specified.
---
 common/mlstdutils/std_utils.ml       | 29 ++++++++++++++++------------
 common/mlstdutils/std_utils.mli      |  5 ++++-
 common/mlstdutils/std_utils_tests.ml | 10 ++++++++++
 3 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/common/mlstdutils/std_utils.ml b/common/mlstdutils/std_utils.ml
index 5a92dccc9..70156d1ba 100644
--- a/common/mlstdutils/std_utils.ml
+++ b/common/mlstdutils/std_utils.ml
@@ -610,18 +610,23 @@ let failwithf fs = ksprintf failwith fs
 exception Executable_not_found of string (* executable *)
 
 let which executable =
-  let paths =
-    try String.nsplit ":" (Sys.getenv "PATH")
-    with Not_found -> [] in
-  let paths = List.filter_map (
-    fun p ->
-      let path = p // executable in
-      try Unix.access path [Unix.X_OK]; Some path
-      with Unix.Unix_error _ -> None
-  ) paths in
-  match paths with
-  | [] -> raise (Executable_not_found executable)
-  | x :: _ -> x
+  if String.find executable Filename.dir_sep <> -1 then (
+    try Unix.access executable [Unix.X_OK]; executable
+    with Unix.Unix_error _ -> raise (Executable_not_found executable)
+  ) else (
+    let paths =
+      try String.nsplit ":" (Sys.getenv "PATH")
+      with Not_found -> [] in
+    let paths = List.filter_map (
+      fun p ->
+        let path = p // executable in
+        try Unix.access path [Unix.X_OK]; Some path
+        with Unix.Unix_error _ -> None
+    ) paths in
+    match paths with
+    | [] -> raise (Executable_not_found executable)
+    | x :: _ -> x
+  )
 
 (* Program name. *)
 let prog = Filename.basename Sys.executable_name
diff --git a/common/mlstdutils/std_utils.mli b/common/mlstdutils/std_utils.mli
index ca4e940cf..5e5242f7a 100644
--- a/common/mlstdutils/std_utils.mli
+++ b/common/mlstdutils/std_utils.mli
@@ -359,7 +359,10 @@ exception Executable_not_found of string (* executable *)
     in [$PATH]. *)
 
 val which : string -> string
-(** Return the full path of the specified executable from [$PATH].
+(** Return the full path of the specified executable from [$PATH],
+    in case it is only a name.  In case of a relative or absolute path
+    (i.e. more than just a name), return the same path specified if
+    exists.
 
     Throw [Executable_not_found] if not available. *)
 
diff --git a/common/mlstdutils/std_utils_tests.ml b/common/mlstdutils/std_utils_tests.ml
index f7b0247a4..d161b5e7e 100644
--- a/common/mlstdutils/std_utils_tests.ml
+++ b/common/mlstdutils/std_utils_tests.ml
@@ -149,6 +149,16 @@ let test_string_chomp ctx =
 let test_which ctx =
   assert_nonempty_string (which "true");
   assert_raises_executable_not_found "this-command-does-not-really-exist";
+  begin
+    let exe_name = "true" in
+    let exe = which exe_name in
+    assert_equal_string exe (which exe);
+    with_bracket_chdir ctx (Filename.dirname exe) (
+      fun ctx ->
+        let exe_relative = "./" ^ exe_name in
+        assert_equal_string exe_relative (which exe_relative)
+    )
+  end;
   ()
 
 (* Suites declaration. *)
-- 
2.17.2




More information about the Libguestfs mailing list