From 12018284746e4f19f4e21a6e698cc8e07c38dd1e Mon Sep 17 00:00:00 2001
From: Raymond Toy <toy.raymond@gmail.com>
Date: Sat, 30 Sep 2017 13:51:23 -0700
Subject: [PATCH] Fix #45: Handle relative paths in `run-program`

This is basically the solution proposed by Elias Pipping with a few
minor tweaks.

    - In `run-program`, don't merge `program` with the "path:"
      search-list.  `spawn` will handle this.
    - In `spawn`, if the first call to execve fails, instead of trying
      "/bin/sh", use "/usr/bin/env" which will use the user's PATH if
      necessary to find the program.
---
 src/code/run-program.lisp | 7 ++-----
 src/lisp/runprog.c        | 6 +++---
 2 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/src/code/run-program.lisp b/src/code/run-program.lisp
index 23abdb349..938276372 100644
--- a/src/code/run-program.lisp
+++ b/src/code/run-program.lisp
@@ -528,10 +528,7 @@
   ;; info.  Also, establish proc at this level so we can return it.
   (let (*close-on-error* *close-in-parent* *handlers-installed* proc)
     (unwind-protect
-	(let ((pfile (unix-namestring (merge-pathnames program "path:") t t))
-	      (cookie (list 0)))
-	  (unless pfile
-	    (error (intl:gettext "No such program: ~S") program))
+	(let ((cookie (list 0)))
 	  (multiple-value-bind
 	      (stdin input-stream)
 	      (get-descriptor-for input cookie :direction :input
@@ -570,7 +567,7 @@
 					env))
 			(let ((child-pid
 			       (without-gcing
-				(spawn pfile argv envp pty-name
+				(spawn program argv envp pty-name
 				       stdin stdout stderr))))
 			  (when (< child-pid 0)
 			    (error (intl:gettext "Could not fork child process: ~A")
diff --git a/src/lisp/runprog.c b/src/lisp/runprog.c
index 556c34e0b..61a9bb8df 100644
--- a/src/lisp/runprog.c
+++ b/src/lisp/runprog.c
@@ -65,10 +65,10 @@ spawn(char *program, char *argv[], char *envp[], char *pty_name,
     /* Exec the program. */
     execve(program, argv, envp);
 
-    /* It didn't work, so try /bin/sh. */
+    /* It didn't work, so try /usr/bin/env. */
     argv[0] = program;
-    argv[-1] = "sh";
-    execve("/bin/sh", argv - 1, envp);
+    argv[-1] = "/usr/bin/env";
+    execve("/usr/bin/env", argv - 1, envp);
 
     /* The exec didn't work, flame out. */
     exit(1);
-- 
GitLab