1 /* $NetBSD: timecmp.c,v 1.2 2017/02/14 01:16:49 christos Exp $ */
2
3 /*++
4 /* NAME
5 /* timecmp 3
6 /* SUMMARY
7 /* compare two time_t values
8 /* SYNOPSIS
9 /* #include <timecmp.h>
10 /*
11 /* int timecmp(t1, t2)
12 /* time_t t1;
13 /* time_t t2;
14 /* DESCRIPTION
15 /* The timecmp() function return an integer greater than, equal to, or
16 /* less than 0, according as the time t1 is greater than, equal to, or
17 /* less than the time t2. The comparison is made in a manner that is
18 /* insensitive to clock wrap-around, provided the underlying times are
19 /* within half of the time interval between the smallest and largest
20 /* representable time values.
21 /* LICENSE
22 /* .ad
23 /* .fi
24 /* The Secure Mailer license must be distributed with this software.
25 /* AUTHOR(S)
26 /* Wietse Venema
27 /* IBM T.J. Watson Research
28 /* P.O. Box 704
29 /* Yorktown Heights, NY 10598, USA
30 /*
31 /* Viktor Dukhovni
32 /*--*/
33
34 #include "timecmp.h"
35
36 /* timecmp - wrap-safe time_t comparison */
37
timecmp(time_t t1,time_t t2)38 int timecmp(time_t t1, time_t t2)
39 {
40 time_t delta = t1 - t2;
41
42 if (delta == 0)
43 return 0;
44
45 #define UNSIGNED(type) ( ((type)-1) > ((type)0) )
46
47 /*
48 * With a constant switch value, the compiler will emit only the code for
49 * the correct case, so the signed/unsigned test happens at compile time.
50 */
51 switch (UNSIGNED(time_t) ? 0 : 1) {
52 case 0:
53 return ((2 * delta > delta) ? 1 : -1);
54 case 1:
55 return ((delta > (time_t) 0) ? 1 : -1);
56 }
57 }
58
59 #ifdef TEST
60 #include <assert.h>
61
62 /*
63 * Bit banging!! There is no official constant that defines the INT_MAX
64 * equivalent of the off_t type. Wietse came up with the following macro
65 * that works as long as off_t is some two's complement number.
66 *
67 * Note, however, that C99 permits signed integer representations other than
68 * two's complement.
69 */
70 #include <limits.h>
71 #define __MAXINT__(T) ((T) (((((T) 1) << ((sizeof(T) * CHAR_BIT) - 1)) ^ ((T) -1))))
72
main(void)73 int main(void)
74 {
75 time_t now = time((time_t *) 0);
76
77 /* Test that it works for normal times */
78 assert(timecmp(now + 10, now) > 0);
79 assert(timecmp(now, now) == 0);
80 assert(timecmp(now - 10, now) < 0);
81
82 /* Test that it works at a boundary time */
83 if (UNSIGNED(time_t))
84 now = (time_t) -1;
85 else
86 now = __MAXINT__(time_t);
87
88 assert(timecmp(now + 10, now) > 0);
89 assert(timecmp(now, now) == 0);
90 assert(timecmp(now - 10, now) < 0);
91
92 return (0);
93 }
94
95 #endif
96