file_id_unittest: avoid system()

We have API's for copying files & changing file modes, so there's
no sense in using system() to run programs to do that.

For the strip call, do the minimal spawn+wait dance.  This avoids
weird quoting string issues at least.

Change-Id: Ibda117f243e886c0c7fcf8076fb8602b8d3ba42d
Reviewed-on: https://chromium-review.googlesource.com/c/breakpad/breakpad/+/2396558
Reviewed-by: Mark Mentovai <mark@chromium.org>
diff --git a/src/common/linux/file_id_unittest.cc b/src/common/linux/file_id_unittest.cc
index 477783d..8225e5a 100644
--- a/src/common/linux/file_id_unittest.cc
+++ b/src/common/linux/file_id_unittest.cc
@@ -30,7 +30,10 @@
 // Unit tests for FileID
 
 #include <elf.h>
+#include <spawn.h>
 #include <stdlib.h>
+#include <sys/types.h>
+#include <sys/wait.h>
 
 #include <string>
 #include <vector>
@@ -42,6 +45,7 @@
 #include "common/linux/synth_elf.h"
 #include "common/test_assembler.h"
 #include "common/tests/auto_tempdir.h"
+#include "common/tests/file_utils.h"
 #include "common/using_std_string.h"
 #include "breakpad_googletest_includes.h"
 
@@ -80,13 +84,18 @@
   // copy our binary to a temp file, and strip it
   AutoTempDir temp_dir;
   string templ = temp_dir.path() + "/file-id-unittest";
-  char cmdline[4096];
-  sprintf(cmdline, "cp \"%s\" \"%s\"", exe_name, templ.c_str());
-  ASSERT_EQ(0, system(cmdline)) << "Failed to execute: " << cmdline;
-  sprintf(cmdline, "chmod u+w \"%s\"", templ.c_str());
-  ASSERT_EQ(0, system(cmdline)) << "Failed to execute: " << cmdline;
-  sprintf(cmdline, "strip \"%s\"", templ.c_str());
-  ASSERT_EQ(0, system(cmdline)) << "Failed to execute: " << cmdline;
+  ASSERT_TRUE(CopyFile(exe_name, templ));
+  pid_t pid;
+  char* argv[] = {
+      const_cast<char*>("strip"),
+      const_cast<char*>(templ.c_str()),
+      nullptr,
+  };
+  ASSERT_EQ(0, posix_spawnp(&pid, argv[0], nullptr, nullptr, argv, nullptr));
+  int status;
+  ASSERT_EQ(pid, waitpid(pid, &status, 0));
+  ASSERT_TRUE(WIFEXITED(status));
+  ASSERT_EQ(0, WEXITSTATUS(status));
 
   PageAllocator allocator;
   id_vector identifier1(&allocator, kDefaultBuildIdSize);