summaryrefslogtreecommitdiffstats
path: root/bin/test
diff options
context:
space:
mode:
authorsjg <sjg@FreeBSD.org>2013-09-05 20:18:59 +0000
committersjg <sjg@FreeBSD.org>2013-09-05 20:18:59 +0000
commit62bb1062226d3ce6a2350808256a25508978352d (patch)
tree22b131dceb13c3df96da594fbaadb693504797c7 /bin/test
parent72ab90509b3a51ab361bf710338f2ef44a4e360d (diff)
parent04932445481c2cb89ff69a83b961bdef3d64757e (diff)
downloadFreeBSD-src-62bb1062226d3ce6a2350808256a25508978352d.zip
FreeBSD-src-62bb1062226d3ce6a2350808256a25508978352d.tar.gz
Merge from head
Diffstat (limited to 'bin/test')
-rw-r--r--bin/test/test.187
-rw-r--r--bin/test/test.c184
2 files changed, 55 insertions, 216 deletions
diff --git a/bin/test/test.1 b/bin/test/test.1
index 76a4a9c..136ee57 100644
--- a/bin/test/test.1
+++ b/bin/test/test.1
@@ -32,7 +32,7 @@
.\" @(#)test.1 8.1 (Berkeley) 5/31/93
.\" $FreeBSD$
.\"
-.Dd December 27, 2012
+.Dd June 1, 2013
.Dt TEST 1
.Os
.Sh NAME
@@ -169,65 +169,15 @@ True if
.Ar file
exists and is a socket.
.It Ar file1 Fl nt Ar file2
-True if both
-.Ar file1
-and
-.Ar file2
-exist and
-.Ar file1
-is newer than
-.Ar file2 .
-.It Ar file1 Fl nt Ns Ar X Ns Ar Y Ar file2
-True if both
-.Ar file1
-and
-.Ar file2
-exist and
+True if
.Ar file1
-has a more recent last access time
-.Pq Ar X Ns = Ns Cm a ,
-inode creation time
-.Pq Ar X Ns = Ns Cm b ,
-change time
-.Pq Ar X Ns = Ns Cm c ,
-or modification time
-.Pq Ar X Ns = Ns Cm m
-than the last access time
-.Pq Ar Y Ns = Ns Cm a ,
-inode creation time
-.Pq Ar Y Ns = Ns Cm b ,
-change time
-.Pq Ar Y Ns = Ns Cm c ,
-or modification time
-.Pq Ar Y Ns = Ns Cm m
-of
+exists and is newer than
.Ar file2 .
-Note that
-.Ic -ntmm
-is equivalent to
-.Ic -nt .
.It Ar file1 Fl ot Ar file2
-True if both
-.Ar file1
-and
-.Ar file2
-exist and
+True if
.Ar file1
-is older than
+exists and is older than
.Ar file2 .
-Note that
-.Ar file1
-.Ic -ot
-.Ar file2
-is equivalent to
-.Ar file2
-.Ic -nt
-.Ar file1
-.It Ar file1 Fl ot Ns Ar X Ns Ar Y Ar file2
-Equivalent to
-.Ar file2
-.Ic -nt Ns Ar Y Ns Ar X
-.Ar file1 .
.It Ar file1 Fl ef Ar file2
True if
.Ar file1
@@ -381,6 +331,20 @@ 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
@@ -391,7 +355,9 @@ 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
@@ -399,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 eaa2f40..96aa9f5 100644
--- a/bin/test/test.c
+++ b/bin/test/test.c
@@ -63,7 +63,7 @@ error(const char *msg, ...)
"-u"|"-g"|"-k"|"-s"|"-t"|"-z"|"-n"|"-o"|"-O"|"-G"|"-L"|"-S";
binary-operator ::= "="|"!="|"-eq"|"-ne"|"-ge"|"-gt"|"-le"|"-lt"|
- "-nt"|"-nt[abcm][abcm]"|"-ot"|"-ot[abcm][abcm])"|"-ef";
+ "-nt"|"-ot"|"-ef";
operand ::= <any legal UNIX file name>
*/
@@ -85,38 +85,8 @@ enum token {
FILSUID,
FILSGID,
FILSTCK,
- FILNTAA,
- FILNTAB,
- FILNTAC,
- FILNTAM,
- FILNTBA,
- FILNTBB,
- FILNTBC,
- FILNTBM,
- FILNTCA,
- FILNTCB,
- FILNTCC,
- FILNTCM,
- FILNTMA,
- FILNTMB,
- FILNTMC,
- FILNTMM,
- FILOTAA,
- FILOTAB,
- FILOTAC,
- FILOTAM,
- FILOTBA,
- FILOTBB,
- FILOTBC,
- FILOTBM,
- FILOTCA,
- FILOTCB,
- FILOTCC,
- FILOTCM,
- FILOTMA,
- FILOTMB,
- FILOTMC,
- FILOTMM,
+ FILNT,
+ FILOT,
FILEQ,
FILUID,
FILGID,
@@ -148,16 +118,9 @@ enum token_types {
PAREN
};
-enum time_types {
- ATIME,
- BTIME,
- CTIME,
- MTIME
-};
-
static struct t_op {
- char op_text[6];
- char op_num, op_type;
+ char op_text[4];
+ short op_num, op_type;
} const ops [] = {
{"-r", FILRD, UNOP},
{"-w", FILWR, UNOP},
@@ -191,40 +154,8 @@ static struct t_op {
{"-gt", INTGT, BINOP},
{"-le", INTLE, BINOP},
{"-lt", INTLT, BINOP},
- {"-nt", FILNTMM, BINOP},
- {"-ntaa", FILNTAA, BINOP},
- {"-ntab", FILNTAB, BINOP},
- {"-ntac", FILNTAC, BINOP},
- {"-ntam", FILNTAM, BINOP},
- {"-ntba", FILNTBA, BINOP},
- {"-ntbb", FILNTBB, BINOP},
- {"-ntbc", FILNTBC, BINOP},
- {"-ntbm", FILNTBM, BINOP},
- {"-ntca", FILNTCA, BINOP},
- {"-ntcb", FILNTCB, BINOP},
- {"-ntcc", FILNTCC, BINOP},
- {"-ntcm", FILNTCM, BINOP},
- {"-ntma", FILNTMA, BINOP},
- {"-ntmb", FILNTMB, BINOP},
- {"-ntmc", FILNTMC, BINOP},
- {"-ntmm", FILNTMM, BINOP},
- {"-ot", FILOTMM, BINOP},
- {"-otaa", FILOTAA, BINOP},
- {"-otab", FILOTBB, BINOP},
- {"-otac", FILOTAC, BINOP},
- {"-otam", FILOTAM, BINOP},
- {"-otba", FILOTBA, BINOP},
- {"-otbb", FILOTBB, BINOP},
- {"-otbc", FILOTBC, BINOP},
- {"-otbm", FILOTBM, BINOP},
- {"-otca", FILOTCA, BINOP},
- {"-otcb", FILOTCB, BINOP},
- {"-otcc", FILOTCC, BINOP},
- {"-otcm", FILOTCM, BINOP},
- {"-otma", FILOTMA, BINOP},
- {"-otmb", FILOTMB, BINOP},
- {"-otmc", FILOTMC, BINOP},
- {"-otmm", FILOTMM, BINOP},
+ {"-nt", FILNT, BINOP},
+ {"-ot", FILOT, BINOP},
{"-ef", FILEQ, BINOP},
{"!", UNOT, BUNOP},
{"-a", BAND, BBINOP},
@@ -249,10 +180,10 @@ static int intcmp(const char *, const char *);
static int isunopoperand(void);
static int islparenoperand(void);
static int isrparenoperand(void);
-static int newerf(const char *, const char *, enum time_types,
- enum time_types);
+static int newerf(const char *, const char *);
static int nexpr(enum token);
static int oexpr(enum token);
+static int olderf(const char *, const char *);
static int primary(enum token);
static void syntax(const char *, const char *);
static enum token t_lex(char *);
@@ -422,70 +353,10 @@ binop(void)
return intcmp(opnd1, opnd2) <= 0;
case INTLT:
return intcmp(opnd1, opnd2) < 0;
- case FILNTAA:
- return newerf(opnd1, opnd2, ATIME, ATIME);
- case FILNTAB:
- return newerf(opnd1, opnd2, ATIME, BTIME);
- case FILNTAC:
- return newerf(opnd1, opnd2, ATIME, CTIME);
- case FILNTAM:
- return newerf(opnd1, opnd2, ATIME, MTIME);
- case FILNTBA:
- return newerf(opnd1, opnd2, BTIME, ATIME);
- case FILNTBB:
- return newerf(opnd1, opnd2, BTIME, BTIME);
- case FILNTBC:
- return newerf(opnd1, opnd2, BTIME, CTIME);
- case FILNTBM:
- return newerf(opnd1, opnd2, BTIME, MTIME);
- case FILNTCA:
- return newerf(opnd1, opnd2, CTIME, ATIME);
- case FILNTCB:
- return newerf(opnd1, opnd2, CTIME, BTIME);
- case FILNTCC:
- return newerf(opnd1, opnd2, CTIME, CTIME);
- case FILNTCM:
- return newerf(opnd1, opnd2, CTIME, MTIME);
- case FILNTMA:
- return newerf(opnd1, opnd2, MTIME, ATIME);
- case FILNTMB:
- return newerf(opnd1, opnd2, MTIME, BTIME);
- case FILNTMC:
- return newerf(opnd1, opnd2, MTIME, CTIME);
- case FILNTMM:
- return newerf(opnd1, opnd2, MTIME, MTIME);
- case FILOTAA:
- return newerf(opnd2, opnd1, ATIME, ATIME);
- case FILOTAB:
- return newerf(opnd2, opnd1, BTIME, ATIME);
- case FILOTAC:
- return newerf(opnd2, opnd1, CTIME, ATIME);
- case FILOTAM:
- return newerf(opnd2, opnd1, MTIME, ATIME);
- case FILOTBA:
- return newerf(opnd2, opnd1, ATIME, BTIME);
- case FILOTBB:
- return newerf(opnd2, opnd1, BTIME, BTIME);
- case FILOTBC:
- return newerf(opnd2, opnd1, CTIME, BTIME);
- case FILOTBM:
- return newerf(opnd2, opnd1, MTIME, BTIME);
- case FILOTCA:
- return newerf(opnd2, opnd1, ATIME, CTIME);
- case FILOTCB:
- return newerf(opnd2, opnd1, BTIME, CTIME);
- case FILOTCC:
- return newerf(opnd2, opnd1, CTIME, CTIME);
- case FILOTCM:
- return newerf(opnd2, opnd1, MTIME, CTIME);
- case FILOTMA:
- return newerf(opnd2, opnd1, ATIME, MTIME);
- case FILOTMB:
- return newerf(opnd2, opnd1, BTIME, MTIME);
- case FILOTMC:
- return newerf(opnd2, opnd1, CTIME, MTIME);
- case FILOTMM:
- return newerf(opnd2, opnd1, MTIME, MTIME);
+ case FILNT:
+ return newerf (opnd1, opnd2);
+ case FILOT:
+ return olderf (opnd1, opnd2);
case FILEQ:
return equalf (opnd1, opnd2);
default:
@@ -699,34 +570,25 @@ intcmp (const char *s1, const char *s2)
}
static int
-newerf (const char *f1, const char *f2, enum time_types t1, enum time_types t2)
+newerf (const char *f1, const char *f2)
{
struct stat b1, b2;
- struct timespec *ts1, *ts2;
if (stat(f1, &b1) != 0 || stat(f2, &b2) != 0)
return 0;
- switch (t1) {
- case ATIME: ts1 = &b1.st_atim; break;
- case BTIME: ts1 = &b1.st_birthtim; break;
- case CTIME: ts1 = &b1.st_ctim; break;
- default: ts1 = &b1.st_mtim; break;
- }
-
- switch (t2) {
- case ATIME: ts2 = &b2.st_atim; break;
- case BTIME: ts2 = &b2.st_birthtim; break;
- case CTIME: ts2 = &b2.st_ctim; break;
- default: ts2 = &b2.st_mtim; break;
- }
-
- if (ts1->tv_sec > ts2->tv_sec)
+ if (b1.st_mtim.tv_sec > b2.st_mtim.tv_sec)
return 1;
- if (ts1->tv_sec < ts2->tv_sec)
+ if (b1.st_mtim.tv_sec < b2.st_mtim.tv_sec)
return 0;
- return (ts1->tv_nsec > ts2->tv_nsec);
+ return (b1.st_mtim.tv_nsec > b2.st_mtim.tv_nsec);
+}
+
+static int
+olderf (const char *f1, const char *f2)
+{
+ return (newerf(f2, f1));
}
static int
OpenPOWER on IntegriCloud