diff options
Diffstat (limited to 'libbb/execable.c')
-rw-r--r-- | libbb/execable.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/libbb/execable.c b/libbb/execable.c new file mode 100644 index 000000000..cb56b9181 --- /dev/null +++ b/libbb/execable.c @@ -0,0 +1,62 @@ +/* vi: set sw=4 ts=4: */ +/* + * Utility routines. + * + * Copyright (C) 2006 Gabriel Somlo <somlo at cmu.edu> + * + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + */ + +#include "libbb.h" + +/* check if path points to an executable file; + * return 1 if found; + * return 0 otherwise; + */ +int execable_file(const char *name) +{ + struct stat s; + return (!access(name, X_OK) && !stat(name, &s) && S_ISREG(s.st_mode)); +} + +/* search $PATH for an executable file; + * return allocated string containing full path if found; + * return NULL otherwise; + */ +char *find_execable(const char *filename) +{ + char *path, *p, *n; + + p = path = xstrdup(getenv("PATH") ? : ""); + while (p) { + n = strchr(p, ':'); + if (n) + *n++ = '\0'; + if (*p != '\0') { /* it's not a PATH="foo::bar" situation */ + p = concat_path_file(p, filename); + if (execable_file(p)) { + free(path); + return p; + } + free(p); + } + p = n; + } + free(path); + return NULL; +} + +/* search $PATH for an executable file; + * return 1 if found; + * return 0 otherwise; + */ +int exists_execable(const char *filename) +{ + char *ret = find_execable(filename); + if (ret) { + free(ret); + return 1; + } + return 0; +} + |