shim.cpp
Go to the documentation of this file.
1 // Sets up a node process environment and executes the target node
2 // Author: Max Schwarz <max.schwarz@ais.uni-bonn.de>
3 
4 #include <stdexcept>
5 #include <vector>
6 #include <sstream>
7 
8 #include <unistd.h>
9 #include <getopt.h>
10 #include <string.h>
11 
12 #include <utmp.h>
13 
14 #include <sys/time.h>
15 #include <sys/resource.h>
16 #include <sys/prctl.h>
17 
18 static const struct option OPTIONS[] = {
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 
27  {nullptr, 0, nullptr, 0}
28 };
29 
30 void usage()
31 {
32  fprintf(stderr, R"EOS(
33 This is an internal tool for rosmon. You should not need to call it yourself.
34 
35 Usage:
36  _shim [options] --run <executable> [args...]
37 
38 Options:
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
44 )EOS");
45 }
46 
47 int main(int argc, char** argv)
48 {
49  bool coredumpsEnabled = false;
50  char* coredumpsRelative = nullptr;
51 
52  char* nodeExecutable = nullptr;
53  int nodeOptionsBegin = -1;
54 
55  int tty = -1;
56 
57  while(true)
58  {
59  int option_index;
60  int c = getopt_long(argc, argv, "h", OPTIONS, &option_index);
61 
62  if(c == -1)
63  break;
64 
65  switch(c)
66  {
67  case 'h':
68  usage();
69  return 0;
70  case '?':
71  usage();
72  return 1;
73  case 'n':
74  setenv("ROS_NAMESPACE", optarg, 1);
75  break;
76  case 'e':
77  {
78  char* value = strchr(optarg, '=');
79  if(!value)
80  throw std::invalid_argument("Need '=' in --env spec");
81 
82  *value = 0;
83 
84  setenv(optarg, value + 1, 1);
85  break;
86  }
87  case 'c':
88  coredumpsEnabled = true;
89  break;
90  case 'C':
91  coredumpsRelative = optarg;
92  break;
93  case 't':
94  tty = atoi(optarg);
95  break;
96  case 'r':
97  nodeExecutable = optarg;
98  nodeOptionsBegin = optind;
99  break;
100  }
101 
102  if(nodeExecutable)
103  break;
104  }
105 
106  if(!nodeExecutable)
107  throw std::invalid_argument("Need --run option");
108 
109  if(tty < 0)
110  throw std::invalid_argument("Need --tty option");
111 
112  if(login_tty(tty) != 0)
113  {
114  perror("Could not call login_tty()");
115  std::abort();
116  }
117 
118  // Try to enable core dumps
119  if(coredumpsEnabled)
120  {
121  rlimit limit;
122  if(getrlimit(RLIMIT_CORE, &limit) == 0)
123  {
124  // only modify the limit if coredumps are disabled entirely
125  if(limit.rlim_cur == 0)
126  {
127  limit.rlim_cur = limit.rlim_max;
128  setrlimit(RLIMIT_CORE, &limit);
129  }
130  }
131 
132  // If needed for coredump collection with a relative core_pattern,
133  // cd to a temporary directory.
134  if(coredumpsRelative)
135  {
136  if(chdir(coredumpsRelative) != 0)
137  {
138  perror("Could not change to newly created process working directory");
139  }
140  }
141  }
142  else
143  {
144  // Disable coredumps
145  rlimit limit;
146  if(getrlimit(RLIMIT_CORE, &limit) == 0)
147  {
148  limit.rlim_cur = 0;
149  setrlimit(RLIMIT_CORE, &limit);
150  }
151  }
152 
153  // Allow gdb to attach
154  prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY);
155 
156  // Build up argument vector
157  std::vector<char*> args;
158 
159  args.push_back(nodeExecutable);
160 
161  for(int i = nodeOptionsBegin; i < argc; ++i)
162  args.push_back(argv[i]);
163 
164  // Go!
165  if(execvp(nodeExecutable, args.data()) != 0)
166  {
167  std::stringstream ss;
168  for(const auto& part : args)
169  ss << part << " ";
170 
171  fprintf(stderr, "Could not execute %s: %s\n", ss.str().c_str(), strerror(errno));
172  }
173 
174  // We should not arrive here
175  std::abort();
176 }
void usage()
Definition: shim.cpp:30
static const struct option OPTIONS[]
Definition: shim.cpp:18
int main(int argc, char **argv)
Definition: shim.cpp:47


rosmon_core
Author(s): Max Schwarz
autogenerated on Wed Jul 10 2019 03:10:12