Blame gl/gettimeofday.c

Packit 549fdc
/* Provide gettimeofday for systems that don't have it or for which it's broken.
Packit 549fdc
Packit 549fdc
   Copyright (C) 2001-2003, 2005-2007, 2009-2016 Free Software Foundation, Inc.
Packit 549fdc
Packit 549fdc
   This program is free software; you can redistribute it and/or modify
Packit 549fdc
   it under the terms of the GNU Lesser General Public License as published by
Packit 549fdc
   the Free Software Foundation; either version 2.1, or (at your option)
Packit 549fdc
   any later version.
Packit 549fdc
Packit 549fdc
   This program is distributed in the hope that it will be useful,
Packit 549fdc
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 549fdc
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 549fdc
   GNU Lesser General Public License for more details.
Packit 549fdc
Packit 549fdc
   You should have received a copy of the GNU Lesser General Public License
Packit 549fdc
   along with this program; if not, see <http://www.gnu.org/licenses/>.  */
Packit 549fdc
Packit 549fdc
/* written by Jim Meyering */
Packit 549fdc
Packit 549fdc
#include <config.h>
Packit 549fdc
Packit 549fdc
/* Specification.  */
Packit 549fdc
#include <sys/time.h>
Packit 549fdc
Packit 549fdc
#include <time.h>
Packit 549fdc
Packit 549fdc
#if HAVE_SYS_TIMEB_H
Packit 549fdc
# include <sys/timeb.h>
Packit 549fdc
#endif
Packit 549fdc
Packit 549fdc
#if GETTIMEOFDAY_CLOBBERS_LOCALTIME || TZSET_CLOBBERS_LOCALTIME
Packit 549fdc
Packit 549fdc
/* Work around the bug in some systems whereby gettimeofday clobbers
Packit 549fdc
   the static buffer that localtime uses for its return value.  The
Packit 549fdc
   gettimeofday function from Mac OS X 10.0.4 (i.e., Darwin 1.3.7) has
Packit 549fdc
   this problem.  The tzset replacement is necessary for at least
Packit 549fdc
   Solaris 2.5, 2.5.1, and 2.6.  */
Packit 549fdc
Packit 549fdc
static struct tm tm_zero_buffer;
Packit 549fdc
static struct tm *localtime_buffer_addr = &tm_zero_buffer;
Packit 549fdc
Packit 549fdc
# undef localtime
Packit 549fdc
extern struct tm *localtime (time_t const *);
Packit 549fdc
Packit 549fdc
# undef gmtime
Packit 549fdc
extern struct tm *gmtime (time_t const *);
Packit 549fdc
Packit 549fdc
/* This is a wrapper for localtime.  It is used only on systems for which
Packit 549fdc
   gettimeofday clobbers the static buffer used for localtime's result.
Packit 549fdc
Packit 549fdc
   On the first call, record the address of the static buffer that
Packit 549fdc
   localtime uses for its result.  */
Packit 549fdc
Packit 549fdc
struct tm *
Packit 549fdc
rpl_localtime (time_t const *timep)
Packit 549fdc
{
Packit 549fdc
  struct tm *tm = localtime (timep);
Packit 549fdc
Packit 549fdc
  if (localtime_buffer_addr == &tm_zero_buffer)
Packit 549fdc
    localtime_buffer_addr = tm;
Packit 549fdc
Packit 549fdc
  return tm;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
/* Same as above, since gmtime and localtime use the same buffer.  */
Packit 549fdc
struct tm *
Packit 549fdc
rpl_gmtime (time_t const *timep)
Packit 549fdc
{
Packit 549fdc
  struct tm *tm = gmtime (timep);
Packit 549fdc
Packit 549fdc
  if (localtime_buffer_addr == &tm_zero_buffer)
Packit 549fdc
    localtime_buffer_addr = tm;
Packit 549fdc
Packit 549fdc
  return tm;
Packit 549fdc
}
Packit 549fdc
Packit 549fdc
#endif /* GETTIMEOFDAY_CLOBBERS_LOCALTIME || TZSET_CLOBBERS_LOCALTIME */
Packit 549fdc
Packit 549fdc
#if TZSET_CLOBBERS_LOCALTIME
Packit 549fdc
Packit 549fdc
# undef tzset
Packit 549fdc
extern void tzset (void);
Packit 549fdc
Packit 549fdc
/* This is a wrapper for tzset, for systems on which tzset may clobber
Packit 549fdc
   the static buffer used for localtime's result.  */
Packit 549fdc
void
Packit 549fdc
rpl_tzset (void)
Packit 549fdc
{
Packit 549fdc
  /* Save and restore the contents of the buffer used for localtime's
Packit 549fdc
     result around the call to tzset.  */
Packit 549fdc
  struct tm save = *localtime_buffer_addr;
Packit 549fdc
  tzset ();
Packit 549fdc
  *localtime_buffer_addr = save;
Packit 549fdc
}
Packit 549fdc
#endif
Packit 549fdc
Packit 549fdc
/* This is a wrapper for gettimeofday.  It is used only on systems
Packit 549fdc
   that lack this function, or whose implementation of this function
Packit 549fdc
   causes problems.  */
Packit 549fdc
Packit 549fdc
int
Packit 549fdc
gettimeofday (struct timeval *restrict tv, void *restrict tz)
Packit 549fdc
{
Packit 549fdc
#undef gettimeofday
Packit 549fdc
#if HAVE_GETTIMEOFDAY
Packit 549fdc
# if GETTIMEOFDAY_CLOBBERS_LOCALTIME
Packit 549fdc
  /* Save and restore the contents of the buffer used for localtime's
Packit 549fdc
     result around the call to gettimeofday.  */
Packit 549fdc
  struct tm save = *localtime_buffer_addr;
Packit 549fdc
# endif
Packit 549fdc
Packit 549fdc
# if defined timeval /* 'struct timeval' overridden by gnulib?  */
Packit 549fdc
#  undef timeval
Packit 549fdc
  struct timeval otv;
Packit 549fdc
  int result = gettimeofday (&otv, (struct timezone *) tz);
Packit 549fdc
  if (result == 0)
Packit 549fdc
    {
Packit 549fdc
      tv->tv_sec = otv.tv_sec;
Packit 549fdc
      tv->tv_usec = otv.tv_usec;
Packit 549fdc
    }
Packit 549fdc
# else
Packit 549fdc
  int result = gettimeofday (tv, (struct timezone *) tz);
Packit 549fdc
# endif
Packit 549fdc
Packit 549fdc
# if GETTIMEOFDAY_CLOBBERS_LOCALTIME
Packit 549fdc
  *localtime_buffer_addr = save;
Packit 549fdc
# endif
Packit 549fdc
Packit 549fdc
  return result;
Packit 549fdc
Packit 549fdc
#else
Packit 549fdc
Packit 549fdc
# if HAVE__FTIME
Packit 549fdc
Packit 549fdc
  struct _timeb timebuf;
Packit 549fdc
  _ftime (&timebuf);
Packit 549fdc
  tv->tv_sec = timebuf.time;
Packit 549fdc
  tv->tv_usec = timebuf.millitm * 1000;
Packit 549fdc
Packit 549fdc
# else
Packit 549fdc
Packit 549fdc
#  if !defined OK_TO_USE_1S_CLOCK
Packit 549fdc
#   error "Only 1-second nominal clock resolution found.  Is that intended?" \
Packit 549fdc
          "If so, compile with the -DOK_TO_USE_1S_CLOCK option."
Packit 549fdc
#  endif
Packit 549fdc
  tv->tv_sec = time (NULL);
Packit 549fdc
  tv->tv_usec = 0;
Packit 549fdc
Packit 549fdc
# endif
Packit 549fdc
Packit 549fdc
  return 0;
Packit 549fdc
Packit 549fdc
#endif
Packit 549fdc
}