Home | History | Annotate | Download | only in debuggerd
      1 /*
      2  * Copyright 2016, The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "util.h"
     18 
     19 #include <sys/socket.h>
     20 
     21 #include <string>
     22 #include <utility>
     23 
     24 #include <android-base/file.h>
     25 #include <android-base/stringprintf.h>
     26 #include <android-base/strings.h>
     27 #include <android-base/unique_fd.h>
     28 #include <cutils/sockets.h>
     29 #include "protocol.h"
     30 
     31 using android::base::unique_fd;
     32 
     33 ssize_t send_fd(int sockfd, const void* data, size_t len, unique_fd fd) {
     34   char cmsg_buf[CMSG_SPACE(sizeof(int))];
     35 
     36   iovec iov = { .iov_base = const_cast<void*>(data), .iov_len = len };
     37   msghdr msg = {
     38     .msg_iov = &iov, .msg_iovlen = 1, .msg_control = cmsg_buf, .msg_controllen = sizeof(cmsg_buf),
     39   };
     40   auto cmsg = CMSG_FIRSTHDR(&msg);
     41   cmsg->cmsg_level = SOL_SOCKET;
     42   cmsg->cmsg_type = SCM_RIGHTS;
     43   cmsg->cmsg_len = CMSG_LEN(sizeof(int));
     44   *reinterpret_cast<int*>(CMSG_DATA(cmsg)) = fd.get();
     45 
     46   return TEMP_FAILURE_RETRY(sendmsg(sockfd, &msg, 0));
     47 }
     48 
     49 ssize_t recv_fd(int sockfd, void* _Nonnull data, size_t len, unique_fd* _Nullable out_fd) {
     50   char cmsg_buf[CMSG_SPACE(sizeof(int))];
     51 
     52   iovec iov = { .iov_base = const_cast<void*>(data), .iov_len = len };
     53   msghdr msg = {
     54     .msg_iov = &iov,
     55     .msg_iovlen = 1,
     56     .msg_control = cmsg_buf,
     57     .msg_controllen = sizeof(cmsg_buf),
     58     .msg_flags = 0,
     59   };
     60   auto cmsg = CMSG_FIRSTHDR(&msg);
     61   cmsg->cmsg_level = SOL_SOCKET;
     62   cmsg->cmsg_type = SCM_RIGHTS;
     63   cmsg->cmsg_len = CMSG_LEN(sizeof(int));
     64 
     65   ssize_t result = TEMP_FAILURE_RETRY(recvmsg(sockfd, &msg, 0));
     66   if (result == -1) {
     67     return -1;
     68   }
     69 
     70   unique_fd fd;
     71   bool received_fd = msg.msg_controllen == sizeof(cmsg_buf);
     72   if (received_fd) {
     73     fd.reset(*reinterpret_cast<int*>(CMSG_DATA(cmsg)));
     74   }
     75 
     76   if ((msg.msg_flags & MSG_TRUNC) != 0) {
     77     errno = EFBIG;
     78     return -1;
     79   } else if ((msg.msg_flags & MSG_CTRUNC) != 0) {
     80     errno = ERANGE;
     81     return -1;
     82   }
     83 
     84   if (out_fd) {
     85     *out_fd = std::move(fd);
     86   } else if (received_fd) {
     87     errno = ERANGE;
     88     return -1;
     89   }
     90 
     91   return result;
     92 }
     93 
     94 std::string get_process_name(pid_t pid) {
     95   std::string result = "<unknown>";
     96   android::base::ReadFileToString(android::base::StringPrintf("/proc/%d/cmdline", pid), &result);
     97   return result;
     98 }
     99 
    100 std::string get_thread_name(pid_t tid) {
    101   std::string result = "<unknown>";
    102   android::base::ReadFileToString(android::base::StringPrintf("/proc/%d/comm", tid), &result);
    103   return android::base::Trim(result);
    104 }
    105