which: Move executable check to helper function

This commit is contained in:
Michael Forney 2017-10-20 12:30:20 -07:00
parent 5b66e55a83
commit 44265b29ce
1 changed files with 12 additions and 7 deletions

19
which.c
View File

@ -13,18 +13,25 @@
static int aflag; static int aflag;
static int
canexec(int fd, const char *name)
{
struct stat st;
if (fstatat(fd, name, &st, 0) < 0 || !S_ISREG(st.st_mode))
return 0;
return faccessat(fd, name, X_OK, 0) == 0;
}
static int static int
which(const char *path, const char *name) which(const char *path, const char *name)
{ {
char *ptr, *p; char *ptr, *p;
size_t i, len; size_t i, len;
struct stat st;
int dirfd, found = 0; int dirfd, found = 0;
if (strchr(name, '/')) { if (strchr(name, '/')) {
if (!fstatat(AT_FDCWD, name, &st, 0) && if (canexec(AT_FDCWD, name)) {
S_ISREG(st.st_mode) &&
!access(name, X_OK)) {
puts(name); puts(name);
return 1; return 1;
} }
@ -37,9 +44,7 @@ which(const char *path, const char *name)
continue; continue;
ptr[i] = '\0'; ptr[i] = '\0';
if ((dirfd = open(p, O_RDONLY, 0)) >= 0) { if ((dirfd = open(p, O_RDONLY, 0)) >= 0) {
if (!fstatat(dirfd, name, &st, 0) && if (canexec(dirfd, name)) {
S_ISREG(st.st_mode) &&
!faccessat(dirfd, name, X_OK, 0)) {
found = 1; found = 1;
fputs(p, stdout); fputs(p, stdout);
if (i && ptr[i - 1] != '/') if (i && ptr[i - 1] != '/')