summaryrefslogtreecommitdiff
path: root/test.c
diff options
context:
space:
mode:
Diffstat (limited to 'test.c')
-rw-r--r--test.c139
1 files changed, 20 insertions, 119 deletions
diff --git a/test.c b/test.c
index 4fc0ade..f01929f 100644
--- a/test.c
+++ b/test.c
@@ -101,14 +101,7 @@ static int test_error_return;
#define test_exit(val) \
do { test_error_return = val; longjmp (test_exit_buf, 1); } while (0)
-/* We have to use access(2) for machines running AFS, because it's
- not a Unix file system. This may produce incorrect answers for
- non-AFS files. I hate AFS. */
-#if defined (AFS)
-# define EACCESS(path, mode) access(path, mode)
-#else
-# define EACCESS(path, mode) test_eaccess(path, mode)
-#endif /* AFS */
+extern int sh_stat __P((const char *, struct stat *));
static int pos; /* The offset of the current argument in ARGV. */
static int argc; /* The number of arguments present in ARGV. */
@@ -119,8 +112,6 @@ static void test_syntax_error __P((char *, char *)) __attribute__((__noreturn__)
static void beyond __P((void)) __attribute__((__noreturn__));
static void integer_expected_error __P((char *)) __attribute__((__noreturn__));
-static int test_stat __P((char *, struct stat *));
-
static int unary_operator __P((void));
static int binary_operator __P((void));
static int two_arguments __P((void));
@@ -163,96 +154,6 @@ integer_expected_error (pch)
test_syntax_error (_("%s: integer expression expected"), pch);
}
-/* A wrapper for stat () which disallows pathnames that are empty strings
- and handles /dev/fd emulation on systems that don't have it. */
-static int
-test_stat (path, finfo)
- char *path;
- struct stat *finfo;
-{
- if (*path == '\0')
- {
- errno = ENOENT;
- return (-1);
- }
- if (path[0] == '/' && path[1] == 'd' && strncmp (path, "/dev/fd/", 8) == 0)
- {
-#if !defined (HAVE_DEV_FD)
- intmax_t fd;
- int r;
-
- if (legal_number (path + 8, &fd) && fd == (int)fd)
- {
- r = fstat ((int)fd, finfo);
- if (r == 0 || errno != EBADF)
- return (r);
- }
- errno = ENOENT;
- return (-1);
-#else
- /* If HAVE_DEV_FD is defined, DEV_FD_PREFIX is defined also, and has a
- trailing slash. Make sure /dev/fd/xx really uses DEV_FD_PREFIX/xx.
- On most systems, with the notable exception of linux, this is
- effectively a no-op. */
- char pbuf[32];
- strcpy (pbuf, DEV_FD_PREFIX);
- strcat (pbuf, path + 8);
- return (stat (pbuf, finfo));
-#endif /* !HAVE_DEV_FD */
- }
-#if !defined (HAVE_DEV_STDIN)
- else if (STREQN (path, "/dev/std", 8))
- {
- if (STREQ (path+8, "in"))
- return (fstat (0, finfo));
- else if (STREQ (path+8, "out"))
- return (fstat (1, finfo));
- else if (STREQ (path+8, "err"))
- return (fstat (2, finfo));
- else
- return (stat (path, finfo));
- }
-#endif /* !HAVE_DEV_STDIN */
- return (stat (path, finfo));
-}
-
-/* Do the same thing access(2) does, but use the effective uid and gid,
- and don't make the mistake of telling root that any file is
- executable. */
-int
-test_eaccess (path, mode)
- char *path;
- int mode;
-{
- struct stat st;
-
- if (test_stat (path, &st) < 0)
- return (-1);
-
- if (current_user.euid == 0)
- {
- /* Root can read or write any file. */
- if (mode != X_OK)
- return (0);
-
- /* Root can execute any file that has any one of the execute
- bits set. */
- if (st.st_mode & S_IXUGO)
- return (0);
- }
-
- if (st.st_uid == current_user.euid) /* owner */
- mode <<= 6;
- else if (group_member (st.st_gid))
- mode <<= 3;
-
- if (st.st_mode & mode)
- return (0);
-
- errno = EACCES;
- return (-1);
-}
-
/* Increment our position in the argument list. Check that we're not
past the end of the argument list. This check is supressed if the
argument is FALSE. Made a macro for efficiency. */
@@ -394,12 +295,12 @@ filecomp (s, t, op)
struct stat st1, st2;
int r1, r2;
- if ((r1 = test_stat (s, &st1)) < 0)
+ if ((r1 = sh_stat (s, &st1)) < 0)
{
if (op == EF)
return (FALSE);
}
- if ((r2 = test_stat (t, &st2)) < 0)
+ if ((r2 = sh_stat (t, &st2)) < 0)
{
if (op == EF)
return (FALSE);
@@ -597,31 +498,31 @@ unary_test (op, arg)
{
case 'a': /* file exists in the file system? */
case 'e':
- return (test_stat (arg, &stat_buf) == 0);
+ return (sh_stat (arg, &stat_buf) == 0);
case 'r': /* file is readable? */
- return (EACCESS (arg, R_OK) == 0);
+ return (sh_eaccess (arg, R_OK) == 0);
case 'w': /* File is writeable? */
- return (EACCESS (arg, W_OK) == 0);
+ return (sh_eaccess (arg, W_OK) == 0);
case 'x': /* File is executable? */
- return (EACCESS (arg, X_OK) == 0);
+ return (sh_eaccess (arg, X_OK) == 0);
case 'O': /* File is owned by you? */
- return (test_stat (arg, &stat_buf) == 0 &&
+ return (sh_stat (arg, &stat_buf) == 0 &&
(uid_t) current_user.euid == (uid_t) stat_buf.st_uid);
case 'G': /* File is owned by your group? */
- return (test_stat (arg, &stat_buf) == 0 &&
+ return (sh_stat (arg, &stat_buf) == 0 &&
(gid_t) current_user.egid == (gid_t) stat_buf.st_gid);
case 'N':
- return (test_stat (arg, &stat_buf) == 0 &&
+ return (sh_stat (arg, &stat_buf) == 0 &&
stat_buf.st_atime <= stat_buf.st_mtime);
case 'f': /* File is a file? */
- if (test_stat (arg, &stat_buf) < 0)
+ if (sh_stat (arg, &stat_buf) < 0)
return (FALSE);
/* -f is true if the given file exists and is a regular file. */
@@ -632,29 +533,29 @@ unary_test (op, arg)
#endif /* !S_IFMT */
case 'd': /* File is a directory? */
- return (test_stat (arg, &stat_buf) == 0 && (S_ISDIR (stat_buf.st_mode)));
+ return (sh_stat (arg, &stat_buf) == 0 && (S_ISDIR (stat_buf.st_mode)));
case 's': /* File has something in it? */
- return (test_stat (arg, &stat_buf) == 0 && stat_buf.st_size > (off_t) 0);
+ return (sh_stat (arg, &stat_buf) == 0 && stat_buf.st_size > (off_t) 0);
case 'S': /* File is a socket? */
#if !defined (S_ISSOCK)
return (FALSE);
#else
- return (test_stat (arg, &stat_buf) == 0 && S_ISSOCK (stat_buf.st_mode));
+ return (sh_stat (arg, &stat_buf) == 0 && S_ISSOCK (stat_buf.st_mode));
#endif /* S_ISSOCK */
case 'c': /* File is character special? */
- return (test_stat (arg, &stat_buf) == 0 && S_ISCHR (stat_buf.st_mode));
+ return (sh_stat (arg, &stat_buf) == 0 && S_ISCHR (stat_buf.st_mode));
case 'b': /* File is block special? */
- return (test_stat (arg, &stat_buf) == 0 && S_ISBLK (stat_buf.st_mode));
+ return (sh_stat (arg, &stat_buf) == 0 && S_ISBLK (stat_buf.st_mode));
case 'p': /* File is a named pipe? */
#ifndef S_ISFIFO
return (FALSE);
#else
- return (test_stat (arg, &stat_buf) == 0 && S_ISFIFO (stat_buf.st_mode));
+ return (sh_stat (arg, &stat_buf) == 0 && S_ISFIFO (stat_buf.st_mode));
#endif /* S_ISFIFO */
case 'L': /* Same as -h */
@@ -667,17 +568,17 @@ unary_test (op, arg)
#endif /* S_IFLNK && HAVE_LSTAT */
case 'u': /* File is setuid? */
- return (test_stat (arg, &stat_buf) == 0 && (stat_buf.st_mode & S_ISUID) != 0);
+ return (sh_stat (arg, &stat_buf) == 0 && (stat_buf.st_mode & S_ISUID) != 0);
case 'g': /* File is setgid? */
- return (test_stat (arg, &stat_buf) == 0 && (stat_buf.st_mode & S_ISGID) != 0);
+ return (sh_stat (arg, &stat_buf) == 0 && (stat_buf.st_mode & S_ISGID) != 0);
case 'k': /* File has sticky bit set? */
#if !defined (S_ISVTX)
/* This is not Posix, and is not defined on some Posix systems. */
return (FALSE);
#else
- return (test_stat (arg, &stat_buf) == 0 && (stat_buf.st_mode & S_ISVTX) != 0);
+ return (sh_stat (arg, &stat_buf) == 0 && (stat_buf.st_mode & S_ISVTX) != 0);
#endif
case 't': /* File fd is a terminal? */