diff options
Diffstat (limited to 'toys')
-rw-r--r-- | toys/Config.in | 16 | ||||
-rw-r--r-- | toys/which.c | 72 |
2 files changed, 88 insertions, 0 deletions
diff --git a/toys/Config.in b/toys/Config.in index d9b1da10..89481bde 100644 --- a/toys/Config.in +++ b/toys/Config.in @@ -28,6 +28,12 @@ config DF_PEDANTIC -k Sets units back to 1024 bytes (the default without -P) +config HELLO + bool "hello" + default n + help + A hello world program. You don't need this. + config TOYSH bool "sh (toysh)" default n @@ -146,5 +152,15 @@ config TOYSH_BUILTINS Adds the commands exec, fg, bg, help, jobs, pwd, export, source, set, unset, read, alias. +config WHICH + bool "Which" + default n + help + usage: which [-a] filename ... + + Search $PATH for executable files matching filename(s). + + -a Show all matches + endmenu diff --git a/toys/which.c b/toys/which.c new file mode 100644 index 00000000..6d00bc82 --- /dev/null +++ b/toys/which.c @@ -0,0 +1,72 @@ +/* vi: set sw=4 ts=4: */ +/* + * which.c - + * + * Copyright 2006 Rob landley <rob@landley.net> + */ + +#include "toys.h" + +#define OPTIONS "a" +#define OPT_a 1 + +// Find an exectuable file either at a path with a slash in it (absolute or +// relative to current directory), or in $PATH. Returns absolute path to file, +// or NULL if not found. + +static int which_in_path(char *filename) +{ + struct string_list *list; + + // If they gave us a path, don't worry about $PATH or -a + + if (index(filename, '/')) { + // Confirm it has the executable bit set, and it's not a directory. + if (!access(filename, X_OK)) { + struct stat st; + + if (!stat(filename, &st) && S_ISREG(st.st_mode)) { + puts(filename); + return 0; + } + return 1; + } + } + + // Search $PATH for matches. + list = find_in_path(getenv("PATH"), filename); + if (!list) return 1; + + // Print out matches + while (list) { + if (!access(list->str, X_OK)) { + puts(list->str); + // If we should stop at one match, do so + if (toys.optflags & OPT_a) { + llist_free(list, NULL); + break; + } + } + free(llist_pop(&list)); + } + + return 0; +} + +int which_main(void) +{ + char **argv; + int rc = 0; + + // get_optflags(OPTIONS); + argv = toys.argv+1; + + if (!*argv) rc++; + else { + int i; + for (i=0; argv[i]; i++) rc |= which_in_path(argv[i]); + } + // if (CFG_TOYS_FREE) free(argv); + + return rc; +} |