11#include <kj/string-tree.h>
15#include <sys/resource.h>
16#include <sys/socket.h>
18#include <system_error>
25#include <sys/syscall.h>
28#ifdef HAVE_PTHREAD_GETTHREADID_NP
29#include <pthread_np.h>
39 if (getrlimit(RLIMIT_NOFILE, &nofile) == 0) {
40 return nofile.rlim_cur - 1;
50 char thread_name[16] = {0};
51#ifdef HAVE_PTHREAD_GETNAME_NP
52 pthread_getname_np(pthread_self(), thread_name,
sizeof(thread_name));
55 std::ostringstream buffer;
56 buffer << (exe_name ? exe_name :
"") <<
"-" << getpid() <<
"/";
58 if (thread_name[0] !=
'\0') {
59 buffer << thread_name <<
"-";
65 buffer << syscall(SYS_gettid);
66#elif defined(HAVE_PTHREAD_THREADID_NP)
68 pthread_threadid_np(NULL, &tid);
70#elif defined(HAVE_PTHREAD_GETTHREADID_NP)
71 buffer << pthread_getthreadid_np();
73 buffer << std::this_thread::get_id();
76 return std::move(buffer).str();
79std::string
LogEscape(
const kj::StringTree&
string,
size_t max_size)
82 string.visit([&](
const kj::ArrayPtr<const char>& piece) {
83 if (result.size() > max_size)
return;
84 for (
const char c : piece) {
86 result.append(
"\\\\");
87 }
else if (c < 0x20 || c > 0x7e) {
89 snprintf(escape, 4,
"\\%02x", c);
90 result.append(escape);
94 if (result.size() > max_size) {
106 if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) != 0) {
107 throw std::system_error(errno, std::system_category(),
"socketpair");
112 throw std::system_error(errno, std::system_category(),
"fork");
115 if (close(fds[pid ? 0 : 1]) != 0) {
116 throw std::system_error(errno, std::system_category(),
"close");
120 const int maxFd = MaxFd();
121 for (
int fd = 3; fd < maxFd; ++fd) {
133 std::vector<char*> argv;
134 argv.reserve(
args.size());
135 for (
const auto& arg :
args) {
136 argv.push_back(
const_cast<char*
>(arg.c_str()));
138 argv.push_back(
nullptr);
139 if (execvp(argv[0], argv.data()) != 0) {
140 perror(
"execvp failed");
148 if (::waitpid(pid, &status, 0 ) != pid) {
149 throw std::system_error(errno, std::system_category(),
"waitpid");
Functions to serialize / deserialize common bitcoin types.
int WaitProcess(int pid)
Wait for a process to exit and return its exit code.
std::string ThreadName(const char *exe_name)
Format current thread name as "{exe_name}-{$pid}/{thread_name}-{$tid}".
int SpawnProcess(int &pid, FdToArgsFn &&fd_to_args)
Spawn a new process that communicates with the current process over a socket pair.
std::function< std::vector< std::string >(int fd)> FdToArgsFn
Callback type used by SpawnProcess below.
void ExecProcess(const std::vector< std::string > &args)
Call execvp with vector args.
std::string LogEscape(const kj::StringTree &string, size_t max_size)
Escape binary string for use in log so it doesn't trigger unicode decode errors in python unit tests.
for(const CTxIn &txin :tx.vin)