toybox/toys/other/which.c
<<
>>
Prefs
   1/* which.c - Find executable files in $PATH.
   2 *
   3 * Copyright 2006 Rob landley <rob@landley.net>
   4
   5USE_WHICH(NEWTOY(which, "<1a", TOYFLAG_USR|TOYFLAG_BIN))
   6
   7config WHICH
   8  bool "which"
   9  default y
  10  help
  11    usage: which [-a] filename ...
  12
  13    Search $PATH for executable files matching filename(s).
  14
  15    -a  Show all matches
  16*/
  17#include "toys.h"
  18
  19// Find an exectuable file either at a path with a slash in it (absolute or
  20// relative to current directory), or in $PATH.  Returns absolute path to file,
  21// or NULL if not found.
  22
  23static int which_in_path(char *filename)
  24{
  25  struct string_list *list;
  26
  27  // If they gave us a path, don't worry about $PATH or -a
  28
  29  if (strchr(filename, '/')) {
  30    // Confirm it has the executable bit set, and it's not a directory.
  31    if (!access(filename, X_OK)) {
  32      struct stat st;
  33
  34      if (!stat(filename, &st) && S_ISREG(st.st_mode)) {
  35        puts(filename);
  36        return 0;
  37      }
  38      return 1;
  39    }
  40  }
  41
  42  // Search $PATH for matches.
  43  list = find_in_path(getenv("PATH"), filename);
  44  if (!list) return 1;
  45
  46  // Print out matches
  47  while (list) {
  48    if (!access(list->str, X_OK)) {
  49      puts(list->str);
  50      // If we should stop at one match, do so
  51      if (!toys.optflags) {
  52        llist_traverse(list, free);
  53        break;
  54      }
  55    }
  56    free(llist_pop(&list));
  57  }
  58
  59  return 0;
  60}
  61
  62void which_main(void)
  63{
  64  int i;
  65
  66  for (i=0; toys.optargs[i]; i++)
  67    toys.exitval |= which_in_path(toys.optargs[i]);
  68}
  69