[libxslt] Add support timestamps from environment



commit e57df303eca25a2a3f9e0625c29f4b20177858cc
Author: Daniel Veillard <veillard redhat com>
Date:   Tue May 17 11:19:07 2016 +0800

    Add support timestamps from environment
    
    For https://bugzilla.gnome.org/show_bug.cgi?id=758148
    this is needed for reproductible builds
    
    Allow an environment variable SOURCE_DATE_EPOCH to be passed
    and define time, this is useful to get reproductable output
    when libxslt is used to generate documentation for packages.

 config.h.in     |    6 ++++--
 configure.in    |    1 +
 libexslt/date.c |   47 +++++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 48 insertions(+), 6 deletions(-)
---
diff --git a/config.h.in b/config.h.in
index d2a0cca..8f7d8c0 100644
--- a/config.h.in
+++ b/config.h.in
@@ -12,6 +12,9 @@
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #undef HAVE_DLFCN_H
 
+/* Define to 1 if you have the <errno.h> header file. */
+#undef HAVE_ERRNO_H
+
 /* Define if fabs is there */
 #undef HAVE_FABS
 
@@ -147,8 +150,7 @@
 /* Define to 1 if you have the `_stat' function. */
 #undef HAVE__STAT
 
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
-   */
+/* Define to the sub-directory where libtool stores uninstalled libraries. */
 #undef LT_OBJDIR
 
 /* Name of package */
diff --git a/configure.in b/configure.in
index 7e03d11..d055979 100644
--- a/configure.in
+++ b/configure.in
@@ -235,6 +235,7 @@ dnl
 
 AC_CHECK_HEADERS(ieeefp.h nan.h math.h fp_class.h float.h ansidecl.h)
 AC_CHECK_HEADERS(sys/timeb.h time.h sys/stat.h sys/select.h stdarg.h)
+AC_CHECK_HEADERS(errno.h)
 AC_CHECK_FUNCS(stat _stat)
 AC_CHECK_FUNC(pow, , AC_CHECK_LIB(m, pow,
   [M_LIBS="-lm"; AC_DEFINE([HAVE_POW],[], [Define if pow is there])]))
diff --git a/libexslt/date.c b/libexslt/date.c
index 87c4848..4d5b8ba 100644
--- a/libexslt/date.c
+++ b/libexslt/date.c
@@ -47,6 +47,9 @@
 
 #include <string.h>
 
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
 #ifdef HAVE_MATH_H
 #include <math.h>
 #endif
@@ -752,21 +755,55 @@ static exsltDateValPtr
 exsltDateCurrent (void)
 {
     struct tm localTm, gmTm;
+#ifndef HAVE_GMTIME_R
+    struct tm *tb = NULL;
+#endif
     time_t secs;
     int local_s, gm_s;
     exsltDateValPtr ret;
+#ifdef HAVE_ERRNO_H
+    char *source_date_epoch;
+    int override = 0;
+#endif /* HAVE_ERRNO_H */
 
     ret = exsltDateCreateDate(XS_DATETIME);
     if (ret == NULL)
         return NULL;
 
+#ifdef HAVE_ERRNO_H
+    /*
+     * Allow the date and time to be set externally by an exported
+     * environment variable to enable reproducible builds.
+     */
+    source_date_epoch = getenv("SOURCE_DATE_EPOCH");
+    if (source_date_epoch) {
+        errno = 0;
+       secs = (time_t) strtol (source_date_epoch, NULL, 10);
+       if (errno == 0) {
+#if HAVE_GMTIME_R
+           if (gmtime_r(&secs, &localTm) != NULL)
+               override = 1;
+#else
+           tb = gmtime(&secs);
+           if (tb != NULL) {
+               localTm = *tb;
+               override = 1;
+           }
+#endif
+        }
+    }
+#endif /* HAVE_ERRNO_H */
+
+    if (override == 0) {
     /* get current time */
-    secs    = time(NULL);
+       secs    = time(NULL);
+
 #if HAVE_LOCALTIME_R
-    localtime_r(&secs, &localTm);
+       localtime_r(&secs, &localTm);
 #else
-    localTm = *localtime(&secs);
+       localTm = *localtime(&secs);
 #endif
+    }
 
     /* get real year, not years since 1900 */
     ret->value.date.year = localTm.tm_year + 1900;
@@ -783,7 +820,9 @@ exsltDateCurrent (void)
 #if HAVE_GMTIME_R
     gmtime_r(&secs, &gmTm);
 #else
-    gmTm = *gmtime(&secs);
+    tb = gmtime(&secs);
+    if (tb != NULL)
+        gmTm = *tb;
 #endif
     ret->value.date.tz_flag = 0;
 #if 0


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]