line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#include "EXTERN.h" |
2
|
|
|
|
|
|
|
#include "perl.h" |
3
|
|
|
|
|
|
|
#include "XSUB.h" |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
#include "ppport.h" |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
#include |
8
|
|
|
|
|
|
|
#include |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
#define TIME_STRING_SIZE 26 |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
/* thanks to Michael Schout's Env::C module, this solves problem with FreeBSD */ |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
/* in order to work around system and perl implementation bugs/leaks, we need |
17
|
|
|
|
|
|
|
* to sometimes force PERL_USE_SAFE_PUTENV mode. |
18
|
|
|
|
|
|
|
*/ |
19
|
|
|
|
|
|
|
#ifndef PERL_USE_SAFE_PUTENV |
20
|
|
|
|
|
|
|
# if PERL_BCDVERSION >= 0x5009004 && defined(USE_ITHREADS) && defined(PERL_TRACK_MEMPOOL) |
21
|
|
|
|
|
|
|
# define USE_SAFE_PUTENV 1 |
22
|
|
|
|
|
|
|
# elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) |
23
|
|
|
|
|
|
|
# define USE_SAFE_PUTENV 1 |
24
|
|
|
|
|
|
|
# endif |
25
|
|
|
|
|
|
|
#endif |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
#ifdef USE_SAFE_PUTENV |
28
|
|
|
|
|
|
|
# define SAFE_PUTENV_ON() PL_use_safe_putenv = 1; |
29
|
|
|
|
|
|
|
#else |
30
|
|
|
|
|
|
|
# define SAFE_PUTENV_ON() |
31
|
|
|
|
|
|
|
#endif |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
#ifdef sun |
34
|
|
|
|
|
|
|
#define asctime_r(a, b) asctime_r(a, b, TIME_STRING_SIZE) |
35
|
|
|
|
|
|
|
#endif |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
#ifdef WIN32 |
38
|
|
|
|
|
|
|
#define setenv(name, value, flag) _putenv_s(name, value) |
39
|
|
|
|
|
|
|
#define unsetenv(name) _putenv_s(name, "") |
40
|
|
|
|
|
|
|
#define localtime_r(time, tm) localtime_s(tm, time) |
41
|
|
|
|
|
|
|
#define asctime_r(tm, time_string) asctime_s(time_string, TIME_STRING_SIZE, tm) |
42
|
|
|
|
|
|
|
#define gmtime_r(time, tm) gmtime_s(tm, time) |
43
|
|
|
|
|
|
|
#endif |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
#define BACKUP_TZ() \ |
46
|
|
|
|
|
|
|
SAFE_PUTENV_ON(); \ |
47
|
|
|
|
|
|
|
char* old_tz_p = getenv("TZ"); \ |
48
|
|
|
|
|
|
|
int envsize = old_tz_p == NULL ? 1 : strlen(old_tz_p)+1; \ |
49
|
|
|
|
|
|
|
char old_tz[envsize]; \ |
50
|
|
|
|
|
|
|
if (old_tz_p != NULL) \ |
51
|
|
|
|
|
|
|
memcpy(old_tz, old_tz_p, envsize); \ |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
#define RESTORE_TZ() \ |
54
|
|
|
|
|
|
|
if (old_tz_p == NULL) { \ |
55
|
|
|
|
|
|
|
unsetenv("TZ"); \ |
56
|
|
|
|
|
|
|
} else { \ |
57
|
|
|
|
|
|
|
setenv("TZ", old_tz, 1); \ |
58
|
|
|
|
|
|
|
} \ |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
MODULE = Time::Local::TZ PACKAGE = Time::Local::TZ |
62
|
|
|
|
|
|
|
PROTOTYPES: DISABLE |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
void |
65
|
|
|
|
|
|
|
tz_localtime(tz, time) |
66
|
|
|
|
|
|
|
char* tz |
67
|
|
|
|
|
|
|
time_t time |
68
|
|
|
|
|
|
|
PREINIT: |
69
|
|
|
|
|
|
|
char time_string[TIME_STRING_SIZE]; |
70
|
|
|
|
|
|
|
struct tm tm; |
71
|
|
|
|
|
|
|
PPCODE: |
72
|
32
|
100
|
|
|
|
|
BACKUP_TZ(); |
|
|
100
|
|
|
|
|
|
73
|
32
|
|
|
|
|
|
setenv("TZ", tz, 1); |
74
|
32
|
|
|
|
|
|
tzset(); |
75
|
32
|
|
|
|
|
|
localtime_r(&time, &tm); |
76
|
32
|
100
|
|
|
|
|
RESTORE_TZ(); |
77
|
|
|
|
|
|
|
|
78
|
32
|
50
|
|
|
|
|
if (GIMME_V == G_ARRAY) { |
|
|
100
|
|
|
|
|
|
79
|
16
|
50
|
|
|
|
|
EXTEND(SP, 9); |
80
|
16
|
|
|
|
|
|
ST(0) = sv_2mortal(newSViv(tm.tm_sec)); |
81
|
16
|
|
|
|
|
|
ST(1) = sv_2mortal(newSViv(tm.tm_min)); |
82
|
16
|
|
|
|
|
|
ST(2) = sv_2mortal(newSViv(tm.tm_hour)); |
83
|
16
|
|
|
|
|
|
ST(3) = sv_2mortal(newSViv(tm.tm_mday)); |
84
|
16
|
|
|
|
|
|
ST(4) = sv_2mortal(newSViv(tm.tm_mon)); |
85
|
16
|
|
|
|
|
|
ST(5) = sv_2mortal(newSViv(tm.tm_year)); |
86
|
16
|
|
|
|
|
|
ST(6) = sv_2mortal(newSViv(tm.tm_wday)); |
87
|
16
|
|
|
|
|
|
ST(7) = sv_2mortal(newSViv(tm.tm_yday)); |
88
|
16
|
|
|
|
|
|
ST(8) = sv_2mortal(newSViv(tm.tm_isdst)); |
89
|
16
|
|
|
|
|
|
XSRETURN(9); |
90
|
|
|
|
|
|
|
} else { |
91
|
16
|
|
|
|
|
|
asctime_r(&tm, time_string); |
92
|
16
|
|
|
|
|
|
ST(0) = sv_2mortal(newSVpv(time_string, 24)); |
93
|
32
|
|
|
|
|
|
XSRETURN(1); |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
void |
98
|
|
|
|
|
|
|
tz_timelocal(...) |
99
|
|
|
|
|
|
|
PREINIT: |
100
|
|
|
|
|
|
|
char* tz; |
101
|
|
|
|
|
|
|
struct tm tm; |
102
|
|
|
|
|
|
|
time_t time; |
103
|
|
|
|
|
|
|
PPCODE: |
104
|
24
|
100
|
|
|
|
|
if (items < 7 || items > 10) |
|
|
100
|
|
|
|
|
|
105
|
8
|
|
|
|
|
|
croak("Usage: tz_timelocal(tz, sec, min, hour, mday, mon, year, [ wday, yday, is_dst ])"); |
106
|
|
|
|
|
|
|
|
107
|
16
|
50
|
|
|
|
|
tz = SvPV_nolen(ST(0)); |
108
|
16
|
50
|
|
|
|
|
tm.tm_sec = SvIV(ST(1)); |
109
|
16
|
50
|
|
|
|
|
tm.tm_min = SvIV(ST(2)); |
110
|
16
|
50
|
|
|
|
|
tm.tm_hour = SvIV(ST(3)); |
111
|
16
|
50
|
|
|
|
|
tm.tm_mday = SvIV(ST(4)); |
112
|
16
|
50
|
|
|
|
|
tm.tm_mon = SvIV(ST(5)); |
113
|
16
|
50
|
|
|
|
|
tm.tm_year = SvIV(ST(6)); |
114
|
16
|
|
|
|
|
|
tm.tm_wday = -1; |
115
|
16
|
|
|
|
|
|
tm.tm_yday = -1; |
116
|
16
|
|
|
|
|
|
tm.tm_isdst = -1; |
117
|
|
|
|
|
|
|
|
118
|
16
|
100
|
|
|
|
|
BACKUP_TZ(); |
|
|
100
|
|
|
|
|
|
119
|
16
|
|
|
|
|
|
setenv("TZ", tz, 1); |
120
|
16
|
|
|
|
|
|
tzset(); |
121
|
16
|
|
|
|
|
|
time = mktime(&tm); |
122
|
16
|
100
|
|
|
|
|
RESTORE_TZ(); |
123
|
|
|
|
|
|
|
|
124
|
16
|
|
|
|
|
|
ST(0) = sv_2mortal(newSViv((IV)time)); |
125
|
16
|
|
|
|
|
|
XSRETURN(1); |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
void |
129
|
|
|
|
|
|
|
tz_truncate(tz, time, unit) |
130
|
|
|
|
|
|
|
char* tz |
131
|
|
|
|
|
|
|
time_t time |
132
|
|
|
|
|
|
|
int unit |
133
|
|
|
|
|
|
|
PREINIT: |
134
|
|
|
|
|
|
|
struct tm tm; |
135
|
|
|
|
|
|
|
PPCODE: |
136
|
64
|
100
|
|
|
|
|
if (unit < 1 || unit > 5) |
|
|
100
|
|
|
|
|
|
137
|
4
|
|
|
|
|
|
croak("Usage: tz_truncate(tz, time, unit), unit should be 1..5"); |
138
|
|
|
|
|
|
|
|
139
|
60
|
100
|
|
|
|
|
BACKUP_TZ(); |
|
|
100
|
|
|
|
|
|
140
|
60
|
|
|
|
|
|
setenv("TZ", tz, 1); |
141
|
60
|
|
|
|
|
|
tzset(); |
142
|
60
|
|
|
|
|
|
localtime_r(&time, &tm); |
143
|
60
|
100
|
|
|
|
|
if (unit == 5) tm.tm_mon = 0; |
144
|
60
|
100
|
|
|
|
|
if (unit >= 4) tm.tm_mday = 1; |
145
|
60
|
100
|
|
|
|
|
if (unit >= 3) tm.tm_hour = 0; |
146
|
60
|
100
|
|
|
|
|
if (unit >= 2) tm.tm_min = 0; |
147
|
60
|
50
|
|
|
|
|
if (unit >= 1) tm.tm_sec = 0; |
148
|
60
|
|
|
|
|
|
time = mktime(&tm); |
149
|
60
|
100
|
|
|
|
|
RESTORE_TZ(); |
150
|
|
|
|
|
|
|
|
151
|
60
|
|
|
|
|
|
ST(0) = sv_2mortal(newSViv((IV)time)); |
152
|
60
|
|
|
|
|
|
XSRETURN(1); |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
void |
156
|
|
|
|
|
|
|
tz_offset(tz, time) |
157
|
|
|
|
|
|
|
char* tz |
158
|
|
|
|
|
|
|
time_t time |
159
|
|
|
|
|
|
|
PREINIT: |
160
|
|
|
|
|
|
|
struct tm tm; |
161
|
|
|
|
|
|
|
time_t time_utc; |
162
|
|
|
|
|
|
|
PPCODE: |
163
|
7
|
50
|
|
|
|
|
BACKUP_TZ() |
|
|
50
|
|
|
|
|
|
164
|
7
|
|
|
|
|
|
setenv("TZ", tz, 1); |
165
|
7
|
|
|
|
|
|
tzset(); |
166
|
7
|
|
|
|
|
|
gmtime_r(&time, &tm); |
167
|
7
|
|
|
|
|
|
time_utc = mktime(&tm); |
168
|
7
|
50
|
|
|
|
|
RESTORE_TZ(); |
169
|
|
|
|
|
|
|
|
170
|
7
|
|
|
|
|
|
ST(0) = sv_2mortal(newSViv((int)(time-time_utc))); |
171
|
7
|
|
|
|
|
|
XSRETURN(1); |