From d5d041ece235f50adad3e086550555d7201f43b9 Mon Sep 17 00:00:00 2001 From: Peter Avalos Date: Tue, 30 Jul 2013 21:07:10 -0700 Subject: [PATCH] test: Sync with FreeBSD. * Add examples and non-standard primaries to the manual page. * Reduce code size of ops table. * Put some static keywords in the source code. * Accept == as an alias of = which is a popular GNU extension. * Add more regression tests. -We have eaccess(2) now, so use it. Obtained-from: FreeBSD --- bin/test/Makefile | 2 +- bin/test/test.1 | 53 ++++++++++++++++++++++++------- bin/test/test.c | 51 +++++++++++++----------------- tools/regression/bin/test/Makefile | 2 +- tools/regression/bin/test/regress.sh | 61 +++++++++++++++++++++++++++++------- tools/regression/bin/test/regress.t | 2 +- 6 files changed, 115 insertions(+), 56 deletions(-) diff --git a/bin/test/Makefile b/bin/test/Makefile index 60b0c976c5..101f78b9d5 100644 --- a/bin/test/Makefile +++ b/bin/test/Makefile @@ -4,7 +4,7 @@ PROG= test LINKS= ${BINDIR}/test ${BINDIR}/[ -MLINKS= test.1 '[.1' +MLINKS= test.1 [.1 regress: test cd ${.CURDIR}/../../tools/regression/bin/test && \ diff --git a/bin/test/test.1 b/bin/test/test.1 index e3f88c6d11..e0e2e0b41b 100644 --- a/bin/test/test.1 +++ b/bin/test/test.1 @@ -30,9 +30,9 @@ .\" SUCH DAMAGE. .\" .\" @(#)test.1 8.1 (Berkeley) 5/31/93 -.\" $FreeBSD: src/bin/test/test.1,v 1.31 2010/09/11 10:49:56 brucec Exp $ +.\" $FreeBSD: head/bin/test/test.1 251211 2013-05-31 22:57:04Z jilles $ .\" -.Dd September 10, 2010 +.Dd June 1, 2013 .Dt TEST 1 .Os .Sh NAME @@ -52,7 +52,8 @@ to true, returns a zero (true) exit status; otherwise it returns 1 (false). If there is no expression, .Nm -also returns 1 (false). +also +returns 1 (false). .Pp All operators and flags are separate arguments to the .Nm @@ -133,15 +134,9 @@ True if .Ar file exists and is writable. True -indicates both that the write flag is on and that -.Ar file -resides on a read-write file system. -.Pp -Note that this behaviour is specific to -.Dx . -When writing portable scripts, keep in mind that -on some systems, this test may -indicate only that the write flag is on. +indicates only that the write flag is on. +The file is not writable on a read-only file +system even if this test indicates true. .It Fl x Ar file True if .Ar file @@ -336,10 +331,33 @@ missing. .It >1 An error occurred. .El +.Sh EXAMPLES +Implement +.Li test FILE1 -nt FILE2 +using only +.Tn POSIX +functionality: +.Pp +.Dl test -n \&"$(find -L -- FILE1 -prune -newer FILE2 2>/dev/null)\&" +.Pp +This can be modified using non-standard +.Xr find 1 +primaries like +.Cm -newerca +to compare other timestamps. +.Sh COMPATIBILITY +For compatibility with some other implementations, +the +.Cm = +primary can be substituted with +.Cm == +with the same meaning. .Sh SEE ALSO .Xr builtin 1 , .Xr expr 1 , +.Xr find 1 , .Xr sh 1 , +.Xr stat 1 , .Xr symlink 7 .Sh STANDARDS The @@ -347,6 +365,17 @@ The utility implements a superset of the .St -p1003.2 specification. +The primaries +.Cm < , +.Cm == , +.Cm > , +.Fl ef , +.Fl nt , +.Fl ot , +.Fl G , +and +.Fl O +are extensions. .Sh BUGS Both sides are always evaluated in .Fl a diff --git a/bin/test/test.c b/bin/test/test.c index 7f94685bce..e55e38c99d 100644 --- a/bin/test/test.c +++ b/bin/test/test.c @@ -9,7 +9,11 @@ * * This program is in the Public Domain. * - * $FreeBSD: src/bin/test/test.c,v 1.55 2010/03/28 13:16:08 ed Exp $ + * $FreeBSD: head/bin/test/test.c 251208 2013-05-31 22:54:20Z jilles $ + */ +/* + * Important: This file is used both as a standalone program /bin/test and + * as a builtin for /bin/sh (#define SHELL). */ #include @@ -115,8 +119,8 @@ enum token_types { PAREN }; -struct t_op { - const char *op_text; +static struct t_op { + char op_text[4]; short op_num, op_type; } const ops [] = { {"-r", FILRD, UNOP}, @@ -141,6 +145,7 @@ struct t_op { {"-L", FILSYM, UNOP}, {"-S", FILSOCK,UNOP}, {"=", STREQ, BINOP}, + {"==", STREQ, BINOP}, {"!=", STRNE, BINOP}, {"<", STRLT, BINOP}, {">", STRGT, BINOP}, @@ -158,13 +163,13 @@ struct t_op { {"-o", BOR, BBINOP}, {"(", LPAREN, PAREN}, {")", RPAREN, PAREN}, - {0, 0, 0} + {"", 0, 0} }; -struct t_op const *t_wp_op; -int nargc; -char **t_wp; -int parenlevel; +static struct t_op const *t_wp_op; +static int nargc; +static char **t_wp; +static int parenlevel; static int aexpr(enum token); static int binop(void); @@ -187,8 +192,6 @@ static enum token t_lex(char *); int main(int argc, char **argv) { - gid_t egid, gid; - uid_t euid, uid; int res; char *p; @@ -209,14 +212,6 @@ main(int argc, char **argv) #ifndef SHELL setlocale(LC_CTYPE, ""); #endif - /* XXX work around the absence of an eaccess(2) syscall */ - egid = getegid(); - euid = geteuid(); - gid = getgid(); - uid = getuid(); - setregid(egid, gid); - setreuid(euid, uid); - nargc = argc; t_wp = &argv[1]; parenlevel = 0; @@ -230,8 +225,6 @@ main(int argc, char **argv) if (--nargc > 0) syntax(*t_wp, "unexpected operator"); - setregid(gid, egid); - setreuid(uid, euid); return res; } @@ -383,18 +376,18 @@ filstat(char *nm, enum token mode) switch (mode) { case FILRD: - return access(nm, R_OK) == 0; + return (eaccess(nm, R_OK) == 0); case FILWR: - return access(nm, W_OK) == 0; + return (eaccess(nm, W_OK) == 0); case FILEX: - /* XXX work around access(2) false positives for superuser */ - if (access(nm, X_OK) != 0) + /* XXX work around eaccess(2) false positives for superuser */ + if (eaccess(nm, X_OK) != 0) return 0; - if (S_ISDIR(s.st_mode) || getuid() != 0) + if (S_ISDIR(s.st_mode) || geteuid() != 0) return 1; return (s.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) != 0; case FILEXIST: - return access(nm, F_OK) == 0; + return (eaccess(nm, F_OK) == 0); case FILREG: return S_ISREG(s.st_mode); case FILDIR: @@ -435,7 +428,7 @@ t_lex(char *s) t_wp_op = NULL; return EOI; } - while (op->op_text) { + while (*op->op_text) { if (strcmp(s, op->op_text) == 0) { if (((op->op_type == UNOP || op->op_type == BUNOP) && isunopoperand()) || @@ -464,7 +457,7 @@ isunopoperand(void) if (nargc == 2) return parenlevel == 1 && strcmp(s, ")") == 0; t = *(t_wp + 2); - while (op->op_text) { + while (*op->op_text) { if (strcmp(s, op->op_text) == 0) return op->op_type == BINOP && (parenlevel == 0 || t[0] != ')' || t[1] != '\0'); @@ -486,7 +479,7 @@ islparenoperand(void) return parenlevel == 1 && strcmp(s, ")") == 0; if (nargc != 3) return 0; - while (op->op_text) { + while (*op->op_text) { if (strcmp(s, op->op_text) == 0) return op->op_type == BINOP; op++; diff --git a/tools/regression/bin/test/Makefile b/tools/regression/bin/test/Makefile index 9ae580d217..80a64f4589 100644 --- a/tools/regression/bin/test/Makefile +++ b/tools/regression/bin/test/Makefile @@ -1,4 +1,4 @@ -# $FreeBSD: src/tools/regression/bin/test/Makefile,v 1.1 2010/11/08 23:15:10 jilles Exp $ +# $FreeBSD: head/tools/regression/bin/test/Makefile 215022 2010-11-08 23:15:10Z jilles $ TEST?= /bin/test diff --git a/tools/regression/bin/test/regress.sh b/tools/regression/bin/test/regress.sh index bcd69454b4..ba2fa3da13 100644 --- a/tools/regression/bin/test/regress.sh +++ b/tools/regression/bin/test/regress.sh @@ -2,7 +2,7 @@ #- # Copyright (c) June 1996 Wolfram Schneider . Berlin. -# All rights reserved. +# All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -28,10 +28,10 @@ # # TEST.sh - check if test(1) or builtin test works # -# $FreeBSD: src/tools/regression/bin/test/regress.sh,v 1.1 2010/11/08 23:15:10 jilles Exp $ +# $FreeBSD: head/tools/regression/bin/test/regress.sh 251208 2013-05-31 22:54:20Z jilles $ # force a specified test program, e.g. `env test=/bin/test sh regress.sh' -: ${test=test} +: ${test=test} t () { @@ -52,12 +52,15 @@ t () } count=0 -echo "1..94" - -t 0 'b = b' -t 1 'b != b' -t 0 '\( b = b \)' -t 1 '! \( b = b \)' +echo "1..130" + +t 0 'b = b' +t 0 'b == b' +t 1 'b != b' +t 0 '\( b = b \)' +t 0 '\( b == b \)' +t 1 '! \( b = b \)' +t 1 '! \( b == b \)' t 1 '! -f /etc/passwd' t 0 '-h = -h' @@ -135,8 +138,6 @@ t 1 '! = a' t 0 '! != -n' t 0 '! -c /etc/passwd' -t 0 '! \( = \)' -t 1 '! \( != \)' t 1 '! = = =' t 0 '! = = \)' t 0 '! "" -o ""' @@ -144,7 +145,6 @@ t 1 '! "x" -o ""' t 1 '! "" -o "x"' t 1 '! "x" -o "x"' t 0 '\( -f /etc/passwd \)' -t 1 '\( ! = \)' t 0 '\( ! "" \)' t 1 '\( ! -e \)' @@ -157,3 +157,40 @@ t 1 '-z y -o y = "#" -o y = x' t 0 '0 -ne 0 -o ! -f /' t 0 '1 -ne 0 -o ! -f /etc/passwd' t 1 '0 -ne 0 -o ! -f /etc/passwd' + +t 0 '-n =' +t 1 '-z =' +t 1 '! =' +t 0 '-n -eq' +t 1 '-z -eq' +t 1 '! -eq' +t 0 '-n -a' +t 1 '-z -a' +t 1 '! -a' +t 0 '-n -o' +t 1 '-z -o' +t 1 '! -o' +t 1 '! -n =' +t 0 '! -z =' +t 0 '! ! =' +t 1 '! -n -eq' +t 0 '! -z -eq' +t 0 '! ! -eq' +t 1 '! -n -a' +t 0 '! -z -a' +t 0 '! ! -a' +t 1 '! -n -o' +t 0 '! -z -o' +t 0 '! ! -o' +t 0 '\( -n = \)' +t 1 '\( -z = \)' +t 1 '\( ! = \)' +t 0 '\( -n -eq \)' +t 1 '\( -z -eq \)' +t 1 '\( ! -eq \)' +t 0 '\( -n -a \)' +t 1 '\( -z -a \)' +t 1 '\( ! -a \)' +t 0 '\( -n -o \)' +t 1 '\( -z -o \)' +t 1 '\( ! -o \)' diff --git a/tools/regression/bin/test/regress.t b/tools/regression/bin/test/regress.t index c6e981a5b4..53b3465554 100644 --- a/tools/regression/bin/test/regress.t +++ b/tools/regression/bin/test/regress.t @@ -1,5 +1,5 @@ #!/bin/sh -# $FreeBSD: src/tools/regression/bin/test/regress.t,v 1.1 2010/11/08 23:15:10 jilles Exp $ +# $FreeBSD: head/tools/regression/bin/test/regress.t 215022 2010-11-08 23:15:10Z jilles $ cd `dirname $0` -- 2.11.4.GIT