]> sourceware.org Git - newlib-cygwin.git/blame - winsup/cygwin/tzcode/localtime_wrapper.c
Cygwin: sigfe: Fix a bug that signal handler destroys fpu states
[newlib-cygwin.git] / winsup / cygwin / tzcode / localtime_wrapper.c
CommitLineData
63ff2b84
MG
1/* localtime.cc: Wrapper of NetBSD tzcode support for Cygwin. See README file.
2
3This file is part of Cygwin.
4
5This software is a copyrighted work licensed under the terms of the
6Cygwin license. Please consult the file "CYGWIN_LICENSE" for
7details. */
8
49a843b4
CV
9#include "winsup.h"
10#include "perprocess.h"
63ff2b84 11#include "tz_posixrules.h"
49a843b4
CV
12#include <cygwin/version.h>
13#include <stdlib.h>
7ed95200 14#include <sys/_tz_structs.h>
63ff2b84 15
49a843b4 16static NO_COPY SRWLOCK tzset_guard = SRWLOCK_INIT;
63ff2b84 17
49a843b4
CV
18// Convert these NetBSD rwlock ops into SRWLocks
19#define rwlock_wrlock(X) AcquireSRWLockExclusive(&tzset_guard)
20#define rwlock_unlock(X) ReleaseSRWLockExclusive(&tzset_guard)
63ff2b84
MG
21
22// Set these NetBSD-related option #defines appropriately for Cygwin
23//#define STD_INSPIRED // early-include private.h below does this
24#define lint
25#define HAVE_POSIX_DECLS 0
26#define USG_COMPAT 1
27#define NO_ERROR_IN_DST_GAP
28#define state __state
29
30// Turn a specific known kind of const parameter into non-const
31#define __UNCONST(X) ((char *) (X))
32
33// Turn off these NetBSD audit-related definitions
34#define __aconst
35#define _DIAGASSERT(X)
36
37// Supply this Cygwin-specific function in advance of its use in localtime.c
38static char *
39tzgetwintzi (char *wildabbr, char *outbuf)
40{
41 TIME_ZONE_INFORMATION tzi;
42 char *cp, *dst;
43 wchar_t *wsrc;
44 div_t d;
45
46 GetTimeZoneInformation (&tzi);
47 dst = cp = outbuf;
48 for (wsrc = tzi.StandardName; *wsrc; wsrc++)
49 if (*wsrc >= L'A' && *wsrc <= L'Z')
50 *dst++ = *wsrc;
51 if ((dst - cp) < 3)
52 {
53 /* In non-english Windows, converted tz.StandardName
54 may not contain a valid standard timezone name. */
55 strcpy (cp, wildabbr);
56 cp += strlen (wildabbr);
57 }
58 else
59 cp = dst;
60 d = div (tzi.Bias + tzi.StandardBias, 60);
61 __small_sprintf (cp, "%d", d.quot);
62 if (d.rem)
63 __small_sprintf (cp = strchr (cp, 0), ":%d", abs (d.rem));
64 if (tzi.StandardDate.wMonth)
65 {
66 cp = strchr (cp, 0);
67 dst = cp;
68 for (wsrc = tzi.DaylightName; *wsrc; wsrc++)
69 if (*wsrc >= L'A' && *wsrc <= L'Z')
70 *dst++ = *wsrc;
71 if ((dst - cp) < 3)
72 {
73 /* In non-english Windows, converted tz.DaylightName
74 may not contain a valid daylight timezone name. */
75 strcpy (cp, wildabbr);
76 cp += strlen (wildabbr);
77 }
78 else
79 cp = dst;
80 d = div (tzi.Bias + tzi.DaylightBias, 60);
81 __small_sprintf (cp, "%d", d.quot);
82 if (d.rem)
83 __small_sprintf (cp = strchr (cp, 0), ":%d", abs (d.rem));
84 cp = strchr (cp, 0);
85 __small_sprintf (cp = strchr (cp, 0), ",M%d.%d.%d/%d",
86 tzi.DaylightDate.wMonth,
87 tzi.DaylightDate.wDay,
88 tzi.DaylightDate.wDayOfWeek,
89 tzi.DaylightDate.wHour);
90 if (tzi.DaylightDate.wMinute || tzi.DaylightDate.wSecond)
91 __small_sprintf (cp = strchr (cp, 0), ":%d",
92 tzi.DaylightDate.wMinute);
93 if (tzi.DaylightDate.wSecond)
94 __small_sprintf (cp = strchr (cp, 0), ":%d",
95 tzi.DaylightDate.wSecond);
96 cp = strchr (cp, 0);
97 __small_sprintf (cp = strchr (cp, 0), ",M%d.%d.%d/%d",
98 tzi.StandardDate.wMonth,
99 tzi.StandardDate.wDay,
100 tzi.StandardDate.wDayOfWeek,
101 tzi.StandardDate.wHour);
102 if (tzi.StandardDate.wMinute || tzi.StandardDate.wSecond)
103 __small_sprintf (cp = strchr (cp, 0), ":%d",
104 tzi.StandardDate.wMinute);
105 if (tzi.StandardDate.wSecond)
106 __small_sprintf (cp = strchr (cp, 0), ":%d",
107 tzi.StandardDate.wSecond);
108 }
109 /* __small_printf ("TZ deduced as `%s'\n", outbuf); */
110 return outbuf;
111}
112
63ff2b84
MG
113// Pull these in early to catch any small issues before the real test
114#include "private.h"
115#include "tzfile.h"
116
117/* Some NetBSD differences were too difficult to work around..
118 so #include a patched copy of localtime.c rather than the NetBSD original.
119 Here is a list of the patches...
120 (1) fix an erroneous decl of tzdirslash size (flagged by g++)
121 (2) add conditional call to Cygwin's tzgetwintzi() from tzsetlcl()
122 (3) add Cygwin's historical "posixrules" support to tzloadbody()
123*/
4d5efe1e 124#include "localtime.patched.c"
63ff2b84 125
63ff2b84 126// Don't forget these Cygwin-specific additions from this point to EOF
63ff2b84 127
49a843b4 128long
63ff2b84
MG
129__cygwin_gettzoffset (const struct tm *tmp)
130{
131#ifdef TM_GMTOFF
132 if (CYGWIN_VERSION_CHECK_FOR_EXTRA_TM_MEMBERS)
49a843b4 133 return tmp->TM_GMTOFF;
63ff2b84
MG
134#endif /* defined TM_GMTOFF */
135 __tzinfo_type *tz = __gettzinfo ();
136 /* The sign of this is exactly opposite the envvar TZ. We
137 could directly use the global _timezone for tm_isdst==0,
138 but have to use __tzrule for daylight savings. */
139 long offset = -tz->__tzrule[tmp->tm_isdst > 0].offset;
140 return offset;
141}
142
49a843b4 143const char *
63ff2b84
MG
144__cygwin_gettzname (const struct tm *tmp)
145{
146#ifdef TM_ZONE
147 if (CYGWIN_VERSION_CHECK_FOR_EXTRA_TM_MEMBERS)
148 return tmp->TM_ZONE;
149#endif
150 return _tzname[tmp->tm_isdst > 0];
151}
f2010ed7
CV
152
153EXPORT_ALIAS (tzset_unlocked, _tzset_unlocked)
This page took 0.126269 seconds and 6 git commands to generate.