about summary refs log tree commit diff
path: root/time/timegm.c
diff options
context:
space:
mode:
Diffstat (limited to 'time/timegm.c')
-rw-r--r--time/timegm.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/time/timegm.c b/time/timegm.c
index fb720e2d7d..39ad2a9899 100644
--- a/time/timegm.c
+++ b/time/timegm.c
@@ -33,15 +33,29 @@
 # include <time_r.h>
 # undef __gmtime_r
 # define __gmtime_r gmtime_r
-time_t __mktime_internal (struct tm *,
-			  struct tm * (*) (time_t const *, struct tm *),
-			  time_t *);
+time64_t __mktime_internal (struct tm *,
+			  struct tm * (*) (__time64_t const *, struct tm *),
+			  __time64_t *);
 #endif
+# include <limits.h>
+# include <errno.h>
+
+__time64_t
+__timegm64 (struct tm *tmp)
+{
+  static __time64_t gmtime_offset;
+  tmp->tm_isdst = 0;
+  return __mktime_internal (tmp, __gmtime64_r, &gmtime_offset);
+}
 
 time_t
 timegm (struct tm *tmp)
 {
-  static time_t gmtime_offset;
-  tmp->tm_isdst = 0;
-  return __mktime_internal (tmp, __gmtime_r, &gmtime_offset);
+  __time64_t result = __timegm64(tmp);
+  /* Result may be correct for __mktime_internal() which handles 64-bit
+     time, but still beyond 32-bit time_t */
+  if (fits_in_time_t (result))
+    return (time_t) result;
+  __set_errno(EOVERFLOW);
+  return (time_t) -1;
 }