Movatterモバイル変換


[0]ホーム

URL:


Google Git
Sign in
chromium /chromium /src /refs/heads/main /. /base /linux_util.cc
blob: 25e5eca0d1014506459b79ab7b5356075288eaa6 [file] [log] [blame] [edit]
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/390223051): Remove C-library calls to fix the errors.
#pragma allow_unsafe_libc_calls
#endif
#include"base/linux_util.h"
#include<dirent.h>
#include<errno.h>
#include<fcntl.h>
#include<limits.h>
#include<stdlib.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<unistd.h>
#include<iomanip>
#include<memory>
#include<string_view>
#include"base/base_export.h"
#include"base/files/dir_reader_posix.h"
#include"base/files/file_util.h"
#include"base/files/scoped_file.h"
#include"base/strings/safe_sprintf.h"
#include"base/strings/span_printf.h"
#include"base/strings/string_number_conversions.h"
#include"base/strings/string_split.h"
#include"base/strings/string_tokenizer.h"
#include"base/strings/string_util.h"
#include"build/build_config.h"
namespace base{
namespace{
#if !BUILDFLAG(IS_CHROMEOS)
std::stringGetKeyValueFromOSReleaseFile(const std::string& input,
constchar* key){
StringPairs key_value_pairs;
SplitStringIntoKeyValuePairs(input,'=','\n',&key_value_pairs);
for(constauto& pair: key_value_pairs){
const std::string& key_str= pair.first;
const std::string& value_str= pair.second;
if(key_str== key){
// It can contain quoted characters.
std::stringstream ss;
std::string pretty_name;
ss<< value_str;
// Quoted with a single tick?
if(value_str[0]=='\''){
ss>> std::quoted(pretty_name,'\'');
}else{
ss>> std::quoted(pretty_name);
}
return pretty_name;
}
}
return"";
}
boolReadDistroFromOSReleaseFile(constchar* file){
staticconstchar kPrettyName[]="PRETTY_NAME";
std::string os_release_content;
if(!ReadFileToString(FilePath(file),&os_release_content)){
returnfalse;
}
std::string pretty_name=
GetKeyValueFromOSReleaseFile(os_release_content, kPrettyName);
if(pretty_name.empty()){
returnfalse;
}
SetLinuxDistro(pretty_name);
returntrue;
}
// https://www.freedesktop.org/software/systemd/man/os-release.html
classDistroNameGetter{
public:
DistroNameGetter(){
staticconstchar*const kFilesToCheck[]={"/etc/os-release",
"/usr/lib/os-release"};
for(constchar* file: kFilesToCheck){
if(ReadDistroFromOSReleaseFile(file)){
return;
}
}
}
};
#endif// !BUILDFLAG(IS_CHROMEOS)
boolGetThreadsFromProcessDir(constchar* dir_path, std::vector<pid_t>* tids){
DirReaderPosix dir_reader(dir_path);
if(!dir_reader.IsValid()){
DLOG(WARNING)<<"Cannot open "<< dir_path;
returnfalse;
}
while(dir_reader.Next()){
pid_t tid;
if(StringToInt(dir_reader.name(),&tid)){
tids->push_back(tid);
}
}
returntrue;
}
// Account for the terminating null character.
constexprint kDistroSize=128+1;
}// namespace
// We use this static string to hold the Linux distro info. If we
// crash, the crash handler code will send this in the crash dump.
char g_linux_distro[kDistroSize]=
#if BUILDFLAG(IS_CHROMEOS)
"CrOS";
#elif BUILDFLAG(IS_ANDROID)
"Android";
#else
"Unknown";
#endif
// This function is only supposed to be used in tests. The declaration in the
// header file is guarded by "#if defined(UNIT_TEST)" so that they can be used
// by tests but not non-test code. However, this .cc file is compiled as part
// of "base" where "UNIT_TEST" is not defined. So we need to specify
// "BASE_EXPORT" here again so that they are visible to tests.
BASE_EXPORT std::stringGetKeyValueFromOSReleaseFileForTesting(
const std::string& input,
constchar* key){
#if !BUILDFLAG(IS_CHROMEOS)
returnGetKeyValueFromOSReleaseFile(input, key);
#else
return"";
#endif// !BUILDFLAG(IS_CHROMEOS)
}
std::stringGetLinuxDistro(){
#if !BUILDFLAG(IS_CHROMEOS)
// We do this check only once per process. If it fails, there's
// little reason to believe it will work if we attempt to run it again.
staticDistroNameGetter distro_name_getter;
#endif
return g_linux_distro;
}
voidSetLinuxDistro(const std::string& distro){
std::string trimmed_distro;
TrimWhitespaceASCII(distro, TRIM_ALL,&trimmed_distro);
strlcpy(g_linux_distro, trimmed_distro.c_str(), kDistroSize);
}
boolGetThreadsForProcess(pid_t pid, std::vector<pid_t>* tids){
// 25 > strlen("/proc//task") + strlen(base::NumberToString(INT_MAX)) + 1 = 22
char buf[25];
strings::SafeSPrintf(buf,"/proc/%d/task", pid);
returnGetThreadsFromProcessDir(buf, tids);
}
boolGetThreadsForCurrentProcess(std::vector<pid_t>* tids){
returnGetThreadsFromProcessDir("/proc/self/task", tids);
}
pid_tFindThreadIDWithSyscall(pid_t pid,
const std::string& expected_data,
bool* syscall_supported){
if(syscall_supported){
*syscall_supported=false;
}
std::vector<pid_t> tids;
if(!GetThreadsForProcess(pid,&tids)){
return-1;
}
std::vector<char> syscall_data(expected_data.size());
for(pid_t tid: tids){
char buf[256];
base::SpanPrintf(buf,"/proc/%d/task/%d/syscall", pid, tid);
ScopedFD fd(open(buf, O_RDONLY));
if(!fd.is_valid()){
continue;
}
*syscall_supported=true;
if(!ReadFromFD(fd.get(), syscall_data)){
continue;
}
if(0== strncmp(expected_data.c_str(), syscall_data.data(),
expected_data.size())){
return tid;
}
}
return-1;
}
pid_tFindThreadID(pid_t pid,pid_t ns_tid,bool* ns_pid_supported){
*ns_pid_supported=false;
std::vector<pid_t> tids;
if(!GetThreadsForProcess(pid,&tids)){
return-1;
}
for(pid_t tid: tids){
char buf[256];
base::SpanPrintf(buf,"/proc/%d/task/%d/status", pid, tid);
std::string status;
if(!ReadFileToString(FilePath(buf),&status)){
return-1;
}
StringTokenizer tokenizer(status,"\n");
while(std::optional<std::string_view> token=
tokenizer.GetNextTokenView()){
if(!StartsWith(token.value(),"NSpid")){
continue;
}
*ns_pid_supported=true;
std::vector<std::string_view> split_value_str=SplitStringPiece(
token.value(),"\t", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY);
DCHECK_GE(split_value_str.size(),2u);
int value;
// The last value in the list is the PID in the namespace.
if(StringToInt(split_value_str.back(),&value)&& value== ns_tid){
// The second value in the list is the real PID.
if(StringToInt(split_value_str[1],&value)){
return value;
}
}
break;
}
}
return-1;
}
}// namespace base

[8]ページ先頭

©2009-2025 Movatter.jp