1135446Strhodes/*
2193149Sdougb * Copyright (C) 2004, 2005, 2007  Internet Systems Consortium, Inc. ("ISC")
3135446Strhodes * Copyright (C) 1999-2001  Internet Software Consortium.
4135446Strhodes *
5193149Sdougb * Permission to use, copy, modify, and/or distribute this software for any
6135446Strhodes * purpose with or without fee is hereby granted, provided that the above
7135446Strhodes * copyright notice and this permission notice appear in all copies.
8135446Strhodes *
9135446Strhodes * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10135446Strhodes * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11135446Strhodes * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12135446Strhodes * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13135446Strhodes * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14135446Strhodes * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15135446Strhodes * PERFORMANCE OF THIS SOFTWARE.
16135446Strhodes */
17135446Strhodes
18234010Sdougb/* $Id: stdtime.c,v 1.19 2007/06/19 23:47:18 tbox Exp $ */
19135446Strhodes
20170222Sdougb/*! \file */
21170222Sdougb
22135446Strhodes#include <config.h>
23135446Strhodes
24153816Sdougb#include <stddef.h>	/* NULL */
25135446Strhodes#include <stdlib.h>	/* NULL */
26135446Strhodes#include <syslog.h>
27135446Strhodes
28135446Strhodes#include <sys/time.h>
29135446Strhodes
30135446Strhodes#include <isc/stdtime.h>
31135446Strhodes#include <isc/util.h>
32135446Strhodes
33135446Strhodes#ifndef ISC_FIX_TV_USEC
34135446Strhodes#define ISC_FIX_TV_USEC 1
35135446Strhodes#endif
36135446Strhodes
37135446Strhodes#define US_PER_S 1000000
38135446Strhodes
39135446Strhodes#if ISC_FIX_TV_USEC
40135446Strhodesstatic inline void
41135446Strhodesfix_tv_usec(struct timeval *tv) {
42135446Strhodes	isc_boolean_t fixed = ISC_FALSE;
43135446Strhodes
44135446Strhodes	if (tv->tv_usec < 0) {
45135446Strhodes		fixed = ISC_TRUE;
46135446Strhodes		do {
47135446Strhodes			tv->tv_sec -= 1;
48135446Strhodes			tv->tv_usec += US_PER_S;
49135446Strhodes		} while (tv->tv_usec < 0);
50135446Strhodes	} else if (tv->tv_usec >= US_PER_S) {
51135446Strhodes		fixed = ISC_TRUE;
52135446Strhodes		do {
53135446Strhodes			tv->tv_sec += 1;
54135446Strhodes			tv->tv_usec -= US_PER_S;
55135446Strhodes		} while (tv->tv_usec >=US_PER_S);
56135446Strhodes	}
57135446Strhodes	/*
58135446Strhodes	 * Call syslog directly as we are called from the logging functions.
59135446Strhodes	 */
60135446Strhodes	if (fixed)
61135446Strhodes		(void)syslog(LOG_ERR, "gettimeofday returned bad tv_usec: corrected");
62135446Strhodes}
63135446Strhodes#endif
64135446Strhodes
65135446Strhodesvoid
66135446Strhodesisc_stdtime_get(isc_stdtime_t *t) {
67135446Strhodes	struct timeval tv;
68135446Strhodes
69135446Strhodes	/*
70135446Strhodes	 * Set 't' to the number of seconds since 00:00:00 UTC, January 1,
71135446Strhodes	 * 1970.
72135446Strhodes	 */
73135446Strhodes
74135446Strhodes	REQUIRE(t != NULL);
75135446Strhodes
76135446Strhodes	RUNTIME_CHECK(gettimeofday(&tv, NULL) != -1);
77135446Strhodes
78135446Strhodes#if ISC_FIX_TV_USEC
79135446Strhodes	fix_tv_usec(&tv);
80135446Strhodes	INSIST(tv.tv_usec >= 0);
81135446Strhodes#else
82135446Strhodes	INSIST(tv.tv_usec >= 0 && tv.tv_usec < US_PER_S);
83135446Strhodes#endif
84135446Strhodes
85135446Strhodes	*t = (unsigned int)tv.tv_sec;
86135446Strhodes}
87