* 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:
nobu 2012-04-16 07:22:43 +00:00
Родитель 72fffe5cee
Коммит f2979f3101
5 изменённых файлов: 114 добавлений и 1 удалений

Просмотреть файл

@ -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

Просмотреть файл

@ -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;
}