15 #include <sys/resource.h> 16 #include <sys/prctl.h> 19 {
"help", no_argument,
nullptr,
'h'},
20 {
"namespace", required_argument,
nullptr,
'n'},
21 {
"env", required_argument,
nullptr,
'e'},
22 {
"coredump", no_argument,
nullptr,
'c'},
23 {
"coredump-relative", required_argument,
nullptr,
'C'},
24 {
"tty", required_argument,
nullptr,
't'},
25 {
"run", required_argument,
nullptr,
'r'},
27 {
nullptr, 0,
nullptr, 0}
32 fprintf(stderr, R
"EOS( 33 This is an internal tool for rosmon. You should not need to call it yourself. 36 _shim [options] --run <executable> [args...] 39 --namespace=NS Put the node in namespace NS 40 --env=A=B Set environment variable A to value B (can be repeated) 41 --coredump Enable coredump collection 42 --coredump-relative=DIR Coredumps should go to DIR 43 --run <executable> All arguments after this one are passed on 47 int main(
int argc,
char** argv)
49 bool coredumpsEnabled =
false;
50 char* coredumpsRelative =
nullptr;
52 char* nodeExecutable =
nullptr;
53 int nodeOptionsBegin = -1;
60 int c = getopt_long(argc, argv,
"h",
OPTIONS, &option_index);
74 setenv(
"ROS_NAMESPACE", optarg, 1);
78 char* value = strchr(optarg,
'=');
80 throw std::invalid_argument(
"Need '=' in --env spec");
84 setenv(optarg, value + 1, 1);
88 coredumpsEnabled =
true;
91 coredumpsRelative = optarg;
97 nodeExecutable = optarg;
98 nodeOptionsBegin = optind;
107 throw std::invalid_argument(
"Need --run option");
110 throw std::invalid_argument(
"Need --tty option");
112 if(login_tty(tty) != 0)
114 perror(
"Could not call login_tty()");
122 if(getrlimit(RLIMIT_CORE, &limit) == 0)
125 if(limit.rlim_cur == 0)
127 limit.rlim_cur = limit.rlim_max;
128 setrlimit(RLIMIT_CORE, &limit);
134 if(coredumpsRelative)
136 if(chdir(coredumpsRelative) != 0)
138 perror(
"Could not change to newly created process working directory");
146 if(getrlimit(RLIMIT_CORE, &limit) == 0)
149 setrlimit(RLIMIT_CORE, &limit);
154 prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY);
157 std::vector<char*> args;
159 args.push_back(nodeExecutable);
161 for(
int i = nodeOptionsBegin; i < argc; ++i)
162 args.push_back(argv[i]);
165 if(execvp(nodeExecutable, args.data()) != 0)
167 std::stringstream ss;
168 for(
const auto& part : args)
171 fprintf(stderr,
"Could not execute %s: %s\n", ss.str().c_str(), strerror(errno));
static const struct option OPTIONS[]
int main(int argc, char **argv)