Blame lib/tzset.c

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