[Reproducible-commits] [dpkg] 100/105: dpkg-deb: Use the common build timestamp for all files created at a later time
Niko Tyni
ntyni at moszumanska.debian.org
Mon May 2 13:50:00 UTC 2016
This is an automated email from the git hooks/post-receive script.
ntyni pushed a commit to branch ntyni/reproducible_builds
in repository dpkg.
commit 98d25dcc98139af243756cb24298518ced55abed
Author: Jérémy Bobbio <lunar at debian.org>
Date: Fri Jan 15 17:00:37 2016 +0000
dpkg-deb: Use the common build timestamp for all files created at a later time
In order to make build reproducible in the future, we now set the mtime of
archived files that has been create during the build to the common build
timestamp when tar supports the --clamp-mtime option.
The latter is available in Debian since tar/1.28-1 but has not been accepted
upstream yet.
Address: #759886
---
dpkg-deb/build.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 52 insertions(+), 4 deletions(-)
diff --git a/dpkg-deb/build.c b/dpkg-deb/build.c
index 9578894..fc29b59 100644
--- a/dpkg-deb/build.c
+++ b/dpkg-deb/build.c
@@ -421,6 +421,7 @@ typedef void filenames_feed_func(const char *dir, int fd_out);
*/
static void
tarball_pack(const char *dir, filenames_feed_func *tar_filenames_feeder,
+ time_t build_timestamp, int tar_supports_clamp_mtime,
struct compress_params *tar_compress_params, int fd_out)
{
int pipe_filenames[2], pipe_tarball[2];
@@ -441,8 +442,17 @@ tarball_pack(const char *dir, filenames_feed_func *tar_filenames_feeder,
if (chdir(dir))
ohshite(_("failed to chdir to '%.255s'"), dir);
- execlp(TAR, "tar", "-cf", "-", "--format=gnu", "--null", "--no-unquote",
- "--no-recursion", "-T", "-", NULL);
+ if (tar_supports_clamp_mtime) {
+ char mtime_option[30];
+ snprintf(mtime_option, sizeof(mtime_option), "--mtime=@%ld", build_timestamp);
+ mtime_option[29] = '\0';
+ execlp(TAR, "tar", "-cf", "-", "--format=gnu", "--null", "--no-unquote",
+ mtime_option, "--clamp-mtime", "--no-recursion",
+ "-T", "-", NULL);
+ } else {
+ execlp(TAR, "tar", "-cf", "-", "--format=gnu", "--null", "--no-unquote",
+ "--no-recursion", "-T", "-", NULL);
+ }
ohshite(_("unable to execute %s (%s)"), "tar -cf", TAR);
}
close(pipe_filenames[0]);
@@ -468,6 +478,40 @@ tarball_pack(const char *dir, filenames_feed_func *tar_filenames_feeder,
}
/**
+ * Parse `tar --help` output to see if it supports the given option.
+ */
+static int
+does_tar_support(const char *option)
+{
+ int pipe_tar_output[2];
+ pid_t pid_tar;
+ FILE *tar_output;
+ char line_buf[80];
+ int found = 0;
+
+ m_pipe(pipe_tar_output);
+ pid_tar = subproc_fork();
+ if (pid_tar == 0) {
+ m_dup2(pipe_tar_output[1], 1);
+ close(pipe_tar_output[0]);
+ close(pipe_tar_output[1]);
+ execlp(TAR, "tar", "--help", NULL);
+ ohshite(_("unable to execute %s (%s)"), "tar --help", TAR);
+ }
+ close(pipe_tar_output[1]);
+ tar_output = fdopen(pipe_tar_output[0], "r");
+ while (fgets(line_buf, sizeof(line_buf), tar_output)) {
+ if (strstr(line_buf, option)) {
+ found = 1;
+ /* we don't break to consume all output and avoid getting a SIGPIPE. */
+ }
+ }
+ close(pipe_tar_output[0]);
+ subproc_reap(pid_tar, "tar --help", 0);
+ return found;
+}
+
+/**
* Overly complex function that builds a .deb file.
*/
int
@@ -481,6 +525,7 @@ do_build(const char *const *argv)
char *tfbuf;
int arfd;
int gzfd;
+ int tar_supports_clamp_mtime;
time_t build_timestamp;
/* Decode our arguments. */
@@ -511,6 +556,8 @@ do_build(const char *const *argv)
}
m_output(stdout, _("<standard output>"));
+ tar_supports_clamp_mtime = does_tar_support("--clamp-mtime");
+
build_timestamp = time(NULL);
/* Now that we have verified everything its time to actually
@@ -544,7 +591,8 @@ do_build(const char *const *argv)
}
/* Fork a tar to package the control-section of the package. */
- tarball_pack(ctrldir, control_treewalk_feed, &control_compress_params, gzfd);
+ tarball_pack(ctrldir, control_treewalk_feed, build_timestamp,
+ tar_supports_clamp_mtime, &control_compress_params, gzfd);
free(ctrldir);
@@ -605,7 +653,7 @@ do_build(const char *const *argv)
}
/* Pack the directory into a tarball, feeding files from the callback. */
- tarball_pack(dir, file_treewalk_feed, &compress_params, gzfd);
+ tarball_pack(dir, file_treewalk_feed, build_timestamp, tar_supports_clamp_mtime, &compress_params, gzfd);
/* Okay, we have data.tar as well now, add it to the ar wrapper. */
if (deb_format.major == 2) {
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/dpkg.git
More information about the Reproducible-commits
mailing list