From d932ade7ea0cbe5152021533dc65a30e39cf993a Mon Sep 17 00:00:00 2001
From: Sag0Sag0 <Sag0Sag0@users.noreply.github.com>
Date: Tue, 5 Dec 2017 13:28:20 +1100
Subject: [PATCH] Add ability for which builtin to process multiple arguments
 (#629)

* Start adding manpages

* Add manpages for all builtins

* Fix so that changes pass tests

* Add ability for which to process more than one argument

* Fix typo

* Fixes

* Fixes
---
 src/builtins/man_pages.rs |  6 ++---
 src/builtins/mod.rs       | 48 +++++++++++++++++----------------------
 2 files changed, 24 insertions(+), 30 deletions(-)

diff --git a/src/builtins/man_pages.rs b/src/builtins/man_pages.rs
index 57eb541f..d5b5355f 100644
--- a/src/builtins/man_pages.rs
+++ b/src/builtins/man_pages.rs
@@ -577,9 +577,9 @@ pub(crate) const MAN_WHICH: &'static str = r#"NAME
     which - locate a program file in the current user's path
 
 SYNOPSIS
-    which PROGRAM
+    which PROGRAM 
 
 DESCRIPTION
-    The which utility takes a command name and searches the path for the executable file that would 
-    be run had the command been executed.
+    The which utility takes a list of command names and searches for the 
+    alias/builtin/function/executable that would be executed if you ran that command.
 "#;
\ No newline at end of file
diff --git a/src/builtins/mod.rs b/src/builtins/mod.rs
index 72ecc24c..cd6361a9 100644
--- a/src/builtins/mod.rs
+++ b/src/builtins/mod.rs
@@ -585,34 +585,28 @@ fn builtin_which(args: &[&str], shell: &mut Shell) -> i32 {
         return SUCCESS
     }
 
-    if args[1..].len() != 1 {
-        let stderr = io::stderr();
-        let mut stderr = stderr.lock();
-        let _ = stderr.write_all(b"which takes one argument\n");
-        return BAD_ARG;
-    }
-
-    let command = args[1];
-
-    if let Some(alias) = shell.variables.aliases.get(command) {
-        println!("{}: alias to {}", command, alias);
-        SUCCESS
-    } else if shell.builtins.contains_key(command) {
-        println!("{}: built-in shell command", command);
-        SUCCESS
-    } else if shell.functions.contains_key(command) {
-        println!("{}: function", command);
-        SUCCESS
-    } else {
-        for path in env::var("PATH").unwrap_or("/bin".to_string()).split(sys::PATH_SEPARATOR) {
-            let executable = Path::new(path).join(command);
-            if executable.is_file() {
-                println!("{}", executable.display());
-                return SUCCESS;
+    let mut result = SUCCESS;
+    'outer: for &command in &args[1..] {
+        if let Some(alias) = shell.variables.aliases.get(command) {
+            println!("{}: alias to {}", command, alias);
+            continue;
+        } else if shell.functions.contains_key(command) {
+            println!("{}: function", command);
+            continue;
+        } else if shell.builtins.contains_key(command) {
+            println!("{}: built-in shell command", command);
+            continue;
+        } else {
+            for path in env::var("PATH").unwrap_or("/bin".to_string()).split(sys::PATH_SEPARATOR) {
+                let executable = Path::new(path).join(command);
+                if executable.is_file() {
+                    println!("{}", executable.display());
+                    continue 'outer;
+                }
             }
+            result = FAILURE;
+            println!("{} not found", command);
         }
-
-        println!("{} not found", command);
-        FAILURE
     }
+    result
 }
-- 
GitLab