mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* win32/win32.c (gmtime_r, localtime_r): POSIX compliant reentrant
versions. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35348 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
72fffe5cee
commit
f2979f3101
5 changed files with 114 additions and 1 deletions
|
@ -1,4 +1,7 @@
|
|||
Mon Apr 16 16:08:18 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
Mon Apr 16 16:22:40 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* win32/win32.c (gmtime_r, localtime_r): POSIX compliant reentrant
|
||||
versions.
|
||||
|
||||
* configure.in (RUBY_MSVCRT_VERSION): define on mingw too.
|
||||
|
||||
|
|
|
@ -1089,6 +1089,7 @@ main()
|
|||
rb_cv_negative_time_t=no
|
||||
ac_cv_func_fcntl=yes
|
||||
ac_cv_func_flock=yes
|
||||
ac_cv_func_gmtime_r=yes
|
||||
rb_cv_large_fd_select=yes
|
||||
AC_LIBOBJ([langinfo])
|
||||
: ${enable_win95=maybe}
|
||||
|
|
|
@ -690,6 +690,9 @@ struct tms {
|
|||
|
||||
int rb_w32_times(struct tms *);
|
||||
|
||||
struct tm *gmtime_r(const time_t *, struct tm *);
|
||||
struct tm *localtime_r(const time_t *, struct tm *);
|
||||
|
||||
/* thread stuff */
|
||||
int rb_w32_sleep(unsigned long msec);
|
||||
int rb_w32_putc(int, FILE*);
|
||||
|
|
|
@ -651,6 +651,7 @@ $(CONFIG_H): $(MKFILES) $(srcdir)/win32/Makefile.sub $(win_srcdir)/Makefile.sub
|
|||
#define HAVE_SIGNBIT 1
|
||||
#define HAVE_TZNAME 1
|
||||
#define HAVE_DAYLIGHT 1
|
||||
#define HAVE_GMTIME_R 1
|
||||
#define SETPGRP_VOID 1
|
||||
#define RSHIFT(x,y) ((x)>>(int)y)
|
||||
#define HAVE_RB_FD_INIT 1
|
||||
|
|
105
win32/win32.c
105
win32/win32.c
|
@ -6257,3 +6257,108 @@ char
|
|||
rb_w32_fd_is_text(int fd) {
|
||||
return _osfile(fd) & FTEXT;
|
||||
}
|
||||
|
||||
#if RUBY_MSVCRT_VERSION < 80
|
||||
static int
|
||||
unixtime_to_systemtime(const time_t t, SYSTEMTIME *st)
|
||||
{
|
||||
FILETIME ft;
|
||||
if (unixtime_to_filetime(t, &ft)) return -1;
|
||||
if (!FileTimeToSystemTime(&ft, st)) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
systemtime_to_tm(const SYSTEMTIME *st, struct tm *t)
|
||||
{
|
||||
int y = st->wYear, m = st->wMonth, d = st->wDay;
|
||||
t->tm_sec = st->wSecond;
|
||||
t->tm_min = st->wMinute;
|
||||
t->tm_hour = st->wHour;
|
||||
t->tm_mday = st->wDay;
|
||||
t->tm_mon = st->wMonth - 1;
|
||||
t->tm_year = y - 1900;
|
||||
t->tm_wday = st->wDayOfWeek;
|
||||
switch (m) {
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
d += 31;
|
||||
break;
|
||||
default:
|
||||
d += 31 + 28 + (!(y % 4) && ((y % 100) || !(y % 400)));
|
||||
d += ((m - 3) * 153 + 2) / 5;
|
||||
break;
|
||||
}
|
||||
t->tm_yday = d - 1;
|
||||
}
|
||||
|
||||
static int
|
||||
systemtime_to_localtime(TIME_ZONE_INFORMATION *tz, SYSTEMTIME *gst, SYSTEMTIME *lst)
|
||||
{
|
||||
TIME_ZONE_INFORMATION stdtz;
|
||||
SYSTEMTIME sst;
|
||||
|
||||
if (!SystemTimeToTzSpecificLocalTime(tz, gst, lst)) return -1;
|
||||
if (!tz) {
|
||||
GetTimeZoneInformation(&stdtz);
|
||||
tz = &stdtz;
|
||||
}
|
||||
if (tz->StandardBias == tz->DaylightBias) return 0;
|
||||
if (!tz->StandardDate.wMonth) return 0;
|
||||
if (!tz->DaylightDate.wMonth) return 0;
|
||||
if (tz != &stdtz) stdtz = *tz;
|
||||
|
||||
stdtz.StandardDate.wMonth = stdtz.DaylightDate.wMonth = 0;
|
||||
if (!SystemTimeToTzSpecificLocalTime(&stdtz, gst, &sst)) return 0;
|
||||
if (lst->wMinute == sst.wMinute && lst->wHour == sst.wHour)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct tm *
|
||||
gmtime_r(const time_t *tp, struct tm *rp)
|
||||
{
|
||||
int e = EINVAL;
|
||||
if (!tp || !rp) {
|
||||
error:
|
||||
errno = e;
|
||||
return NULL;
|
||||
}
|
||||
#if RUBY_MSVCRT_VERSION >= 80
|
||||
e = gmtime_s(rp, tp);
|
||||
if (e != 0) goto error;
|
||||
#else
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
if (unixtime_to_systemtime(*tp, &st)) goto error;
|
||||
rp->tm_isdst = 0;
|
||||
systemtime_to_tm(&st, rp);
|
||||
}
|
||||
#endif
|
||||
return rp;
|
||||
}
|
||||
|
||||
struct tm *
|
||||
localtime_r(const time_t *tp, struct tm *rp)
|
||||
{
|
||||
int e = EINVAL;
|
||||
if (!tp || !rp) {
|
||||
error:
|
||||
errno = e;
|
||||
return NULL;
|
||||
}
|
||||
#if RUBY_MSVCRT_VERSION >= 80
|
||||
e = localtime_s(rp, tp);
|
||||
if (e) goto error;
|
||||
#else
|
||||
{
|
||||
SYSTEMTIME gst, lst;
|
||||
if (unixtime_to_systemtime(*tp, &gst)) goto error;
|
||||
rp->tm_isdst = systemtime_to_localtime(NULL, &gst, &lst);
|
||||
systemtime_to_tm(&lst, rp);
|
||||
}
|
||||
#endif
|
||||
return rp;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue