[tex-k] Reproducible builds using pdftex
Norbert Preining
preining at logic.at
Tue May 3 09:50:45 CEST 2016
Hi all,
> there can't be any case where we will want to set SOURCE_DATE_EPOCH but
> not SOURCE_DATE_EPOCH_TEX_PRIMITIVES.
I would suggest the following:
SOURCE_DATE_EPOCH is used to define the date/epoch and is evaluated
for pdf output etc
SOURCE_DATE_EPOCH_FIXUP_TEX_PRIMITIVES = 0|1
if non-0 then also \today is fixed.
It does not make sense to set the same value in two variables, and
complicates the code, but it *does* make sense to install an
additional safeguard not to redefine TeX primitives.
I attach a *suggestion* for a patch against current svn (some changes
have already been included in dvipdfmx, those are dropped).
All the best
Norbert
------------------------------------------------------------------------
PREINING, Norbert http://www.preining.info
JAIST, Japan TeX Live & Debian Developer
GPG: 0x860CDC13 fp: F7D8 A928 26E3 16A1 9FA0 ACF0 6CAC A448 860C DC13
------------------------------------------------------------------------
-------------- next part --------------
---
texk/web2c/lib/texmfmp.c | 60 ++++++++++++++++++++++++--------------
texk/web2c/luatexdir/luatex.c | 12 ++++++-
texk/web2c/luatexdir/pdf/pdfgen.w | 20 ++++++++++--
3 files changed, 64 insertions(+), 28 deletions(-)
--- texlive-bin.orig/texk/web2c/lib/texmfmp.c
+++ texlive-bin/texk/web2c/lib/texmfmp.c
@@ -2200,6 +2200,30 @@
}
#endif /* not WIN32 */
+static boolean start_time_set = false;
+static time_t start_time = 0;
+
+void init_start_time() {
+ char *source_date_epoch;
+ unsigned long long epoch;
+ char *endptr;
+ if (!start_time_set) {
+ start_time_set = true;
+ source_date_epoch = getenv("SOURCE_DATE_EPOCH");
+ if (source_date_epoch) {
+ errno = 0;
+ epoch = strtoull(source_date_epoch, &endptr, 10);
+ if (epoch < 0 || *endptr != '\0' || errno != 0) {
+ FATAL1 ("invalid value for environment variable $SOURCE_DATE_EPOCH: %s",
+ source_date_epoch);
+ }
+ start_time = epoch;
+ } else {
+ start_time = time((time_t *) NULL);
+ }
+ }
+}
+
/* Besides getting the date and time here, we also set up the interrupt
handler, for no particularly good reason. It's just that since the
`fix_date_and_time' routine is called early on (section 1337 in TeX,
@@ -2210,8 +2234,14 @@
get_date_and_time (integer *minutes, integer *day,
integer *month, integer *year)
{
- time_t myclock = time ((time_t *) 0);
- struct tm *tmptr = localtime (&myclock);
+ struct tm *tmptr;
+ if(getenv("SOURCE_DATE_EPOCH_FIXUP_TEX_PRIMITIVES")) {
+ init_start_time();
+ tmptr = gmtime (&start_time);
+ } else {
+ time_t myclock = time ((time_t *) 0);
+ tmptr = localtime (&myclock);
+ }
*minutes = tmptr->tm_hour * 60 + tmptr->tm_min;
*day = tmptr->tm_mday;
@@ -2930,8 +2960,7 @@
#endif /* not pdfTeX */
#if !defined(XeTeX)
-static boolean start_time_set = false;
-static time_t start_time = 0;
+
#define TIME_STR_SIZE 30
char start_time_str[TIME_STR_SIZE];
static char time_str[TIME_STR_SIZE];
@@ -2996,25 +3025,12 @@
void initstarttime(void)
{
- char *source_date_epoch;
- int64_t epoch;
- char *endptr;
if (!start_time_set) {
- start_time_set = true;
- source_date_epoch = getenv("SOURCE_DATE_EPOCH");
- if (source_date_epoch) {
- errno = 0;
- epoch = strtoll(source_date_epoch, &endptr, 10);
- if (epoch < 0 || *endptr != '\0' || errno != 0) {
- FATAL1 ("invalid value for environment variable $SOURCE_DATE_EPOCH: %s",
- source_date_epoch);
- }
- start_time = epoch;
- makepdftime(start_time, start_time_str, /* utc= */true);
- }
- else {
- start_time = time((time_t *) NULL);
- makepdftime(start_time, start_time_str, /* utc= */false);
+ init_start_time ();
+ if (getenv ("SOURCE_DATE_EPOCH")) {
+ makepdftime (start_time, start_time_str, /* utc= */true);
+ } else {
+ makepdftime (start_time, start_time_str, /* utc= */false);
}
}
}
--- texlive-bin.orig/texk/web2c/luatexdir/luatex.c
+++ texlive-bin/texk/web2c/luatexdir/luatex.c
@@ -858,8 +858,16 @@
void get_date_and_time(int *minutes, int *day, int *month, int *year)
{
- time_t myclock = time((time_t *) 0);
- struct tm *tmptr = localtime(&myclock);
+ char *source_date_epoch = getenv("SOURCE_DATE_EPOCH");
+ struct tm *tmptr;
+ time_t myclock;
+ if(source_date_epoch) {
+ myclock = strtoull(source_date_epoch, NULL, 10);
+ tmptr = gmtime (&myclock);
+ } else {
+ myclock = time((time_t *) 0);
+ tmptr = localtime(&myclock);
+ }
*minutes = tmptr->tm_hour * 60 + tmptr->tm_min;
*day = tmptr->tm_mday;
--- texlive-bin.orig/texk/web2c/luatexdir/pdf/pdfgen.w
+++ texlive-bin/texk/web2c/luatexdir/pdf/pdfgen.w
@@ -1534,7 +1534,7 @@
@c
#define TIME_STR_SIZE 30 /* minimum size for |time_str| is 24: |"D:YYYYmmddHHMMSS+HH'MM'"| */
-static void makepdftime(PDF pdf)
+static void makepdftime(PDF pdf, int utc)
{
struct tm lt, gmt;
size_t size;
@@ -1542,7 +1542,12 @@
time_t t = pdf->start_time;
char *time_str = pdf->start_time_str;
/* get the time */
- lt = *localtime(&t);
+ if (utc) {
+ lt = *gmtime(&t);
+ }
+ else {
+ lt = *localtime(&t);
+ }
size = strftime(time_str, TIME_STR_SIZE, "D:%Y%m%d%H%M%S", <);
/* expected format: "YYYYmmddHHMMSS" */
if (size == 0) {
@@ -1584,10 +1589,17 @@
@ @c
void init_start_time(PDF pdf)
{
+ char *source_date_epoch;
if (pdf->start_time == 0) {
- pdf->start_time = time((time_t *) NULL);
pdf->start_time_str = xtalloc(TIME_STR_SIZE, char);
- makepdftime(pdf);
+ source_date_epoch = getenv("SOURCE_DATE_EPOCH");
+ if(source_date_epoch) {
+ pdf->start_time = strtoull(source_date_epoch, NULL, 10);
+ makepdftime(pdf,true);
+ } else {
+ pdf->start_time = time((time_t *) NULL);
+ makepdftime(pdf,false);
+ }
}
}
More information about the tex-k
mailing list