update_payload: Adapt subprocess.check_call to py3

In python3, file descriptors(fd) are not passed to child processes, so
the call to 'puffin' fails because puffin cannot receive the file
descriptors passed by applier.py. In python3, there is an option to set
a fd inheritable so the subprocess can access the fd.

BUG=chromium:1027199
TEST=cros_generate_update_payload --src_image ~/trunk/src/build/images/eve/R80-12705.0.2019_11_23_1521-a1/dlc/dummy-dlc/dummy-package/dlc.img --image ~/trunk/src/build/images/eve/R80-12713.0.2019_11_26_0806-a1/dlc/dummy-dlc/dummy-package/dlc.img --output ~/delete/ttt3 --check
TEST=cros_generate_update_payload --src_image  ~/trunk/src/build/images/eve/R80-12697.0.2019_11_21_1601-a1/chromiumos_test_image.bin --image ~/trunk/src/build/images/eve/R80-12713.0.2019_11_26_0806-a1/chromiumos_image.bin --check --output ~/delete/ttt5

Change-Id: I5d68d5a7ce0a128f2438b0d9f2e32167463661c2
Reviewed-on: https://chromium-review.googlesource.com/c/aosp/platform/system/update_engine/+/1938007
Tested-by: Andrew Lassalle <andrewlassalle@chromium.org>
Reviewed-by: Mike Frysinger <vapier@chromium.org>
Reviewed-by: Amin Hassani <ahassani@chromium.org>
Commit-Queue: Mike Frysinger <vapier@chromium.org>
diff --git a/scripts/update_payload/applier.py b/scripts/update_payload/applier.py
index ce1998f..29ccb8e 100644
--- a/scripts/update_payload/applier.py
+++ b/scripts/update_payload/applier.py
@@ -398,11 +398,19 @@
       # Diff from source partition.
       old_file_name = '/dev/fd/%d' % old_part_file.fileno()
 
+      # In python3, file descriptors(fd) are not passed to child processes by
+      # default. To pass the fds to the child processes, we need to set the flag
+      # 'inheritable' in the fds and make the subprocess calls with the argument
+      # close_fds set to False.
+      if sys.version_info.major >= 3:
+        os.set_inheritable(new_part_file.fileno(), True)
+        os.set_inheritable(old_part_file.fileno(), True)
+
       if op.type in (common.OpType.SOURCE_BSDIFF, common.OpType.BROTLI_BSDIFF):
         # Invoke bspatch on partition file with extents args.
         bspatch_cmd = [self.bspatch_path, old_file_name, new_file_name,
                        patch_file_name, in_extents_arg, out_extents_arg]
-        subprocess.check_call(bspatch_cmd)
+        subprocess.check_call(bspatch_cmd, close_fds=False)
       elif op.type == common.OpType.PUFFDIFF:
         # Invoke puffpatch on partition file with extents args.
         puffpatch_cmd = [self.puffpatch_path,
@@ -412,7 +420,7 @@
                          "--patch_file=%s" % patch_file_name,
                          "--src_extents=%s" % in_extents_arg,
                          "--dst_extents=%s" % out_extents_arg]
-        subprocess.check_call(puffpatch_cmd)
+        subprocess.check_call(puffpatch_cmd, close_fds=False)
       else:
         raise PayloadError("Unknown operation %s" % op.type)