Index: common/mac/launch_reporter.cc |
diff --git a/common/linux/crc32.cc b/common/mac/launch_reporter.cc |
similarity index 55% |
copy from common/linux/crc32.cc |
copy to common/mac/launch_reporter.cc |
index 8df636ce4d73c7d5751d4ea3a68332ebe0d27bd3..245be82659521d0e6fa54430c8bb12d38842efff 100644 |
--- a/common/linux/crc32.cc |
+++ b/common/mac/launch_reporter.cc |
@@ -1,4 +1,4 @@ |
-// Copyright 2014 Google Inc. |
+// Copyright (c) 2014, Google Inc. |
// All rights reserved. |
// |
// Redistribution and use in source and binary forms, with or without |
@@ -27,44 +27,58 @@ |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
-#include "common/linux/crc32.h" |
+#include <stdio.h> |
+#include <sys/wait.h> |
+#include <unistd.h> |
namespace google_breakpad { |
-// This implementation is based on the sample implementation in RFC 1952. |
+void LaunchReporter(const char *reporter_executable_path, |
+ const char *config_file_path) { |
+ const char* argv[] = { reporter_executable_path, config_file_path, NULL }; |
-// CRC32 polynomial, in reversed form. |
-// See RFC 1952, or http://en.wikipedia.org/wiki/Cyclic_redundancy_check |
-static const uint32_t kCrc32Polynomial = 0xEDB88320; |
-static uint32_t kCrc32Table[256] = { 0 }; |
+ // Launch the reporter |
+ pid_t pid = fork(); |
-#define arraysize(f) (sizeof(f) / sizeof(*f)) |
+ if (pid == -1) { |
+ perror("fork"); |
+ fprintf(stderr, "Failed to fork reporter process\n"); |
+ return; |
+ } |
-static void EnsureCrc32TableInited() { |
- if (kCrc32Table[arraysize(kCrc32Table) - 1]) |
- return; // already inited |
- for (uint32_t i = 0; i < arraysize(kCrc32Table); ++i) { |
- uint32_t c = i; |
- for (size_t j = 0; j < 8; ++j) { |
- if (c & 1) { |
- c = kCrc32Polynomial ^ (c >> 1); |
- } else { |
- c >>= 1; |
- } |
- } |
- kCrc32Table[i] = c; |
+ // If we're in the child, load in our new executable and run. |
+ // The parent will not wait for the child to complete. |
+ if (pid == 0) { |
+ execv(argv[0], (char* const*)argv); |
+ perror("exec"); |
+ fprintf(stderr, |
+ "Failed to launch reporter process from path %s\n", |
+ reporter_executable_path); |
+ unlink(config_file_path); // launch failed - get rid of config file |
+ _exit(1); |
} |
-} |
-uint32_t UpdateCrc32(uint32_t start, const void* buf, size_t len) { |
- EnsureCrc32TableInited(); |
+ // Wait until the Reporter child process exits. |
+ // |
- uint32_t c = start ^ 0xFFFFFFFF; |
- const uint8_t* u = static_cast<const uint8_t*>(buf); |
- for (size_t i = 0; i < len; ++i) { |
- c = kCrc32Table[(c ^ u[i]) & 0xFF] ^ (c >> 8); |
+ // We'll use a timeout of one minute. |
+ int timeout_count = 60; // 60 seconds |
+ |
+ while (timeout_count-- > 0) { |
+ int status; |
+ pid_t result = waitpid(pid, &status, WNOHANG); |
+ |
+ if (result == 0) { |
+ // The child has not yet finished. |
+ sleep(1); |
+ } else if (result == -1) { |
+ // error occurred. |
+ break; |
+ } else { |
+ // child has finished |
+ break; |
+ } |
} |
- return c ^ 0xFFFFFFFF; |
} |
} // namespace google_breakpad |