diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | src/bltin/test.c | 22 |
3 files changed, 28 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog index 7af5070..9f63819 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2010-04-02 Herbert Xu <herbert@gondor.apana.org.au> + * Use faccessat if available. + +2010-04-02 Herbert Xu <herbert@gondor.apana.org.au> + * Make trap signal name/number errors non-fatal. * Release 0.5.6. diff --git a/configure.ac b/configure.ac index df6e099..c943725 100644 --- a/configure.ac +++ b/configure.ac @@ -46,7 +46,8 @@ dnl Checks for header files. AC_CHECK_HEADERS(alloca.h) dnl Checks for library functions. -AC_CHECK_FUNCS(bsearch getpwnam getrlimit imaxdiv isalpha killpg mempcpy \ +AC_CHECK_FUNCS(bsearch faccessat getpwnam getrlimit imaxdiv isalpha killpg \ + mempcpy \ sigsetmask stpcpy strchrnul strsignal strtod strtoimax \ strtoumax sysconf) diff --git a/src/bltin/test.c b/src/bltin/test.c index 8e7077a..7888f38 100644 --- a/src/bltin/test.c +++ b/src/bltin/test.c @@ -11,6 +11,7 @@ #include <sys/stat.h> #include <sys/types.h> +#include <fcntl.h> #include <stdint.h> #include <stdlib.h> #include <string.h> @@ -147,8 +148,12 @@ static int isoperand(char **); static int newerf(const char *, const char *); static int olderf(const char *, const char *); static int equalf(const char *, const char *); +#ifdef HAVE_FACCESSAT +static int test_file_access(const char *, int); +#else static int test_st_mode(const struct stat64 *, int); static int bash_group_member(gid_t); +#endif static inline intmax_t getn(const char *s) { @@ -295,6 +300,14 @@ primary(enum token n) return strlen(*t_wp) != 0; case FILTT: return isatty(getn(*t_wp)); +#ifdef HAVE_FACCESSAT + case FILRD: + return test_file_access(*t_wp, R_OK); + case FILWR: + return test_file_access(*t_wp, W_OK); + case FILEX: + return test_file_access(*t_wp, X_OK); +#endif default: return filstat(*t_wp, n); } @@ -364,12 +377,14 @@ filstat(char *nm, enum token mode) return 0; switch (mode) { +#ifndef HAVE_FACCESSAT case FILRD: return test_st_mode(&s, R_OK); case FILWR: return test_st_mode(&s, W_OK); case FILEX: return test_st_mode(&s, X_OK); +#endif case FILEXIST: return 1; case FILREG: @@ -469,6 +484,12 @@ equalf (const char *f1, const char *f2) b1.st_ino == b2.st_ino); } +#ifdef HAVE_FACCESSAT +static int test_file_access(const char *path, int mode) +{ + return !faccessat(AT_FDCWD, path, mode, AT_EACCESS); +} +#else /* HAVE_FACCESSAT */ /* * Similar to what access(2) does, but uses the effective uid and gid. * Doesn't make the mistake of telling root that any file is executable. @@ -519,3 +540,4 @@ bash_group_member(gid_t gid) return (0); } +#endif /* HAVE_FACCESSAT */ |