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'},
26 {
"stderr", required_argument,
nullptr,
's'},
28 {
nullptr, 0,
nullptr, 0}
33 fprintf(stderr, R
"EOS( 34 This is an internal tool for rosmon. You should not need to call it yourself. 37 _shim [options] --run <executable> [args...] 40 --namespace=NS Put the node in namespace NS 41 --env=A=B Set environment variable A to value B (can be repeated) 42 --coredump Enable coredump collection 43 --coredump-relative=DIR Coredumps should go to DIR 44 --run <executable> All arguments after this one are passed on 45 --tty TTY TTY fd for stdout 46 --stderr FD file descriptor for stderr 50 int main(
int argc,
char** argv)
52 bool coredumpsEnabled =
false;
53 char* coredumpsRelative =
nullptr;
55 char* nodeExecutable =
nullptr;
56 int nodeOptionsBegin = -1;
64 int c = getopt_long(argc, argv,
"h",
OPTIONS, &option_index);
78 setenv(
"ROS_NAMESPACE", optarg, 1);
82 char* value = strchr(optarg,
'=');
84 throw std::invalid_argument(
"Need '=' in --env spec");
88 setenv(optarg, value + 1, 1);
92 coredumpsEnabled =
true;
95 coredumpsRelative = optarg;
101 nodeExecutable = optarg;
102 nodeOptionsBegin = optind;
105 stderr_fd = atoi(optarg);
114 throw std::invalid_argument(
"Need --run option");
117 throw std::invalid_argument(
"Need --tty option");
120 throw std::invalid_argument(
"Need --stderr option");
122 if(login_tty(tty) != 0)
124 perror(
"Could not call login_tty()");
128 if(dup2(stderr_fd, STDERR_FILENO) < 0)
130 perror(
"Could not call dup2() for stderr");
138 if(getrlimit(RLIMIT_CORE, &limit) == 0)
141 if(limit.rlim_cur == 0)
143 limit.rlim_cur = limit.rlim_max;
144 setrlimit(RLIMIT_CORE, &limit);
150 if(coredumpsRelative)
152 if(chdir(coredumpsRelative) != 0)
154 perror(
"Could not change to newly created process working directory");
162 if(getrlimit(RLIMIT_CORE, &limit) == 0)
165 setrlimit(RLIMIT_CORE, &limit);
170 prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY);
173 std::vector<char*> args;
175 args.push_back(nodeExecutable);
177 for(
int i = nodeOptionsBegin; i < argc; ++i)
178 args.push_back(argv[i]);
180 args.push_back(
nullptr);
183 if(execvp(nodeExecutable, args.data()) != 0)
185 std::stringstream ss;
186 for(
const auto& part : args)
189 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)