Imported from ../bash-3.2.tar.gz.

This commit is contained in:
Jari Aalto
2009-09-12 16:46:58 +00:00
parent 95732b497d
commit 0628567a28
182 changed files with 17647 additions and 9477 deletions
+20 -119
View File
@@ -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? */