/* * 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 # include #else /* TIME_WITH_SYS_TIME */ # if HAVE_SYS_TIME_H # include # else # include # 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 */