Blame lib/tzset.c

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