2025-12-25 04:06:29 +01:00
|
|
|
/*
|
|
|
|
|
* util.cpp
|
|
|
|
|
*
|
|
|
|
|
* Created on: Aug 31, 2015
|
|
|
|
|
* Author: Yen-Sheng Ho
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <iomanip>
|
|
|
|
|
#include <csignal>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
2025-12-25 04:47:46 +01:00
|
|
|
#include "misc/util/abc_namespaces.h"
|
2025-12-25 04:06:29 +01:00
|
|
|
#include "util.h"
|
|
|
|
|
|
2025-12-25 04:47:46 +01:00
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
|
|
2025-12-25 04:06:29 +01:00
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
unsigned LogT::loglevel = 0;
|
|
|
|
|
string LogT::prefix = "LOG";
|
|
|
|
|
|
|
|
|
|
bool OptMgr::Parse(int argc, char * argv[]) {
|
|
|
|
|
if(argc <= 1) return true;
|
|
|
|
|
|
|
|
|
|
for(int i = 1; i < argc; i++) {
|
|
|
|
|
if(_map.count(argv[i]) == 0)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
Option& opt = _map[argv[i]];
|
|
|
|
|
opt._val = "yes";
|
|
|
|
|
|
|
|
|
|
if(!opt.isBool()) {
|
|
|
|
|
if (i + 1 == argc)
|
|
|
|
|
return false;
|
|
|
|
|
opt._val = argv[++i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void OptMgr::PrintUsage() {
|
|
|
|
|
cout << "usage: " << _cmd << endl;
|
|
|
|
|
cout << " Uninterpreted Function Abstraction and Refinement (UFAR)\n";
|
|
|
|
|
for (auto x : _map) {
|
|
|
|
|
ostringstream ss;
|
|
|
|
|
ss << x.first << " " << (x.second.isBool() ? "" : x.second._arg_type);
|
|
|
|
|
cout << " " << setw(10) << left << ss.str();
|
|
|
|
|
cout << " : " << x.second._help << " [default = " << x.second._default << "]" << endl;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-25 06:08:18 +01:00
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|
|
|
|
2025-12-25 04:06:29 +01:00
|
|
|
#ifdef __linux__
|
|
|
|
|
|
|
|
|
|
#include <sys/prctl.h>
|
|
|
|
|
|
2025-12-25 06:08:18 +01:00
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
|
|
2025-12-25 04:06:29 +01:00
|
|
|
void kill_on_parent_death(int sig)
|
|
|
|
|
{
|
|
|
|
|
// kill process if parent dies
|
|
|
|
|
prctl(PR_SET_PDEATHSIG, sig);
|
|
|
|
|
|
|
|
|
|
// the parent might have died before calling prctl
|
|
|
|
|
// in that case, it would be adopted by init, whose pid is 1
|
|
|
|
|
if (getppid() == 1)
|
|
|
|
|
{
|
|
|
|
|
raise(sig);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-25 06:08:18 +01:00
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|
|
|
|
2025-12-25 04:06:29 +01:00
|
|
|
#elif defined(__APPLE__)
|
|
|
|
|
|
|
|
|
|
#include <thread>
|
|
|
|
|
|
|
|
|
|
#include <cassert>
|
2025-12-25 05:49:55 +01:00
|
|
|
#include <cerrno>
|
2025-12-25 04:06:29 +01:00
|
|
|
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <sys/event.h>
|
|
|
|
|
#include <sys/time.h>
|
|
|
|
|
|
2025-12-25 06:08:18 +01:00
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
|
|
2025-12-25 05:49:55 +01:00
|
|
|
template <typename Func>
|
|
|
|
|
static auto retry_eintr(Func &&fn) -> decltype(fn())
|
|
|
|
|
{
|
|
|
|
|
decltype(fn()) rc;
|
|
|
|
|
do {
|
|
|
|
|
rc = fn();
|
|
|
|
|
} while (rc == -1 && errno == EINTR);
|
|
|
|
|
return rc;
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-25 04:06:29 +01:00
|
|
|
void kill_on_parent_death(int sig)
|
|
|
|
|
{
|
|
|
|
|
const int ppid = getppid();
|
|
|
|
|
|
|
|
|
|
std::thread monitor_thread([ppid, sig](){
|
|
|
|
|
|
|
|
|
|
struct kevent change;
|
|
|
|
|
EV_SET(&change, ppid, EVFILT_PROC, EV_ADD, NOTE_EXIT, 0, nullptr);
|
|
|
|
|
|
|
|
|
|
int kq = kqueue();
|
|
|
|
|
assert( kq >= 0 );
|
|
|
|
|
|
|
|
|
|
struct kevent event;
|
|
|
|
|
struct timespec ts = {0, 0};
|
|
|
|
|
|
|
|
|
|
// start listening, we are guaranteed to receive a notification if ppid is dead
|
|
|
|
|
kevent(kq, &change, 1, &event, 1, &ts);
|
|
|
|
|
|
|
|
|
|
// however, if ppid died before the call to kevent, ppid might not be the pid of the parent
|
|
|
|
|
// in that case, the process it would be adopted by init, whose pid is 1
|
|
|
|
|
if( getppid() == 1 )
|
|
|
|
|
{
|
|
|
|
|
raise(sig);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// now block on kevent until the the parent process dies
|
|
|
|
|
retry_eintr([&](){
|
|
|
|
|
return kevent(kq, &change, 1, &event, 1, nullptr);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
raise(sig);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
monitor_thread.detach();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-25 06:08:18 +01:00
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|
|
|
|
2025-12-25 04:06:29 +01:00
|
|
|
#else // neither linux or OS X
|
|
|
|
|
|
2025-12-25 06:08:18 +01:00
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
|
|
2025-12-25 04:06:29 +01:00
|
|
|
void kill_on_parent_death(int sig)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-25 04:47:46 +01:00
|
|
|
ABC_NAMESPACE_IMPL_END
|
2025-12-25 06:08:18 +01:00
|
|
|
|
|
|
|
|
#endif
|