183e085b7a331c96237cf8e814f97b3ef4c36a70fjimblandy// Copyright (c) 2010 Google Inc. 2f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek// All rights reserved. 3f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek// 4f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek// Redistribution and use in source and binary forms, with or without 5f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek// modification, are permitted provided that the following conditions are 6f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek// met: 7f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek// 8f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek// * Redistributions of source code must retain the above copyright 9f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek// notice, this list of conditions and the following disclaimer. 10f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek// * Redistributions in binary form must reproduce the above 11f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek// copyright notice, this list of conditions and the following disclaimer 12f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek// in the documentation and/or other materials provided with the 13f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek// distribution. 14f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek// * Neither the name of Google Inc. nor the names of its 15f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek// contributors may be used to endorse or promote products derived from 16f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek// this software without specific prior written permission. 17f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek// 18f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek 303daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org#include "client/linux/crash_generation/crash_generation_client.h" 313daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org 32de545c09d0363e6964822ec92529a80feaca152dnealsid#include <stdio.h> 33f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek#include <sys/socket.h> 34f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek#include <sys/types.h> 35f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek 36f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek#include <algorithm> 37f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek 38f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek#include "common/linux/eintr_wrapper.h" 394021866432da1659f6fdd9c4a1fa33aab92a400cthestig@chromium.org#include "common/linux/ignore_ret.h" 400e3b7020b8f679259acfcfdbea4d39e1c13e6f19thestig@chromium.org#include "third_party/lss/linux_syscall_support.h" 41f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek 42f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczareknamespace google_breakpad { 43f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek 443daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.orgnamespace { 453daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org 463daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.orgclass CrashGenerationClientImpl : public CrashGenerationClient { 473daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org public: 483daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org explicit CrashGenerationClientImpl(int server_fd) : server_fd_(server_fd) {} 493daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org virtual ~CrashGenerationClientImpl() {} 503daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org 513daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org virtual bool RequestDump(const void* blob, size_t blob_size) { 523daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org int fds[2]; 532290db8d52d3d4692d25d4918abc31880f1eb31fted.mielczarek@gmail.com if (sys_pipe(fds) < 0) 543daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org return false; 553daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org static const unsigned kControlMsgSize = CMSG_SPACE(sizeof(int)); 563daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org 573daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org struct kernel_iovec iov; 583daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org iov.iov_base = const_cast<void*>(blob); 593daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org iov.iov_len = blob_size; 603daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org 613daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org struct kernel_msghdr msg = { 0 }; 623daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org msg.msg_iov = &iov; 633daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org msg.msg_iovlen = 1; 643daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org char cmsg[kControlMsgSize] = ""; 653daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org msg.msg_control = cmsg; 663daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org msg.msg_controllen = sizeof(cmsg); 67f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek 683daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org struct cmsghdr* hdr = CMSG_FIRSTHDR(&msg); 693daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org hdr->cmsg_level = SOL_SOCKET; 703daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org hdr->cmsg_type = SCM_RIGHTS; 713daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org hdr->cmsg_len = CMSG_LEN(sizeof(int)); 723daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org int* p = reinterpret_cast<int*>(CMSG_DATA(hdr)); 733daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org *p = fds[1]; 743daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org 753daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org ssize_t ret = HANDLE_EINTR(sys_sendmsg(server_fd_, &msg, 0)); 763daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org sys_close(fds[1]); 775d02db696277270a9515010b06589d8cb6e41db7rsesek@chromium.org if (ret < 0) { 785d02db696277270a9515010b06589d8cb6e41db7rsesek@chromium.org sys_close(fds[0]); 793daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org return false; 805d02db696277270a9515010b06589d8cb6e41db7rsesek@chromium.org } 813daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org 823daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org // Wait for an ACK from the server. 833daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org char b; 843daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org IGNORE_RET(HANDLE_EINTR(sys_read(fds[0], &b, 1))); 853daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org sys_close(fds[0]); 863daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org 873daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org return true; 883daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org } 893daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org 903daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org private: 913daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org int server_fd_; 923daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org 933daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org DISALLOW_COPY_AND_ASSIGN(CrashGenerationClientImpl); 943daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org}; 953daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org 963daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org} // namespace 973daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org 983daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org// static 993daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.orgCrashGenerationClient* CrashGenerationClient::TryCreate(int server_fd) { 1003daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org if (server_fd < 0) 101f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek return NULL; 1023daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org return new CrashGenerationClientImpl(server_fd); 103f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek} 104f480ba116971a56d4de25ae1df2369e3d5503d16ted.mielczarek 1053daf3e4247a62dccea7187e94ae06f3ec578f619rsesek@chromium.org} // namespace google_breakpad 106