/*
* Copyright (c) 2002-2005 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*
* $Id: time.h,v 1.23 2006/12/10 20:55:59 ca Exp $
*/
#ifndef SM_TIME_H
#define SM_TIME_H 1
#include "sm/generic.h"
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else /* TIME_WITH_SYS_TIME */
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif /* TIME_WITH_SYS_TIME */
/* required by arpadate() prototype */
#include "sm/str.h"
/* should be defined in sys/time.h */
#ifndef timersub
# define timersub(tvp, uvp, res) \
do \
{ \
(res)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
(res)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
if ((res)->tv_usec < 0) \
{ \
(res)->tv_sec--; \
(res)->tv_usec += 1000000; \
} \
} while (0)
#endif /* ! timersub */
#ifndef timeradd
# define timeradd(tvp, uvp, res) \
do \
{ \
(res)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \
(res)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \
if ((res)->tv_usec >= 1000000) \
{ \
(res)->tv_sec++; \
(res)->tv_usec -= 1000000; \
} \
} while (0)
#endif /* ! timeradd */
#ifndef timercmp
# define timercmp(tvp, uvp, cmp) \
(((tvp)->tv_sec == (uvp)->tv_sec) ? \
((tvp)->tv_usec cmp (uvp)->tv_usec) : \
((tvp)->tv_sec cmp (uvp)->tv_sec))
#endif /* ! timercmp */
/* some people are clueless and define this without do { } while (0) */
#define SM_TIMEVAL_TO_TIMESPEC(tv, ts) \
do { \
(ts)->tv_sec = (tv)->tv_sec; \
(ts)->tv_nsec = (tv)->tv_usec * 1000; \
} while (0)
#define SM_TIMESPEC_TO_TIMEVAL(tv, ts) \
do { \
(tv)->tv_sec = (ts)->tv_sec; \
(tv)->tv_usec = (ts)->tv_nsec / 1000; \
} while (0)
#ifndef timespecclear
# define timespecclear(tsp) (tsp)->tv_sec = (tsp)->tv_nsec = 0
#endif
#ifndef timespeccmp
# define timespeccmp(tvp, uvp, cmp) \
(((tvp)->tv_sec == (uvp)->tv_sec) ? \
((tvp)->tv_nsec cmp (uvp)->tv_nsec) : \
((tvp)->tv_sec cmp (uvp)->tv_sec))
#endif
/* FreeBSD and OpenBSD don't agree on number of arguments... */
#define sm_timespecadd(tsp, usp, res) \
do { \
(res)->tv_sec = (tsp)->tv_sec + (usp)->tv_sec; \
(res)->tv_nsec = (tsp)->tv_nsec + (usp)->tv_nsec; \
if ((res)->tv_nsec >= 1000000000L) { \
(res)->tv_sec++; \
(res)->tv_nsec -= 1000000000L; \
} \
} while (0)
#define sm_timespecsub(tsp, usp, res) \
do { \
(res)->tv_sec = (tsp)->tv_sec - (usp)->tv_sec; \
(res)->tv_nsec = (tsp)->tv_nsec - (usp)->tv_nsec; \
if ((res)->tv_nsec < 0) { \
(res)->tv_sec--; \
(res)->tv_nsec += 1000000000L; \
} \
} while (0)
typedef struct timeval timeval_T, *timeval_P;
typedef time_t time_T;
typedef struct timespec timespec_T, *timespec_P;
/* fixme: rename this to something more intuitive! */
#define NULLT ((time_T *)0)
#if SIZEOF_TIME_T == 4
# define TIME_T_MAX ((time_T)INT_MAX)
#elif SIZEOF_TIME_T == 8
# define TIME_T_MAX ((time_T)LONG_MAX)
#else
oops _SIZEOF_TIME_T is neither 4 nor 8
#endif /* SIZEOF_TIME_T == 4 */
#define sm_usleep(s, us, tv) ( \
tv.tv_sec = (s), \
tv.tv_usec = (us), \
select(0, NULL, NULL, NULL, &tv) \
)
#define SEC2USEC(s) ((s)*1000000LL)
#define SEC2NSEC(s) ((s)*1000000000LL)
#if HAVE_GETHRTIME
# define MTA_NS_TIME(ns) ns = gethrtime()
#elif HAVE_CLOCK_GETTIME
# ifndef CLOCK_MONOTONIC
# define CLOCK_MONOTONIC CLOCK_REALTIME
#endif
# define MTA_NS_TIME(ns) do { \
struct timespec tsr; \
(void) clock_gettime(CLOCK_MONOTONIC, &tsr); \
ns = SEC2NSEC((uint64_t)tsr.tv_sec) + (uint64_t)tsr.tv_nsec; \
} while (0)
#endif
sm_ret_T arpadate(time_t *_when, sm_str_P _udate);
#if HAVE_STRPTIME && NEED_STRPTIME_PROTO
char *strptime(const char *_s, const char *_format, struct tm *_tm);
#endif
#endif /* SM_TIME_H */
syntax highlighted by Code2HTML, v. 0.9.1