1 /* 2 * Copyright (C) 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 <procinfo/process.h> 18 19 #include <fcntl.h> 20 #include <stdio.h> 21 #include <stdlib.h> 22 #include <string.h> 23 #include <unistd.h> 24 25 #include <string> 26 27 #include <android-base/unique_fd.h> 28 29 using android::base::unique_fd; 30 31 namespace android { 32 namespace procinfo { 33 34 bool GetProcessInfo(pid_t tid, ProcessInfo* process_info) { 35 char path[PATH_MAX]; 36 snprintf(path, sizeof(path), "/proc/%d", tid); 37 38 unique_fd dirfd(open(path, O_DIRECTORY | O_RDONLY)); 39 if (dirfd == -1) { 40 PLOG(ERROR) << "failed to open " << path; 41 return false; 42 } 43 44 return GetProcessInfoFromProcPidFd(dirfd.get(), process_info); 45 } 46 47 bool GetProcessInfoFromProcPidFd(int fd, ProcessInfo* process_info) { 48 int status_fd = openat(fd, "status", O_RDONLY | O_CLOEXEC); 49 50 if (status_fd == -1) { 51 PLOG(ERROR) << "failed to open status fd in GetProcessInfoFromProcPidFd"; 52 return false; 53 } 54 55 std::unique_ptr<FILE, decltype(&fclose)> fp(fdopen(status_fd, "r"), fclose); 56 if (!fp) { 57 PLOG(ERROR) << "failed to open status file in GetProcessInfoFromProcPidFd"; 58 close(status_fd); 59 return false; 60 } 61 62 int field_bitmap = 0; 63 static constexpr int finished_bitmap = 127; 64 char* line = nullptr; 65 size_t len = 0; 66 67 while (getline(&line, &len, fp.get()) != -1 && field_bitmap != finished_bitmap) { 68 char* tab = strchr(line, '\t'); 69 if (tab == nullptr) { 70 continue; 71 } 72 73 size_t header_len = tab - line; 74 std::string header = std::string(line, header_len); 75 if (header == "Name:") { 76 std::string name = line + header_len + 1; 77 78 // line includes the trailing newline. 79 name.pop_back(); 80 process_info->name = std::move(name); 81 82 field_bitmap |= 1; 83 } else if (header == "Pid:") { 84 process_info->tid = atoi(tab + 1); 85 field_bitmap |= 2; 86 } else if (header == "Tgid:") { 87 process_info->pid = atoi(tab + 1); 88 field_bitmap |= 4; 89 } else if (header == "PPid:") { 90 process_info->ppid = atoi(tab + 1); 91 field_bitmap |= 8; 92 } else if (header == "TracerPid:") { 93 process_info->tracer = atoi(tab + 1); 94 field_bitmap |= 16; 95 } else if (header == "Uid:") { 96 process_info->uid = atoi(tab + 1); 97 field_bitmap |= 32; 98 } else if (header == "Gid:") { 99 process_info->gid = atoi(tab + 1); 100 field_bitmap |= 64; 101 } 102 } 103 104 free(line); 105 return field_bitmap == finished_bitmap; 106 } 107 108 } /* namespace procinfo */ 109 } /* namespace android */ 110