Blame lib/tzset.c

Packit 33f14e
/* Provide tzset for systems that don't have it or for which it's broken.
Packit 33f14e
Packit 33f14e
   Copyright (C) 2001-2003, 2005-2007, 2009-2017 Free Software Foundation, Inc.
Packit 33f14e
Packit 33f14e
   This program is free software; you can redistribute it and/or modify
Packit 33f14e
   it under the terms of the GNU General Public License as published by
Packit 33f14e
   the Free Software Foundation; either version 3, or (at your option)
Packit 33f14e
   any later version.
Packit 33f14e
Packit 33f14e
   This program is distributed in the hope that it will be useful,
Packit 33f14e
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 33f14e
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 33f14e
   GNU General Public License for more details.
Packit 33f14e
Packit 33f14e
   You should have received a copy of the GNU General Public License
Packit 33f14e
   along with this program; if not, see <http://www.gnu.org/licenses/>.  */
Packit 33f14e
Packit 33f14e
/* written by Jim Meyering */
Packit 33f14e
Packit 33f14e
#include <config.h>
Packit 33f14e
Packit 33f14e
/* Specification.  */
Packit 33f14e
#include <time.h>
Packit 33f14e
Packit 33f14e
#include "localtime-buffer.h"
Packit 33f14e
Packit 33f14e
/* This is a wrapper for tzset, for systems on which tzset may clobber
Packit 33f14e
   the static buffer used for localtime's result.
Packit 33f14e
   Work around the bug in some systems whereby tzset clobbers the
Packit 33f14e
   static buffer that localtime uses for its return value.  The
Packit 33f14e
   tzset function from Solaris 2.5, 2.5.1, and 2.6 has this problem.  */
Packit 33f14e
Packit 33f14e
void
Packit 33f14e
tzset (void)
Packit 33f14e
#undef tzset
Packit 33f14e
{
Packit 33f14e
#if TZSET_CLOBBERS_LOCALTIME
Packit 33f14e
  /* Save and restore the contents of the buffer used for localtime's
Packit 33f14e
     result around the call to tzset.  */
Packit 33f14e
  struct tm save = *localtime_buffer_addr;
Packit 33f14e
#endif
Packit 33f14e
Packit 33f14e
#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
Packit 33f14e
  /* Rectify the value of the environment variable TZ.
Packit 33f14e
     There are four possible kinds of such values:
Packit 33f14e
       - Traditional US time zone names, e.g. "PST8PDT".  Syntax: see
Packit 33f14e
         <https://msdn.microsoft.com/en-us/library/90s5c885.aspx>
Packit 33f14e
       - Time zone names based on geography, that contain one or more
Packit 33f14e
         slashes, e.g. "Europe/Moscow".
Packit 33f14e
       - Time zone names based on geography, without slashes, e.g.
Packit 33f14e
         "Singapore".
Packit 33f14e
       - Time zone names that contain explicit DST rules.  Syntax: see
Packit 33f14e
         <http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03>
Packit 33f14e
     The Microsoft CRT understands only the first kind.  It produces incorrect
Packit 33f14e
     results if the value of TZ is of the other kinds.
Packit 33f14e
     But in a Cygwin environment, /etc/profile.d/tzset.sh sets TZ to a value
Packit 33f14e
     of the second kind for most geographies, or of the first kind in a few
Packit 33f14e
     other geographies.  If it is of the second kind, neutralize it.  For the
Packit 33f14e
     Microsoft CRT, an absent or empty TZ means the time zone that the user
Packit 33f14e
     has set in the Windows Control Panel.
Packit 33f14e
     If the value of TZ is of the third or fourth kind -- Cygwin programs
Packit 33f14e
     understand these syntaxes as well --, it does not matter whether we
Packit 33f14e
     neutralize it or not, since these values occur only when a Cygwin user
Packit 33f14e
     has set TZ explicitly; this case is 1. rare and 2. under the user's
Packit 33f14e
     responsibility.  */
Packit 33f14e
  const char *tz = getenv ("TZ");
Packit 33f14e
  if (tz != NULL && strchr (tz, '/') != NULL)
Packit 33f14e
    _putenv ("TZ=");
Packit 33f14e
Packit 33f14e
  /* On native Windows, tzset() is deprecated.  Use _tzset() instead.  See
Packit 33f14e
     https://msdn.microsoft.com/en-us/library/ms235451.aspx
Packit 33f14e
     https://msdn.microsoft.com/en-us/library/90s5c885.aspx  */
Packit 33f14e
  _tzset ();
Packit 33f14e
#elif HAVE_TZSET
Packit 33f14e
  tzset ();
Packit 33f14e
#else
Packit 33f14e
  /* Do nothing.  Avoid infinite recursion.  */
Packit 33f14e
#endif
Packit 33f14e
Packit 33f14e
#if TZSET_CLOBBERS_LOCALTIME
Packit 33f14e
  *localtime_buffer_addr = save;
Packit 33f14e
#endif
Packit 33f14e
}