1// Copyright (c) 2014, Google Inc. 2// All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions are 6// met: 7// 8// * Redistributions of source code must retain the above copyright 9// notice, this list of conditions and the following disclaimer. 10// * Redistributions in binary form must reproduce the above 11// copyright notice, this list of conditions and the following disclaimer 12// in the documentation and/or other materials provided with the 13// distribution. 14// * Neither the name of Google Inc. nor the names of its 15// contributors may be used to endorse or promote products derived from 16// this software without specific prior written permission. 17// 18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30#include <stdio.h> 31#include <sys/wait.h> 32#include <unistd.h> 33 34namespace google_breakpad { 35 36void LaunchReporter(const char *reporter_executable_path, 37 const char *config_file_path) { 38 const char* argv[] = { reporter_executable_path, config_file_path, NULL }; 39 40 // Launch the reporter 41 pid_t pid = fork(); 42 43 if (pid == -1) { 44 perror("fork"); 45 fprintf(stderr, "Failed to fork reporter process\n"); 46 return; 47 } 48 49 // If we're in the child, load in our new executable and run. 50 // The parent will not wait for the child to complete. 51 if (pid == 0) { 52 execv(argv[0], (char* const*)argv); 53 perror("exec"); 54 fprintf(stderr, 55 "Failed to launch reporter process from path %s\n", 56 reporter_executable_path); 57 unlink(config_file_path); // launch failed - get rid of config file 58 _exit(1); 59 } 60 61 // Wait until the Reporter child process exits. 62 // 63 64 // We'll use a timeout of one minute. 65 int timeout_count = 60; // 60 seconds 66 67 while (timeout_count-- > 0) { 68 int status; 69 pid_t result = waitpid(pid, &status, WNOHANG); 70 71 if (result == 0) { 72 // The child has not yet finished. 73 sleep(1); 74 } else if (result == -1) { 75 // error occurred. 76 break; 77 } else { 78 // child has finished 79 break; 80 } 81 } 82} 83 84} // namespace google_breakpad 85