[Libguestfs] [PATCH] mllib: check for executable existance in run_command (RHBZ#1362357)

Pino Toscano ptoscano at redhat.com
Tue Aug 2 17:14:09 UTC 2016


run_command uses Unix.create_process which forks a child process, and
executes execve: the latter fails when the executable does not exist,
triggering the exit which, in older OCaml versions [1], also runs the
at_exit handlers.

Since there is not much that can be done to avoid this on the OCaml
side, to keep run_command working also in older OCaml version then
manually search for the existance of the given executable, exiting with
code 127 (as a shell does) in this case.

[1] http://caml.inria.fr/mantis/view.php?id=7209
---
 mllib/common_utils.ml | 32 ++++++++++++++++++++------------
 1 file changed, 20 insertions(+), 12 deletions(-)

diff --git a/mllib/common_utils.ml b/mllib/common_utils.ml
index 14f4935..fdca713 100644
--- a/mllib/common_utils.ml
+++ b/mllib/common_utils.ml
@@ -677,18 +677,26 @@ let external_command ?(echo_cmd = true) cmd =
 let run_command ?(echo_cmd = true) args =
   if echo_cmd then
     debug "%s" (stringify_args args);
-  let pid =
-    Unix.create_process (List.hd args) (Array.of_list args) Unix.stdin
-      Unix.stdout Unix.stderr in
-  let _, stat = Unix.waitpid [] pid in
-  match stat with
-  | Unix.WEXITED i -> i
-  | Unix.WSIGNALED i ->
-    error (f_"external command '%s' killed by signal %d")
-      (stringify_args args) i
-  | Unix.WSTOPPED i ->
-    error (f_"external command '%s' stopped by signal %d")
-      (stringify_args args) i
+  let app = List.hd args in
+  try
+    let app =
+      if Filename.is_relative app then which app
+      else (Unix.access app [Unix.X_OK]; app) in
+    let pid =
+      Unix.create_process app (Array.of_list args) Unix.stdin
+        Unix.stdout Unix.stderr in
+    let _, stat = Unix.waitpid [] pid in
+    match stat with
+    | Unix.WEXITED i -> i
+    | Unix.WSIGNALED i ->
+      error (f_"external command '%s' killed by signal %d")
+        (stringify_args args) i
+    | Unix.WSTOPPED i ->
+      error (f_"external command '%s' stopped by signal %d")
+        (stringify_args args) i
+  with
+  | Executable_not_found tool -> 127
+  | Unix.Unix_error (errcode, _, _) when errcode = Unix.ENOENT -> 127
 
 let shell_command ?(echo_cmd = true) cmd =
   if echo_cmd then
-- 
2.7.4




More information about the Libguestfs mailing list