teknoraver / rpms / rpm

Forked from rpms/rpm 4 months ago
Clone
Blob Blame History Raw
From aa31421bfe835dadd29da3aa46ee446038f80d02 Mon Sep 17 00:00:00 2001
From: Matthew Almond <malmond@fb.com>
Date: Sun, 31 Jan 2021 13:51:16 -0800
Subject: [PATCH 03/30] Match formatting/style of existing code

The existing code contains some variability in formatting. I'm not sure
if { is meant to be on the end of the line, or on a new line, but I've
standardized on the former.

The indentation is intended to match the existing convention: 4 column
indent, but 8 column wide tab characters. This is easy to follow/use in
vim, but is surprisingly difficult to get right in vscode. I am doing
this reformat here and now, and future changes will be after this.

I'm keen to fold the patches together, but for now, I'm trying to keep
the history of #1470 linear so everyone can follow along.
---
 lib/rpmplugins.c  |   6 +-
 plugins/reflink.c | 407 ++++++++++++++++++---------------
 rpm2extents.c     | 562 ++++++++++++++++++++--------------------------
 3 files changed, 462 insertions(+), 513 deletions(-)

diff --git a/lib/rpmplugins.c b/lib/rpmplugins.c
index c5084d398..3da3097af 100644
--- a/lib/rpmplugins.c
+++ b/lib/rpmplugins.c
@@ -368,9 +368,9 @@ rpmRC rpmpluginsCallFsmFilePre(rpmPlugins plugins, rpmfi fi, const char *path,
 		rc = RPMRC_FAIL;
 	    } else if (hook_rc == RPMRC_PLUGIN_CONTENTS && rc != RPMRC_FAIL) {
 		if (rc == RPMRC_PLUGIN_CONTENTS) {
-		    /*
-		    Another plugin already said it'd handle contents. It's undefined how
-		    these would combine, so treat this as a failure condition.
+		    /* Another plugin already said it'd handle contents. It's
+		     * undefined how these would combine, so treat this as a
+		     * failure condition.
 		    */
 		    rc = RPMRC_FAIL;
 		} else {
diff --git a/plugins/reflink.c b/plugins/reflink.c
index d7f19acd9..9eaa87094 100644
--- a/plugins/reflink.c
+++ b/plugins/reflink.c
@@ -32,31 +32,32 @@
 #include "lib/rpmhash.H"
 #include "lib/rpmhash.C"
 
-/*
-We use this in find to indicate a key wasn't found. This is an unrecoverable
-error, but we can at least show a decent error. 0 is never a valid offset
-because it's the offset of the start of the file.
-*/
+/* We use this in find to indicate a key wasn't found. This is an
+ * unrecoverable error, but we can at least show a decent error. 0 is never a
+ * valid offset because it's the offset of the start of the file.
+ */
 #define NOT_FOUND 0
 
 #define BUFFER_SIZE (1024 * 128)
 
-/* magic value at end of file (64 bits) that indicates this is a transcoded rpm */
+/* magic value at end of file (64 bits) that indicates this is a transcoded
+ * rpm.
+ */
 #define MAGIC 3472329499408095051
 
 struct reflink_state_s {
-  /* Stuff that's used across rpms */
-  long fundamental_block_size;
-  char *buffer;
+    /* Stuff that's used across rpms */
+    long fundamental_block_size;
+    char *buffer;
 
-  /* stuff that's used/updated per psm */
-  uint32_t keys, keysize;
+    /* stuff that's used/updated per psm */
+    uint32_t keys, keysize;
 
-  // table for current rpm, keys * (keysize + sizeof(rpm_loff_t))
-  unsigned char *table;
-  FD_t fd;
-  rpmfiles files;
-  inodeIndexHash inodeIndexes;
+    /* table for current rpm, keys * (keysize + sizeof(rpm_loff_t)) */
+    unsigned char *table;
+    FD_t fd;
+    rpmfiles files;
+    inodeIndexHash inodeIndexes;
 };
 
 typedef struct reflink_state_s * reflink_state;
@@ -73,60 +74,62 @@ static unsigned int inodeId(rpm_ino_t a)
 }
 
 static rpmRC reflink_init(rpmPlugin plugin, rpmts ts) {
-  reflink_state state = rcalloc(1, sizeof(struct reflink_state_s));
+    reflink_state state = rcalloc(1, sizeof(struct reflink_state_s));
 
-  /*
-  IOCTL-FICLONERANGE(2): ...Disk filesystems generally require the offset and
-  length arguments to be aligned to the fundamental block size.
+    /* IOCTL-FICLONERANGE(2): ...Disk filesystems generally require the offset
+     * and length arguments to be aligned to the fundamental block size.
+     *
+     * The value of "fundamental block size" is directly related to the
+     * system's page size, so we should use that.
+     */
+    state->fundamental_block_size = sysconf(_SC_PAGESIZE);
+    state->buffer = rcalloc(1, BUFFER_SIZE);
+    rpmPluginSetData(plugin, state);
 
-  The value of "fundamental block size" is directly related to the system's
-  page size, so we should use that.
-  */
-  state->fundamental_block_size = sysconf(_SC_PAGESIZE);
-  state->buffer = rcalloc(1, BUFFER_SIZE);
-  rpmPluginSetData(plugin, state);
-
-  return RPMRC_OK;
+    return RPMRC_OK;
 }
 
 static void reflink_cleanup(rpmPlugin plugin) {
-  reflink_state state = rpmPluginGetData(plugin);
-  free(state->buffer);
-  free(state);
+    reflink_state state = rpmPluginGetData(plugin);
+    free(state->buffer);
+    free(state);
 }
 
 static rpmRC reflink_psm_pre(rpmPlugin plugin, rpmte te) {
     reflink_state state = rpmPluginGetData(plugin);
     state->fd = rpmteFd(te);
     if (state->fd == 0) {
-      rpmlog(RPMLOG_DEBUG, _("reflink: fd = 0, no install\n"));
-      return RPMRC_OK;
+	rpmlog(RPMLOG_DEBUG, _("reflink: fd = 0, no install\n"));
+	return RPMRC_OK;
     }
     rpm_loff_t current = Ftell(state->fd);
     uint64_t magic;
     if (Fseek(state->fd, -(sizeof(magic)), SEEK_END) < 0) {
-      rpmlog(RPMLOG_ERR, _("reflink: failed to seek for magic\n"));
-      if (Fseek(state->fd, current, SEEK_SET) < 0) {
-        /* yes this gets a bit repetitive */
-        rpmlog(RPMLOG_ERR, _("reflink: unable to seek back to original location\n"));
-      }
-      return RPMRC_FAIL;
+	rpmlog(RPMLOG_ERR, _("reflink: failed to seek for magic\n"));
+	if (Fseek(state->fd, current, SEEK_SET) < 0) {
+	    /* yes this gets a bit repetitive */
+	    rpmlog(RPMLOG_ERR,
+		 _("reflink: unable to seek back to original location\n"));
+	}
+	return RPMRC_FAIL;
     }
     size_t len = sizeof(magic);
     if (Fread(&magic, len, 1, state->fd) != len) {
-      rpmlog(RPMLOG_ERR, _("reflink: unable to read magic\n"));
-      if (Fseek(state->fd, current, SEEK_SET) < 0) {
-        rpmlog(RPMLOG_ERR, _("reflink: unable to seek back to original location\n"));
-      }
-      return RPMRC_FAIL;
+	rpmlog(RPMLOG_ERR, _("reflink: unable to read magic\n"));
+	if (Fseek(state->fd, current, SEEK_SET) < 0) {
+	    rpmlog(RPMLOG_ERR,
+		   _("reflink: unable to seek back to original location\n"));
+	}
+	return RPMRC_FAIL;
     }
     if (magic != MAGIC) {
-      rpmlog(RPMLOG_DEBUG, _("reflink: not transcoded\n"));
-      if (Fseek(state->fd, current, SEEK_SET) < 0) {
-        rpmlog(RPMLOG_ERR, _("reflink: unable to seek back to original location\n"));
-        return RPMRC_FAIL;
-      }
-      return RPMRC_OK;
+	rpmlog(RPMLOG_DEBUG, _("reflink: not transcoded\n"));
+	if (Fseek(state->fd, current, SEEK_SET) < 0) {
+	    rpmlog(RPMLOG_ERR,
+		   _("reflink: unable to seek back to original location\n"));
+	    return RPMRC_FAIL;
+	}
+	return RPMRC_OK;
     }
     rpmlog(RPMLOG_DEBUG, _("reflink: *is* transcoded\n"));
     Header h = rpmteHeader(te);
@@ -136,53 +139,60 @@ static rpmRC reflink_psm_pre(rpmPlugin plugin, rpmte te) {
     headerPutString(h, RPMTAG_PAYLOADFORMAT, "clon");
     headerFree(h);
     state->files = rpmteFiles(te);
-    /* tail of file contains offset_table, offset_checksums
-       then magic
-    */
+    /* tail of file contains offset_table, offset_checksums then magic */
     if (Fseek(state->fd, -(sizeof(rpm_loff_t) * 2 + sizeof(magic)), SEEK_END) < 0) {
-      rpmlog(RPMLOG_ERR, _("reflink: failed to seek for tail %p\n"), state->fd);
-      return RPMRC_FAIL;
+	rpmlog(RPMLOG_ERR, _("reflink: failed to seek for tail %p\n"),
+	       state->fd);
+	return RPMRC_FAIL;
     }
     rpm_loff_t table_start;
     len = sizeof(table_start);
     if (Fread(&table_start, len, 1, state->fd) != len) {
-      rpmlog(RPMLOG_ERR, _("reflink: unable to read table_start\n"));
-      return RPMRC_FAIL;
+	rpmlog(RPMLOG_ERR, _("reflink: unable to read table_start\n"));
+	return RPMRC_FAIL;
     }
     if (Fseek(state->fd, table_start, SEEK_SET) < 0) {
-      rpmlog(RPMLOG_ERR, _("reflink: unable to seek to table_start\n"));
-      return RPMRC_FAIL;
+	rpmlog(RPMLOG_ERR, _("reflink: unable to seek to table_start\n"));
+	return RPMRC_FAIL;
     }
     len = sizeof(state->keys);
     if (Fread(&state->keys, len, 1, state->fd) != len) {
-      rpmlog(RPMLOG_ERR, _("reflink: unable to read number of keys\n"));
-      return RPMRC_FAIL;
+	rpmlog(RPMLOG_ERR, _("reflink: unable to read number of keys\n"));
+	return RPMRC_FAIL;
     }
     len = sizeof(state->keysize);
     if (Fread(&state->keysize, len, 1, state->fd) != len) {
-      rpmlog(RPMLOG_ERR, _("reflink: unable to read keysize\n"));
-      return RPMRC_FAIL;
+	rpmlog(RPMLOG_ERR, _("reflink: unable to read keysize\n"));
+	return RPMRC_FAIL;
     }
-    rpmlog(RPMLOG_DEBUG, _("reflink: table_start=0x%lx, keys=%d, keysize=%d\n"), table_start, state->keys, state->keysize);
-    // now get digest table if there is a reason to have one.
+    rpmlog(
+	RPMLOG_DEBUG,
+	_("reflink: table_start=0x%lx, keys=%d, keysize=%d\n"),
+	table_start, state->keys, state->keysize
+    );
+    /* now get digest table if there is a reason to have one. */
     if (state->keys == 0 || state->keysize == 0) {
-      // no files (or no digests(!))
-      state->table = NULL;
+	/* no files (or no digests(!)) */
+	state->table = NULL;
     } else {
-      int table_size = state->keys * (state->keysize + sizeof(rpm_loff_t));
-      state->table = rcalloc(1, table_size);
-      if (Fread(state->table, table_size, 1, state->fd) != table_size) {
-        rpmlog(RPMLOG_ERR, _("reflink: unable to read table\n"));
-        return RPMRC_FAIL;
-      }
-      state->inodeIndexes = inodeIndexHashCreate(state->keys, inodeId, inodeCmp, NULL, NULL);
+	int table_size = state->keys * (state->keysize + sizeof(rpm_loff_t));
+	state->table = rcalloc(1, table_size);
+	if (Fread(state->table, table_size, 1, state->fd) != table_size) {
+	    rpmlog(RPMLOG_ERR, _("reflink: unable to read table\n"));
+	    return RPMRC_FAIL;
+	}
+	state->inodeIndexes = inodeIndexHashCreate(
+	    state->keys, inodeId, inodeCmp, NULL, NULL
+	);
     }
 
-    // seek back to original location
-    // might not be needed if we seek to offset immediately
+    /* Seek back to original location.
+     * Might not be needed if we seek to offset immediately
+     */
     if (Fseek(state->fd, current, SEEK_SET) < 0) {
-      rpmlog(RPMLOG_ERR, _("reflink: unable to seek back to original location\n"));
-      return RPMRC_FAIL;
+	rpmlog(RPMLOG_ERR,
+	       _("reflink: unable to seek back to original location\n"));
+	return RPMRC_FAIL;
     }
     return RPMRC_OK;
 }
@@ -192,40 +202,45 @@ static rpmRC reflink_psm_post(rpmPlugin plugin, rpmte te, int res)
     reflink_state state = rpmPluginGetData(plugin);
     state->files = rpmfilesFree(state->files);
     if (state->table) {
-      free(state->table);
-      state->table = NULL;
+	free(state->table);
+	state->table = NULL;
     }
     if (state->inodeIndexes) {
-      inodeIndexHashFree(state->inodeIndexes);
-      state->inodeIndexes = NULL;
+	inodeIndexHashFree(state->inodeIndexes);
+	state->inodeIndexes = NULL;
     }
     return RPMRC_OK;
 }
 
 
-// have a prototype, warnings system
+/* have a prototype, warnings system */
 rpm_loff_t find(const unsigned char *digest, reflink_state state);
 
 rpm_loff_t find(const unsigned char *digest, reflink_state state) {
 # if defined(__GNUC__)
-  /* GCC nested function because bsearch's comparison function can't access
-     state-keysize otherwise
-  */
-  int cmpdigest(const void *k1, const void *k2) {
-    rpmlog(RPMLOG_DEBUG, _("reflink: cmpdigest k1=%p k2=%p\n"), k1, k2);
-    return memcmp(k1, k2, state->keysize);
-  }
+    /* GCC nested function because bsearch's comparison function can't access
+     * state-keysize otherwise
+     */
+    int cmpdigest(const void *k1, const void *k2) {
+	rpmlog(RPMLOG_DEBUG, _("reflink: cmpdigest k1=%p k2=%p\n"), k1, k2);
+	return memcmp(k1, k2, state->keysize);
+    }
 # endif
-  rpmlog(RPMLOG_DEBUG, _("reflink: bsearch(key=%p, base=%p, nmemb=%d, size=%lu)\n"), digest, state->table, state->keys, state->keysize + sizeof(rpm_loff_t));
-  char *entry = bsearch(digest, state->table, state->keys, state->keysize + sizeof(rpm_loff_t), cmpdigest);
-  if (entry == NULL) {
-    return NOT_FOUND;
-  }
-  rpm_loff_t offset = *(rpm_loff_t *)(entry + state->keysize);
-  return offset;
+    rpmlog(RPMLOG_DEBUG,
+	   _("reflink: bsearch(key=%p, base=%p, nmemb=%d, size=%lu)\n"),
+	   digest, state->table, state->keys,
+	   state->keysize + sizeof(rpm_loff_t));
+    char *entry = bsearch(digest, state->table, state->keys,
+			  state->keysize + sizeof(rpm_loff_t), cmpdigest);
+    if (entry == NULL) {
+	return NOT_FOUND;
+    }
+    rpm_loff_t offset = *(rpm_loff_t *)(entry + state->keysize);
+    return offset;
 }
 
-static rpmRC reflink_fsm_file_pre(rpmPlugin plugin, rpmfi fi, const char* path, mode_t file_mode, rpmFsmOp op)
+static rpmRC reflink_fsm_file_pre(rpmPlugin plugin, rpmfi fi, const char* path,
+                                  mode_t file_mode, rpmFsmOp op)
 {
     struct file_clone_range fcr;
     rpm_loff_t size;
@@ -234,99 +249,119 @@ static rpmRC reflink_fsm_file_pre(rpmPlugin plugin, rpmfi fi, const char* path,
 
     reflink_state state = rpmPluginGetData(plugin);
     if (state->table == NULL) {
-        // no table means rpm is not in reflink format, so leave. Now.
-        return RPMRC_OK;
+	/* no table means rpm is not in reflink format, so leave. Now. */
+	return RPMRC_OK;
     }
     if (op == FA_TOUCH) {
-        // we're not overwriting an existing file
-        return RPMRC_OK;
+	/* we're not overwriting an existing file. */
+	return RPMRC_OK;
     }
     fcr.dest_offset = 0;
     if (S_ISREG(file_mode) && !(rpmfiFFlags(fi) & RPMFILE_GHOST)) {
-      rpm_ino_t inode = rpmfiFInode(fi);
-      /* check for hard link entry in table. GetEntry overwrites hlix with the address of the first match */
-      if (inodeIndexHashGetEntry(state->inodeIndexes, inode, &hlix, NULL, NULL)) {
-        // entry is in table, use hard link
-        char *fn = rpmfilesFN(state->files, hlix[0]);
-        if (link(fn, path) != 0) {
-          rpmlog(RPMLOG_ERR, _("reflink: Unable to hard link %s -> %s due to %s\n"), fn, path, strerror(errno));
-          free(fn);
-          return RPMRC_FAIL;
-        }
-        free(fn);
-        return RPMRC_PLUGIN_CONTENTS;
-      }
-      /* if we didn't hard link, then we'll track this inode as being created soon */
-      if (rpmfiFNlink(fi) > 1) {
-        /* minor optimization: only store files with more than one link */
-        inodeIndexHashAddEntry(state->inodeIndexes, inode, rpmfiFX(fi));
-      }
-      /* derived from wfd_open in fsm.c */
-      mode_t old_umask = umask(0577);
-      dst = open(path, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR);
-      umask(old_umask);
-      if (dst == -1) {
-          rpmlog(RPMLOG_ERR, _("reflink: Unable to open %s for writing due to %s, flags = %x\n"), path, strerror(errno), rpmfiFFlags(fi));
-          return RPMRC_FAIL;
-      }
-      size = rpmfiFSize(fi);
-      if (size > 0) {
-          /* round src_length down to fundamental_block_size multiple */
-          fcr.src_length = size / state->fundamental_block_size * state->fundamental_block_size;
-          if ((size % state->fundamental_block_size) > 0) {
-              /* round up to next fundamental_block_size. We expect the data in the rpm to be similarly padded */
-              fcr.src_length += state->fundamental_block_size;
-          }
-          fcr.src_fd = Fileno(state->fd);
-          if (fcr.src_fd == -1) {
-            close(dst);
-            rpmlog(RPMLOG_ERR, _("reflink: src fd lookup failed\n"));
-            return RPMRC_FAIL;
-          }
-          fcr.src_offset = find(rpmfiFDigest(fi, NULL, NULL), state);
-          if (fcr.src_offset == NOT_FOUND) {
-            close(dst);
-            rpmlog(RPMLOG_ERR, _("reflink: digest not found\n"));
-            return RPMRC_FAIL;
-          }
-          rpmlog(RPMLOG_DEBUG, _("reflink: Reflinking %lu bytes at %lu to %s orig size=%lu, file=%ld\n"), fcr.src_length, fcr.src_offset, path, size, fcr.src_fd);
-          rc = ioctl(dst, FICLONERANGE, &fcr);
-          if (rc) {
-            rpmlog(RPMLOG_WARNING, _("reflink: falling back to copying bits for %s due to %d, %d = %s\n"), path, rc, errno, strerror(errno));
-            if (Fseek(state->fd, fcr.src_offset, SEEK_SET) < 0) {
-                close(dst);
-                rpmlog(RPMLOG_ERR, _("reflink: unable to seek on copying bits\n"));
-                return RPMRC_FAIL;
-            }
-            rpm_loff_t left = size;
-            size_t len, read, written;
-            while (left) {
-              len = (left > BUFFER_SIZE ? BUFFER_SIZE : left);
-              read = Fread(state->buffer, len, 1, state->fd);
-              if (read != len) {
-                close(dst);
-                rpmlog(RPMLOG_ERR, _("reflink: short read on copying bits\n"));
-                return RPMRC_FAIL;
-              }
-              written = write(dst, state->buffer, len);
-              if (read != written) {
-                close(dst);
-                rpmlog(RPMLOG_ERR, _("reflink: short write on copying bits\n"));
-                return RPMRC_FAIL;
-              }
-              left -= len;
-            }
-          } else {
-            /* reflink worked, so truncate */
-            rc = ftruncate(dst, size);
-            if (rc) {
-                rpmlog(RPMLOG_ERR, _("reflink: Unable to truncate %s to %ld due to %s\n"), path, size, strerror(errno));
-                return RPMRC_FAIL;
-            }
-          }
-      }
-      close(dst);
-      return RPMRC_PLUGIN_CONTENTS;
+	rpm_ino_t inode = rpmfiFInode(fi);
+	/* check for hard link entry in table. GetEntry overwrites hlix with
+	 * the address of the first match.
+	 */
+	if (inodeIndexHashGetEntry(state->inodeIndexes, inode, &hlix, NULL,
+	                           NULL)) {
+	    /* entry is in table, use hard link */
+	    char *fn = rpmfilesFN(state->files, hlix[0]);
+	    if (link(fn, path) != 0) {
+		rpmlog(RPMLOG_ERR,
+		       _("reflink: Unable to hard link %s -> %s due to %s\n"),
+		       fn, path, strerror(errno));
+		free(fn);
+		return RPMRC_FAIL;
+	    }
+	    free(fn);
+	    return RPMRC_PLUGIN_CONTENTS;
+	}
+	/* if we didn't hard link, then we'll track this inode as being
+	 * created soon
+	 */
+	if (rpmfiFNlink(fi) > 1) {
+	    /* minor optimization: only store files with more than one link */
+	    inodeIndexHashAddEntry(state->inodeIndexes, inode, rpmfiFX(fi));
+	}
+	/* derived from wfd_open in fsm.c */
+	mode_t old_umask = umask(0577);
+	dst = open(path, O_WRONLY | O_CREAT | O_EXCL, S_IRUSR);
+	umask(old_umask);
+	if (dst == -1) {
+	    rpmlog(RPMLOG_ERR,
+		   _("reflink: Unable to open %s for writing due to %s, flags = %x\n"),
+		   path, strerror(errno), rpmfiFFlags(fi));
+	    return RPMRC_FAIL;
+	}
+	size = rpmfiFSize(fi);
+	if (size > 0) {
+	    /* round src_length down to fundamental_block_size multiple */
+	    fcr.src_length = size / state->fundamental_block_size * state->fundamental_block_size;
+	    if ((size % state->fundamental_block_size) > 0) {
+		/* round up to next fundamental_block_size. We expect the data
+		 * in the rpm to be similarly padded.
+		 */
+		fcr.src_length += state->fundamental_block_size;
+	    }
+	    fcr.src_fd = Fileno(state->fd);
+	    if (fcr.src_fd == -1) {
+		close(dst);
+		rpmlog(RPMLOG_ERR, _("reflink: src fd lookup failed\n"));
+		return RPMRC_FAIL;
+	    }
+	    fcr.src_offset = find(rpmfiFDigest(fi, NULL, NULL), state);
+	    if (fcr.src_offset == NOT_FOUND) {
+		close(dst);
+		rpmlog(RPMLOG_ERR, _("reflink: digest not found\n"));
+		return RPMRC_FAIL;
+	    }
+	    rpmlog(RPMLOG_DEBUG,
+	           _("reflink: Reflinking %lu bytes at %lu to %s orig size=%lu, file=%ld\n"),
+		   fcr.src_length, fcr.src_offset, path, size, fcr.src_fd);
+	    rc = ioctl(dst, FICLONERANGE, &fcr);
+	    if (rc) {
+		rpmlog(RPMLOG_WARNING,
+		       _("reflink: falling back to copying bits for %s due to %d, %d = %s\n"),
+		       path, rc, errno, strerror(errno));
+		if (Fseek(state->fd, fcr.src_offset, SEEK_SET) < 0) {
+		    close(dst);
+		    rpmlog(RPMLOG_ERR,
+			   _("reflink: unable to seek on copying bits\n"));
+		    return RPMRC_FAIL;
+		}
+		rpm_loff_t left = size;
+		size_t len, read, written;
+		while (left) {
+		    len = (left > BUFFER_SIZE ? BUFFER_SIZE : left);
+		    read = Fread(state->buffer, len, 1, state->fd);
+		    if (read != len) {
+			close(dst);
+			rpmlog(RPMLOG_ERR,
+			       _("reflink: short read on copying bits\n"));
+			return RPMRC_FAIL;
+		    }
+		    written = write(dst, state->buffer, len);
+		    if (read != written) {
+			close(dst);
+			rpmlog(RPMLOG_ERR,
+			       _("reflink: short write on copying bits\n"));
+			return RPMRC_FAIL;
+		    }
+		    left -= len;
+		}
+	    } else {
+		/* reflink worked, so truncate */
+		rc = ftruncate(dst, size);
+		if (rc) {
+		    rpmlog(RPMLOG_ERR,
+			   _("reflink: Unable to truncate %s to %ld due to %s\n"),
+			   path, size, strerror(errno));
+		     return RPMRC_FAIL;
+		}
+	    }
+	}
+	close(dst);
+	return RPMRC_PLUGIN_CONTENTS;
     }
     return RPMRC_OK;
 }
diff --git a/rpm2extents.c b/rpm2extents.c
index 5662b86a6..c111be0a2 100644
--- a/rpm2extents.c
+++ b/rpm2extents.c
@@ -24,7 +24,7 @@
 #include "debug.h"
 
 /* hash of void * (pointers) to file digests to offsets within output.
-   The length of the key depends on what the FILEDIGESTALGO is.
+ * The length of the key depends on what the FILEDIGESTALGO is.
  */
 #undef HASHTYPE
 #undef HTKEYTYPE
@@ -34,7 +34,9 @@
 #include "lib/rpmhash.H"
 #include "lib/rpmhash.C"
 
-/* magic value at end of file (64 bits) that indicates this is a transcoded rpm */
+/* magic value at end of file (64 bits) that indicates this is a transcoded
+ * rpm.
+ */
 #define MAGIC 3472329499408095051
 
 struct digestoffset {
@@ -64,77 +66,54 @@ static int digestor(
     int algo;
     rpmRC rc = RPMRC_FAIL;
 
-    for (algo = 0; algo < algos_len; algo++)
-    {
-        fdInitDigest(fdi, algos[algo], 0);
+    for (algo = 0; algo < algos_len; algo++) {
+	fdInitDigest(fdi, algos[algo], 0);
     }
     fdilength = ufdCopy(fdi, fdo);
-    if (fdilength == -1)
-    {
-        fprintf(stderr, _("digest cat failed\n"));
-        goto exit;
+    if (fdilength == -1) {
+	fprintf(stderr, _("digest cat failed\n"));
+	goto exit;
     }
 
     len = sizeof(fdilength);
-    if (Fwrite(&fdilength, len, 1, validationo) != len)
-    {
-        fprintf(stderr, _("Unable to write input length %zd\n"), fdilength);
-        goto exit;
+    if (Fwrite(&fdilength, len, 1, validationo) != len) {
+	fprintf(stderr, _("Unable to write input length %zd\n"), fdilength);
+	goto exit;
     }
     len = sizeof(algos_len);
-    if (Fwrite(&algos_len, len, 1, validationo) != len)
-    {
-        fprintf(stderr, _("Unable to write number of validation digests\n"));
-        goto exit;
+    if (Fwrite(&algos_len, len, 1, validationo) != len) {
+	fprintf(stderr, _("Unable to write number of validation digests\n"));
+	goto exit;
     }
-    for (algo = 0; algo < algos_len; algo++)
-    {
-        fdFiniDigest(fdi, algos[algo], (void **)&filedigest, &filedigest_len, 0);
-
-        algo_name = pgpValString(PGPVAL_HASHALGO, algos[algo]);
-        algo_name_len = (uint32_t)strlen(algo_name);
-        algo_digest_len = (uint32_t)filedigest_len;
-
-        len = sizeof(algo_name_len);
-        if (Fwrite(&algo_name_len, len, 1, validationo) != len)
-        {
-            fprintf(
-                stderr,
-                _("Unable to write validation algo name length\n")
-            );
-            goto exit;
-        }
-        len = sizeof(algo_digest_len);
-        if (Fwrite(&algo_digest_len, len, 1, validationo) != len)
-        {
-            fprintf(
-                stderr,
-                _("Unable to write number of bytes for validation digest\n")
-            );
-            goto exit;
-        }
-        if (Fwrite(algo_name, algo_name_len, 1, validationo) != algo_name_len)
-        {
-            fprintf(stderr, _("Unable to write validation algo name\n"));
-            goto exit;
-        }
-        if (
-            Fwrite(
-                filedigest,
-                algo_digest_len,
-                1,
-                validationo
-            ) != algo_digest_len
-        )
-        {
-            fprintf(
-                stderr,
-                _("Unable to write validation digest value %u, %zu\n"),
-                algo_digest_len,
-                filedigest_len
-            );
-            goto exit;
-        }
+    for (algo = 0; algo < algos_len; algo++) {
+	fdFiniDigest(fdi, algos[algo], (void **)&filedigest, &filedigest_len, 0);
+
+	algo_name = pgpValString(PGPVAL_HASHALGO, algos[algo]);
+	algo_name_len = (uint32_t)strlen(algo_name);
+	algo_digest_len = (uint32_t)filedigest_len;
+
+	len = sizeof(algo_name_len);
+	if (Fwrite(&algo_name_len, len, 1, validationo) != len) {
+	    fprintf(stderr,
+		    _("Unable to write validation algo name length\n"));
+	    goto exit;
+	}
+	len = sizeof(algo_digest_len);
+	if (Fwrite(&algo_digest_len, len, 1, validationo) != len) {
+	    fprintf(stderr,
+		    _("Unable to write number of bytes for validation digest\n"));
+	     goto exit;
+	}
+	if (Fwrite(algo_name, algo_name_len, 1, validationo) != algo_name_len) {
+	    fprintf(stderr, _("Unable to write validation algo name\n"));
+	    goto exit;
+	}
+	if (Fwrite(filedigest, algo_digest_len, 1, validationo ) != algo_digest_len) {
+	    fprintf(stderr,
+		    _("Unable to write validation digest value %u, %zu\n"),
+		    algo_digest_len, filedigest_len);
+	    goto exit;
+	}
     }
     rc = RPMRC_OK;
 exit:
@@ -145,23 +124,20 @@ static rpmRC process_package(FD_t fdi, FD_t validationi)
 {
     uint32_t diglen;
     /* GNU C extension: can use diglen from outer context */
-    int digestSetCmp(const unsigned char * a, const unsigned char * b)
-    {
-        return memcmp(a, b, diglen);
+    int digestSetCmp(const unsigned char * a, const unsigned char * b) {
+	return memcmp(a, b, diglen);
     }
 
-    unsigned int digestSetHash(const unsigned char * digest)
-    {
+    unsigned int digestSetHash(const unsigned char * digest) {
         /* assumes sizeof(unsigned int) < diglen */
         return *(unsigned int *)digest;
     }
 
-    int digestoffsetCmp(const void * a, const void * b)
-    {
-        return digestSetCmp(
-            ((struct digestoffset *)a)->digest,
-            ((struct digestoffset *)b)->digest
-        );
+    int digestoffsetCmp(const void * a, const void * b) {
+	return digestSetCmp(
+	    ((struct digestoffset *)a)->digest,
+	    ((struct digestoffset *)b)->digest
+	);
     }
 
     FD_t fdo;
@@ -179,65 +155,52 @@ static rpmRC process_package(FD_t fdi, FD_t validationi)
 
     fdo = fdDup(STDOUT_FILENO);
 
-    if (rpmReadPackageRaw(fdi, &sigh, &h))
-    {
-        fprintf(stderr, _("Error reading package\n"));
-        exit(EXIT_FAILURE);
+    if (rpmReadPackageRaw(fdi, &sigh, &h)) {
+	fprintf(stderr, _("Error reading package\n"));
+	exit(EXIT_FAILURE);
     }
 
     if (rpmLeadWrite(fdo, h))
     {
-        fprintf(
-            stderr,
-            _("Unable to write package lead: %s\n"),
-            Fstrerror(fdo)
-        );
-        exit(EXIT_FAILURE);
+	fprintf(stderr, _("Unable to write package lead: %s\n"),
+		Fstrerror(fdo));
+	exit(EXIT_FAILURE);
     }
 
-    if (rpmWriteSignature(fdo, sigh))
-    {
-        fprintf(stderr, _("Unable to write signature: %s\n"), Fstrerror(fdo));
-        exit(EXIT_FAILURE);
+    if (rpmWriteSignature(fdo, sigh)) {
+	fprintf(stderr, _("Unable to write signature: %s\n"), Fstrerror(fdo));
+	exit(EXIT_FAILURE);
     }
 
-    if (headerWrite(fdo, h, HEADER_MAGIC_YES))
-    {
-        fprintf(stderr, _("Unable to write headers: %s\n"), Fstrerror(fdo));
-        exit(EXIT_FAILURE);
+    if (headerWrite(fdo, h, HEADER_MAGIC_YES)) {
+	fprintf(stderr, _("Unable to write headers: %s\n"), Fstrerror(fdo));
+	exit(EXIT_FAILURE);
     }
 
     /* Retrieve payload size and compression type. */
-    {	const char *compr = headerGetString(h, RPMTAG_PAYLOADCOMPRESSOR);
-        rpmio_flags = rstrscat(NULL, "r.", compr ? compr : "gzip", NULL);
+    {
+	const char *compr = headerGetString(h, RPMTAG_PAYLOADCOMPRESSOR);
+	rpmio_flags = rstrscat(NULL, "r.", compr ? compr : "gzip", NULL);
     }
 
     gzdi = Fdopen(fdi, rpmio_flags);	/* XXX gzdi == fdi */
     free(rpmio_flags);
 
-    if (gzdi == NULL)
-    {
-        fprintf(stderr, _("cannot re-open payload: %s\n"), Fstrerror(gzdi));
-        exit(EXIT_FAILURE);
+    if (gzdi == NULL) {
+	fprintf(stderr, _("cannot re-open payload: %s\n"), Fstrerror(gzdi));
+	exit(EXIT_FAILURE);
     }
 
     rpmfiles files = rpmfilesNew(NULL, h, 0, RPMFI_KEEPHEADER);
-    rpmfi fi = rpmfiNewArchiveReader(
-        gzdi,
-        files,
-        RPMFI_ITER_READ_ARCHIVE_CONTENT_FIRST
-    );
+    rpmfi fi = rpmfiNewArchiveReader(gzdi, files,
+				     RPMFI_ITER_READ_ARCHIVE_CONTENT_FIRST);
 
     /* this is encoded in the file format, so needs to be fixed size (for
-        now?)
-    */
+     * now?)
+     */
     diglen = (uint32_t)rpmDigestLength(rpmfiDigestAlgo(fi));
-    digestSet ds = digestSetCreate(
-        rpmfiFC(fi),
-        digestSetHash,
-        digestSetCmp,
-        NULL
-    );
+    digestSet ds = digestSetCreate(rpmfiFC(fi), digestSetHash, digestSetCmp,
+				   NULL);
     struct digestoffset offsets[rpmfiFC(fi)];
     pos = RPMLEAD_SIZE + headerSizeof(sigh, HEADER_MAGIC_YES);
 
@@ -247,139 +210,114 @@ static rpmRC process_package(FD_t fdi, FD_t validationi)
 
     zeros = xcalloc(fundamental_block_size, 1);
 
-    while (next >= 0)
-    {
-        next = rpmfiNext(fi);
-        if (next == RPMERR_ITER_END)
-        {
-            rc = RPMRC_OK;
-            break;
-        }
-        mode = rpmfiFMode(fi);
-        if (!S_ISREG(mode) || !rpmfiArchiveHasContent(fi))
-        {
-            /* not a regular file, or the archive doesn't contain any content for
-               this entry
-            */
-            continue;
-        }
-        digest = rpmfiFDigest(fi, NULL, NULL);
-        if (digestSetGetEntry(ds, digest, NULL))
-        {
-            /* This specific digest has already been included, so skip it */
-            continue;
-        }
-        pad = pad_to(pos, fundamental_block_size);
-        if (Fwrite(zeros, sizeof(char), pad, fdo) != pad)
-        {
-            fprintf(stderr, _("Unable to write padding\n"));
-            rc = RPMRC_FAIL;
-            goto exit;
-        }
-        /* round up to next fundamental_block_size */
-        pos += pad;
-        digestSetAddEntry(ds, digest);
-        offsets[offset_ix].digest = digest;
-        offsets[offset_ix].pos = pos;
-        offset_ix++;
-        size = rpmfiFSize(fi);
-        rc = rpmfiArchiveReadToFile(fi, fdo, 0);
-        if (rc != RPMRC_OK)
-        {
-            fprintf(stderr, _("rpmfiArchiveReadToFile failed with %d\n"), rc);
-            goto exit;
-        }
-        pos += size;
+    while (next >= 0) {
+	next = rpmfiNext(fi);
+	if (next == RPMERR_ITER_END) {
+	    rc = RPMRC_OK;
+	    break;
+	}
+	mode = rpmfiFMode(fi);
+	if (!S_ISREG(mode) || !rpmfiArchiveHasContent(fi)) {
+	    /* not a regular file, or the archive doesn't contain any content
+	     * for this entry.
+	    */
+	    continue;
+	}
+	digest = rpmfiFDigest(fi, NULL, NULL);
+	if (digestSetGetEntry(ds, digest, NULL)) {
+	    /* This specific digest has already been included, so skip it. */
+	    continue;
+	}
+	pad = pad_to(pos, fundamental_block_size);
+	if (Fwrite(zeros, sizeof(char), pad, fdo) != pad) {
+	    fprintf(stderr, _("Unable to write padding\n"));
+	    rc = RPMRC_FAIL;
+	    goto exit;
+	}
+	/* round up to next fundamental_block_size */
+	pos += pad;
+	digestSetAddEntry(ds, digest);
+	offsets[offset_ix].digest = digest;
+	offsets[offset_ix].pos = pos;
+	offset_ix++;
+	size = rpmfiFSize(fi);
+	rc = rpmfiArchiveReadToFile(fi, fdo, 0);
+	if (rc != RPMRC_OK) {
+	    fprintf(stderr, _("rpmfiArchiveReadToFile failed with %d\n"), rc);
+	    goto exit;
+	}
+	pos += size;
     }
     Fclose(gzdi);	/* XXX gzdi == fdi */
 
-    qsort(
-        offsets,
-        (size_t)offset_ix,
-        sizeof(struct digestoffset),
-        digestoffsetCmp
-    );
+    qsort(offsets, (size_t)offset_ix, sizeof(struct digestoffset),
+	  digestoffsetCmp);
 
     len = sizeof(offset_ix);
-    if (Fwrite(&offset_ix, len, 1, fdo) != len)
-    {
-        fprintf(stderr, _("Unable to write length of table\n"));
-        rc = RPMRC_FAIL;
-        goto exit;
+    if (Fwrite(&offset_ix, len, 1, fdo) != len) {
+	fprintf(stderr, _("Unable to write length of table\n"));
+	rc = RPMRC_FAIL;
+	goto exit;
     }
     len = sizeof(diglen);
-    if (Fwrite(&diglen, len, 1, fdo) != len)
-    {
-        fprintf(stderr, _("Unable to write length of digest\n"));
-        rc = RPMRC_FAIL;
-        goto exit;
+    if (Fwrite(&diglen, len, 1, fdo) != len) {
+	fprintf(stderr, _("Unable to write length of digest\n"));
+	rc = RPMRC_FAIL;
+	goto exit;
     }
     len = sizeof(rpm_loff_t);
-    for (int x = 0; x < offset_ix; x++)
-    {
-        if (Fwrite(offsets[x].digest, diglen, 1, fdo) != diglen)
-        {
-            fprintf(stderr, _("Unable to write digest\n"));
-            rc = RPMRC_FAIL;
-            goto exit;
-        }
-        if (Fwrite(&offsets[x].pos, len, 1, fdo) != len)
-        {
-            fprintf(stderr, _("Unable to write offset\n"));
-            rc = RPMRC_FAIL;
-            goto exit;
-        }
+    for (int x = 0; x < offset_ix; x++) {
+	if (Fwrite(offsets[x].digest, diglen, 1, fdo) != diglen) {
+	    fprintf(stderr, _("Unable to write digest\n"));
+	    rc = RPMRC_FAIL;
+	    goto exit;
+	}
+	if (Fwrite(&offsets[x].pos, len, 1, fdo) != len) {
+	    fprintf(stderr, _("Unable to write offset\n"));
+	    rc = RPMRC_FAIL;
+	    goto exit;
+	}
     }
     validation_pos = (
-        pos + sizeof(offset_ix) + sizeof(diglen) +
-        offset_ix * (diglen + sizeof(rpm_loff_t))
+	pos + sizeof(offset_ix) + sizeof(diglen) +
+	offset_ix * (diglen + sizeof(rpm_loff_t))
     );
 
     ssize_t validation_len = ufdCopy(validationi, fdo);
-    if (validation_len == -1)
-    {
-        fprintf(stderr, _("digest table ufdCopy failed\n"));
-        rc = RPMRC_FAIL;
-        goto exit;
+    if (validation_len == -1) {
+	fprintf(stderr, _("digest table ufdCopy failed\n"));
+	rc = RPMRC_FAIL;
+	goto exit;
     }
     /* add more padding so the last file can be cloned. It doesn't matter that
-       the table and validation etc are in this space. In fact, it's pretty
-       efficient if it is
+     * the table and validation etc are in this space. In fact, it's pretty
+     * efficient if it is.
     */
 
-    pad = pad_to(
-        (
-            validation_pos + validation_len + 2 * sizeof(rpm_loff_t) +
-            sizeof(uint64_t)
-        ),
-        fundamental_block_size
-    );
-    if (Fwrite(zeros, sizeof(char), pad, fdo) != pad)
-    {
-        fprintf(stderr, _("Unable to write final padding\n"));
-        rc = RPMRC_FAIL;
-        goto exit;
+    pad = pad_to((validation_pos + validation_len + 2 * sizeof(rpm_loff_t) +
+		 sizeof(uint64_t)), fundamental_block_size);
+    if (Fwrite(zeros, sizeof(char), pad, fdo) != pad) {
+	fprintf(stderr, _("Unable to write final padding\n"));
+	rc = RPMRC_FAIL;
+	goto exit;
     }
     zeros = _free(zeros);
-    if (Fwrite(&pos, len, 1, fdo) != len)
-    {
-        fprintf(stderr, _("Unable to write offset of digest table\n"));
-        rc = RPMRC_FAIL;
-        goto exit;
+    if (Fwrite(&pos, len, 1, fdo) != len) {
+	fprintf(stderr, _("Unable to write offset of digest table\n"));
+	rc = RPMRC_FAIL;
+	goto exit;
     }
-    if (Fwrite(&validation_pos, len, 1, fdo) != len)
-    {
-        fprintf(stderr, _("Unable to write offset of validation table\n"));
-        rc = RPMRC_FAIL;
-        goto exit;
+    if (Fwrite(&validation_pos, len, 1, fdo) != len) {
+	fprintf(stderr, _("Unable to write offset of validation table\n"));
+	rc = RPMRC_FAIL;
+	goto exit;
     }
     uint64_t magic = MAGIC;
     len = sizeof(magic);
-    if (Fwrite(&magic, len, 1, fdo) != len)
-    {
-        fprintf(stderr, _("Unable to write magic\n"));
-        rc = RPMRC_FAIL;
-        goto exit;
+    if (Fwrite(&magic, len, 1, fdo) != len) {
+	fprintf(stderr, _("Unable to write magic\n"));
+	rc = RPMRC_FAIL;
+	goto exit;
     }
 
 exit:
@@ -389,8 +327,7 @@ exit:
     return rc;
 }
 
-int main(int argc, char *argv[])
-{
+int main(int argc, char *argv[]) {
     rpmRC rc;
     int cprc = 0;
     uint8_t algos[argc - 1];
@@ -402,118 +339,95 @@ int main(int argc, char *argv[])
     xsetprogname(argv[0]);	/* Portability call -- see system.h */
     rpmReadConfigFiles(NULL, NULL);
 
-    if (argc > 1 && (rstreq(argv[1], "-h") || rstreq(argv[1], "--help")))
-    {
-        fprintf(stderr, _("Usage: %s [DIGESTALGO]...\n"), argv[0]);
-        exit(EXIT_FAILURE);
+    if (argc > 1 && (rstreq(argv[1], "-h") || rstreq(argv[1], "--help"))) {
+	fprintf(stderr, _("Usage: %s [DIGESTALGO]...\n"), argv[0]);
+	exit(EXIT_FAILURE);
     }
 
-    if (argc == 1)
-    {
-        fprintf(
-            stderr,
-            _("Need at least one DIGESTALGO parameter, e.g. 'SHA256'\n")
-        );
-        exit(EXIT_FAILURE);
+    if (argc == 1) {
+	fprintf(stderr,
+		_("Need at least one DIGESTALGO parameter, e.g. 'SHA256'\n"));
+	exit(EXIT_FAILURE);
     }
 
-    for (int x = 0; x < (argc - 1); x++)
-    {
-        if (pgpStringVal(PGPVAL_HASHALGO, argv[x + 1], &algos[x]) != 0)
-        {
-            fprintf(
-                stderr,
-                _("Unable to resolve '%s' as a digest algorithm, exiting\n"),
-                argv[x + 1]
-            );
-            exit(EXIT_FAILURE);
-        }
+    for (int x = 0; x < (argc - 1); x++) {
+	if (pgpStringVal(PGPVAL_HASHALGO, argv[x + 1], &algos[x]) != 0)
+	{
+	    fprintf(stderr,
+		    _("Unable to resolve '%s' as a digest algorithm, exiting\n"),
+		    argv[x + 1]);
+	    exit(EXIT_FAILURE);
+	}
     }
 
 
-    if (pipe(mainpipefd) == -1)
-    {
-        fprintf(stderr, _("Main pipe failure\n"));
-        exit(EXIT_FAILURE);
+    if (pipe(mainpipefd) == -1) {
+	fprintf(stderr, _("Main pipe failure\n"));
+	exit(EXIT_FAILURE);
     }
-    if (pipe(metapipefd) == -1)
-    {
-        fprintf(stderr, _("Meta pipe failure\n"));
-        exit(EXIT_FAILURE);
+    if (pipe(metapipefd) == -1) {
+	fprintf(stderr, _("Meta pipe failure\n"));
+	exit(EXIT_FAILURE);
     }
     cpid = fork();
-    if (cpid == 0)
-    {
-        /* child: digestor */
-        close(mainpipefd[0]);
-        close(metapipefd[0]);
-        FD_t fdi = fdDup(STDIN_FILENO);
-        FD_t fdo = fdDup(mainpipefd[1]);
-        FD_t validationo = fdDup(metapipefd[1]);
-        rc = digestor(fdi, fdo, validationo, algos, argc - 1);
-        Fclose(validationo);
-        Fclose(fdo);
-        Fclose(fdi);
+    if (cpid == 0) {
+	/* child: digestor */
+	close(mainpipefd[0]);
+	close(metapipefd[0]);
+	FD_t fdi = fdDup(STDIN_FILENO);
+	FD_t fdo = fdDup(mainpipefd[1]);
+	FD_t validationo = fdDup(metapipefd[1]);
+	rc = digestor(fdi, fdo, validationo, algos, argc - 1);
+	Fclose(validationo);
+	Fclose(fdo);
+	Fclose(fdi);
     } else {
-        /* parent: main program */
-        close(mainpipefd[1]);
-        close(metapipefd[1]);
-        FD_t fdi = fdDup(mainpipefd[0]);
-        FD_t validationi = fdDup(metapipefd[0]);
-        rc = process_package(fdi, validationi);
-        Fclose(validationi);
-        /* fdi is normally closed through the stacked file gzdi in the function. */
-        /* wait for child process (digestor for stdin) to complete. */
-        if (rc != RPMRC_OK)
-        {
-            if (kill(cpid, SIGTERM) != 0)
-            {
-                fprintf(
-                    stderr,
-                    _("Failed to kill digest process when main process failed: %s\n"),
-                    strerror(errno)
-                );
-            }
-        }
-        w = waitpid(cpid, &wstatus, 0);
-        if (w == -1)
-        {
-            fprintf(stderr, _("waitpid failed\n"));
-            cprc = EXIT_FAILURE;
-        } else if (WIFEXITED(wstatus))
-        {
-            cprc = WEXITSTATUS(wstatus);
-            if (cprc != 0)
-            {
-                fprintf(
-                    stderr,
-                    _("Digest process non-zero exit code %d\n"),
-                    cprc
-                );
-            }
-        } else if (WIFSIGNALED(wstatus))
-        {
-            fprintf(
-                stderr,
-                _("Digest process was terminated with a signal: %d\n"),
-                WTERMSIG(wstatus)
-            );
-            cprc = EXIT_FAILURE;
-        } else
-        {
-            /* don't think this can happen, but covering all bases */
-            fprintf(stderr, _("Unhandled circumstance in waitpid\n"));
-            cprc = EXIT_FAILURE;
-        }
-        if (cprc != EXIT_SUCCESS)
-        {
-            rc = RPMRC_FAIL;
-        }
+	/* parent: main program */
+	close(mainpipefd[1]);
+	close(metapipefd[1]);
+	FD_t fdi = fdDup(mainpipefd[0]);
+	FD_t validationi = fdDup(metapipefd[0]);
+	rc = process_package(fdi, validationi);
+	Fclose(validationi);
+	/* fdi is normally closed through the stacked file gzdi in the
+	 * function.
+	 * Wait for child process (digestor for stdin) to complete.
+	 */
+	if (rc != RPMRC_OK) {
+	    if (kill(cpid, SIGTERM) != 0) {
+		fprintf(stderr,
+		        _("Failed to kill digest process when main process failed: %s\n"),
+			strerror(errno));
+	    }
+	}
+	w = waitpid(cpid, &wstatus, 0);
+	if (w == -1) {
+	    fprintf(stderr, _("waitpid failed\n"));
+	    cprc = EXIT_FAILURE;
+	} else if (WIFEXITED(wstatus)) {
+	    cprc = WEXITSTATUS(wstatus);
+	    if (cprc != 0) {
+		fprintf(stderr,
+			_("Digest process non-zero exit code %d\n"),
+			cprc);
+	    }
+	} else if (WIFSIGNALED(wstatus)) {
+	    fprintf(stderr,
+		    _("Digest process was terminated with a signal: %d\n"),
+		    WTERMSIG(wstatus));
+	    cprc = EXIT_FAILURE;
+	} else {
+	    /* Don't think this can happen, but covering all bases */
+	    fprintf(stderr, _("Unhandled circumstance in waitpid\n"));
+	    cprc = EXIT_FAILURE;
+	}
+	if (cprc != EXIT_SUCCESS) {
+	    rc = RPMRC_FAIL;
+	}
     }
-    if (rc != RPMRC_OK)
-    {
-        /* translate rpmRC into generic failure return code. */
-        return EXIT_FAILURE;
+    if (rc != RPMRC_OK) {
+	/* translate rpmRC into generic failure return code. */
+	return EXIT_FAILURE;
     }
     return EXIT_SUCCESS;
 }
-- 
2.35.1