annotate src/lib/utc-mktime.c @ 22664:fea53c2725c0

director: Fix director_max_parallel_moves/kicks type Should be uint, not time.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Thu, 09 Nov 2017 12:24:16 +0200
parents c4584d7dc07e
children cb108f786fb4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
21390
2e2563132d5f Updated copyright notices to include the year 2017.
Stephan Bosch <stephan.bosch@dovecot.fi>
parents: 20037
diff changeset
1 /* Copyright (c) 2007-2017 Dovecot authors, see the included COPYING file */
492
efa46e28a0d7 Fixes to timezone handling which were handling quite badly. added
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
2
1658
20519e4bca48 utc_mktime() crashed with 64bit time_t if gmtime() didn't like >32bit values
Timo Sirainen <tss@iki.fi>
parents: 493
diff changeset
3 #include "lib.h"
492
efa46e28a0d7 Fixes to timezone handling which were handling quite badly. added
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
4 #include "utc-mktime.h"
efa46e28a0d7 Fixes to timezone handling which were handling quite badly. added
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
5
6483
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
6 static int tm_cmp(const struct tm *tm1, const struct tm *tm2)
492
efa46e28a0d7 Fixes to timezone handling which were handling quite badly. added
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
7 {
6483
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
8 int diff;
492
efa46e28a0d7 Fixes to timezone handling which were handling quite badly. added
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
9
6483
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
10 if ((diff = tm1->tm_year - tm2->tm_year) != 0)
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
11 return diff;
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
12 if ((diff = tm1->tm_mon - tm2->tm_mon) != 0)
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
13 return diff;
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
14 if ((diff = tm1->tm_mday - tm2->tm_mday) != 0)
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
15 return diff;
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
16 if ((diff = tm1->tm_hour - tm2->tm_hour) != 0)
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
17 return diff;
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
18 if ((diff = tm1->tm_min - tm2->tm_min) != 0)
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
19 return diff;
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
20 return tm1->tm_sec - tm2->tm_sec;
492
efa46e28a0d7 Fixes to timezone handling which were handling quite badly. added
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
21 }
efa46e28a0d7 Fixes to timezone handling which were handling quite badly. added
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
22
21661
c4584d7dc07e lib: Accept leap second in utc_mktime
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents: 21390
diff changeset
23 static inline void adjust_leap_second(struct tm *tm)
c4584d7dc07e lib: Accept leap second in utc_mktime
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents: 21390
diff changeset
24 {
c4584d7dc07e lib: Accept leap second in utc_mktime
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents: 21390
diff changeset
25 if (tm->tm_sec == 60)
c4584d7dc07e lib: Accept leap second in utc_mktime
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents: 21390
diff changeset
26 tm->tm_sec = 59;
c4584d7dc07e lib: Accept leap second in utc_mktime
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents: 21390
diff changeset
27 }
c4584d7dc07e lib: Accept leap second in utc_mktime
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents: 21390
diff changeset
28
20037
c27f1eac85b7 lib: Implement utc_mktime() with timegm() if it exists.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
29 #ifdef HAVE_TIMEGM
21661
c4584d7dc07e lib: Accept leap second in utc_mktime
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents: 21390
diff changeset
30 /* Normalization done by timegm is considered a failure here, since it means
c4584d7dc07e lib: Accept leap second in utc_mktime
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents: 21390
diff changeset
31 * the timestamp is not valid as-is. Leap second 60 is adjusted to 59 before
c4584d7dc07e lib: Accept leap second in utc_mktime
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents: 21390
diff changeset
32 * this though. */
20037
c27f1eac85b7 lib: Implement utc_mktime() with timegm() if it exists.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
33 time_t utc_mktime(const struct tm *tm)
c27f1eac85b7 lib: Implement utc_mktime() with timegm() if it exists.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
34 {
21661
c4584d7dc07e lib: Accept leap second in utc_mktime
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents: 21390
diff changeset
35 struct tm leap_adj_tm = *tm;
c4584d7dc07e lib: Accept leap second in utc_mktime
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents: 21390
diff changeset
36 adjust_leap_second(&leap_adj_tm);
c4584d7dc07e lib: Accept leap second in utc_mktime
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents: 21390
diff changeset
37 struct tm tmp = leap_adj_tm;
20037
c27f1eac85b7 lib: Implement utc_mktime() with timegm() if it exists.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
38 time_t t;
c27f1eac85b7 lib: Implement utc_mktime() with timegm() if it exists.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
39
21661
c4584d7dc07e lib: Accept leap second in utc_mktime
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents: 21390
diff changeset
40 t = timegm(&tmp);
c4584d7dc07e lib: Accept leap second in utc_mktime
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents: 21390
diff changeset
41 if (tm_cmp(&leap_adj_tm, &tmp) != 0)
20037
c27f1eac85b7 lib: Implement utc_mktime() with timegm() if it exists.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
42 return (time_t)-1;
c27f1eac85b7 lib: Implement utc_mktime() with timegm() if it exists.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
43 return t;
c27f1eac85b7 lib: Implement utc_mktime() with timegm() if it exists.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
44 }
c27f1eac85b7 lib: Implement utc_mktime() with timegm() if it exists.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
45 #else
6483
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
46 time_t utc_mktime(const struct tm *tm)
492
efa46e28a0d7 Fixes to timezone handling which were handling quite badly. added
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
47 {
21661
c4584d7dc07e lib: Accept leap second in utc_mktime
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents: 21390
diff changeset
48 struct tm leap_adj_tm = *tm;
c4584d7dc07e lib: Accept leap second in utc_mktime
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents: 21390
diff changeset
49 adjust_leap_second(&leap_adj_tm);
6483
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
50 const struct tm *try_tm;
6597
7b5b3b0c7002 Fix to 64bit time_t
Timo Sirainen <tss@iki.fi>
parents: 6584
diff changeset
51 time_t t;
6483
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
52 int bits, dir;
492
efa46e28a0d7 Fixes to timezone handling which were handling quite badly. added
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
53
6483
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
54 /* we'll do a binary search across the entire valid time_t range.
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
55 when gmtime()'s output matches the tm parameter, we've found the
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
56 correct time_t value. this also means that if tm contains invalid
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
57 values, -1 is returned. */
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
58 #ifdef TIME_T_SIGNED
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
59 t = 0;
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
60 #else
14669
6411d91d0755 Fixed signed integer shift overflows.
Timo Sirainen <tss@iki.fi>
parents: 14133
diff changeset
61 t = (time_t)1 << (TIME_T_MAX_BITS - 1);
6483
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
62 #endif
6584
4fb613eb8ce9 utc_mktime() was broken with 32bit time_t. Also don't try to optimize away
Timo Sirainen <tss@iki.fi>
parents: 6483
diff changeset
63 for (bits = TIME_T_MAX_BITS - 2;; bits--) {
6483
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
64 try_tm = gmtime(&t);
21661
c4584d7dc07e lib: Accept leap second in utc_mktime
Martti Rannanjärvi <martti.rannanjarvi@dovecot.fi>
parents: 21390
diff changeset
65 dir = tm_cmp(&leap_adj_tm, try_tm);
6483
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
66 if (dir == 0)
6584
4fb613eb8ce9 utc_mktime() was broken with 32bit time_t. Also don't try to optimize away
Timo Sirainen <tss@iki.fi>
parents: 6483
diff changeset
67 return t;
6483
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
68 if (bits < 0)
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
69 break;
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
70
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
71 if (dir < 0)
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
72 t -= (time_t)1 << bits;
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
73 else
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
74 t += (time_t)1 << bits;
492
efa46e28a0d7 Fixes to timezone handling which were handling quite badly. added
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
75 }
6483
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
76
6d15946eccb5 Rewrote utc_mktime() so it's now MIT licensed. This also fixes handling
Timo Sirainen <tss@iki.fi>
parents: 1741
diff changeset
77 return (time_t)-1;
492
efa46e28a0d7 Fixes to timezone handling which were handling quite badly. added
Timo Sirainen <tss@iki.fi>
parents:
diff changeset
78 }
20037
c27f1eac85b7 lib: Implement utc_mktime() with timegm() if it exists.
Timo Sirainen <timo.sirainen@dovecot.fi>
parents: 19552
diff changeset
79 #endif