Blame SOURCES/0161-mllib-check-for-executable-existance-in-run_command-.patch

e76f14
From 037e340e348af57468920caee842bfb73aa03a3a Mon Sep 17 00:00:00 2001
e76f14
From: Pino Toscano <ptoscano@redhat.com>
e76f14
Date: Tue, 2 Aug 2016 18:45:34 +0200
e76f14
Subject: [PATCH] mllib: check for executable existance in run_command
e76f14
 (RHBZ#1362357)
e76f14
e76f14
run_command uses Unix.create_process which forks a child process, and
e76f14
executes execve: the latter fails when the executable does not exist,
e76f14
triggering the exit which, in older OCaml versions [1], also runs the
e76f14
at_exit handlers.
e76f14
e76f14
Since there is not much that can be done to avoid this on the OCaml
e76f14
side, to keep run_command working also in older OCaml version then
e76f14
manually search for the existance of the given executable, exiting with
e76f14
code 127 (as a shell does) in this case.
e76f14
e76f14
[1] http://caml.inria.fr/mantis/view.php?id=7209
e76f14
e76f14
(cherry picked from commit 2cb053d3fea709b1f72681f1c556c5623c8f6fa7)
e76f14
---
e76f14
 mllib/common_utils.ml | 32 ++++++++++++++++++++------------
e76f14
 1 file changed, 20 insertions(+), 12 deletions(-)
e76f14
e76f14
diff --git a/mllib/common_utils.ml b/mllib/common_utils.ml
e76f14
index 7e44029..51449ad 100644
e76f14
--- a/mllib/common_utils.ml
e76f14
+++ b/mllib/common_utils.ml
e76f14
@@ -707,18 +707,26 @@ let external_command ?(echo_cmd = true) cmd =
e76f14
 let run_command ?(echo_cmd = true) args =
e76f14
   if echo_cmd then
e76f14
     debug "%s" (stringify_args args);
e76f14
-  let pid =
e76f14
-    Unix.create_process (List.hd args) (Array.of_list args) Unix.stdin
e76f14
-      Unix.stdout Unix.stderr in
e76f14
-  let _, stat = Unix.waitpid [] pid in
e76f14
-  match stat with
e76f14
-  | Unix.WEXITED i -> i
e76f14
-  | Unix.WSIGNALED i ->
e76f14
-    error (f_"external command '%s' killed by signal %d")
e76f14
-      (stringify_args args) i
e76f14
-  | Unix.WSTOPPED i ->
e76f14
-    error (f_"external command '%s' stopped by signal %d")
e76f14
-      (stringify_args args) i
e76f14
+  let app = List.hd args in
e76f14
+  try
e76f14
+    let app =
e76f14
+      if Filename.is_relative app then which app
e76f14
+      else (Unix.access app [Unix.X_OK]; app) in
e76f14
+    let pid =
e76f14
+      Unix.create_process app (Array.of_list args) Unix.stdin
e76f14
+        Unix.stdout Unix.stderr in
e76f14
+    let _, stat = Unix.waitpid [] pid in
e76f14
+    match stat with
e76f14
+    | Unix.WEXITED i -> i
e76f14
+    | Unix.WSIGNALED i ->
e76f14
+      error (f_"external command '%s' killed by signal %d")
e76f14
+        (stringify_args args) i
e76f14
+    | Unix.WSTOPPED i ->
e76f14
+      error (f_"external command '%s' stopped by signal %d")
e76f14
+        (stringify_args args) i
e76f14
+  with
e76f14
+  | Executable_not_found tool -> 127
e76f14
+  | Unix.Unix_error (errcode, _, _) when errcode = Unix.ENOENT -> 127
e76f14
 
e76f14
 let shell_command ?(echo_cmd = true) cmd =
e76f14
   if echo_cmd then
e76f14
-- 
e76f14
1.8.3.1
e76f14