| 233 | } |
| 234 | |
| 235 | int ReplxxLineReader::execute(const std::string & command) |
| 236 | { |
| 237 | std::vector<char> argv0("sh", &("sh"[3])); |
| 238 | std::vector<char> argv1("-c", &("-c"[3])); |
| 239 | std::vector<char> argv2(command.data(), command.data() + command.size() + 1); |
| 240 | |
| 241 | const char * filename = "/bin/sh"; |
| 242 | char * const argv[] = {argv0.data(), argv1.data(), argv2.data(), nullptr}; |
| 243 | |
| 244 | static void * real_vfork = dlsym(RTLD_DEFAULT, "vfork"); |
| 245 | if (!real_vfork) |
| 246 | { |
| 247 | rx.print("Cannot find symbol vfork in myself: %s\n", errnoToString(errno).c_str()); |
| 248 | return -1; |
| 249 | } |
| 250 | |
| 251 | pid_t pid = reinterpret_cast<pid_t (*)()>(real_vfork)(); |
| 252 | |
| 253 | if (-1 == pid) |
| 254 | { |
| 255 | rx.print("Cannot vfork: %s\n", errnoToString(errno).c_str()); |
| 256 | return -1; |
| 257 | } |
| 258 | |
| 259 | if (0 == pid) |
| 260 | { |
| 261 | sigset_t mask; |
| 262 | sigemptyset(&mask); |
| 263 | sigprocmask(0, nullptr, &mask); |
| 264 | sigprocmask(SIG_UNBLOCK, &mask, nullptr); |
| 265 | |
| 266 | execv(filename, argv); |
| 267 | _exit(-1); |
| 268 | } |
| 269 | |
| 270 | int status = 0; |
| 271 | if (-1 == waitpid(pid, &status, 0)) |
| 272 | { |
| 273 | rx.print("Cannot waitpid: %s\n", errnoToString(errno).c_str()); |
| 274 | return -1; |
| 275 | } |
| 276 | return status; |
| 277 | } |
| 278 | |
| 279 | void ReplxxLineReader::openEditor() |
| 280 | { |
nothing calls this directly
no test coverage detected