| 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
|
|
|