399 bool is_profiler, fs::path working_path = fs::current_path()) {
400 if (wait_for_notify) {
401 this->notifiable =
true;
405 if (this->stdout_redirect && this->stdout_fd !=
nullptr &&
406 *(this->stdout_fd) == -1) {
410 std::vector<std::string> env_entries;
412 for (
auto &entry : this->env) {
413 env_entries.push_back(entry.first +
"=" + entry.second);
416 if (this->notifiable && pipe(this->notify_pipe) == -1) {
420 if (!this->stdout_redirect) {
421 if (pipe(this->stdout_pipe) == -1) {
422 if (this->notifiable) {
423 close_fd(this->notify_pipe[0]);
424 close_fd(this->notify_pipe[1]);
425 this->notifiable =
false;
431 this->stdout_reader = std::make_unique<FileDescriptor>(this->stdout_pipe,
436 if (pipe(this->stdin_pipe) == -1) {
437 if (this->notifiable) {
438 close_fd(this->notify_pipe[0]);
439 close_fd(this->notify_pipe[1]);
440 this->notifiable =
false;
443 if (!this->stdout_redirect) {
444 close_fd(this->stdout_pipe[0]);
445 close_fd(this->stdout_pipe[1]);
451 if (this->writable) {
452 this->stdin_writer = std::make_unique<FileDescriptor>(
nullptr,
457 pid_t forked = fork();
463 if (this->notifiable) {
464 close_fd(this->notify_pipe[1]);
467 int received = ::read(this->notify_pipe[0], &buf, 1);
468 close_fd(this->notify_pipe[0]);
470 if (received <= 0 || buf != 0x03) {
475 close_fd(this->stdin_pipe[1]);
476 close_fd(this->stdout_pipe[0]);
478 fs::current_path(working_path);
480 if (this->stderr_redirect) {
481 int stderr_fd = creat(this->stderr_path.c_str(),
482 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
484 if (stderr_fd == -1) {
488 if (dup2(stderr_fd, STDERR_FILENO) == -1) {
495 if (this->stdout_redirect) {
496 if (!this->stdout_terminal) {
499 if (this->stdout_fd ==
nullptr) {
500 stdout_fd = creat(this->stdout_path.c_str(),
501 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
503 if (stdout_fd == -1) {
507 stdout_fd = *(this->stdout_fd);
510 if (dup2(stdout_fd, STDOUT_FILENO) == -1) {
517 if (dup2(this->stdout_pipe[1], STDOUT_FILENO) == -1) {
521 close_fd(this->stdout_pipe[1]);
524 if (dup2(this->stdin_pipe[0], STDIN_FILENO) == -1) {
528 close_fd(this->stdin_pipe[0]);
530 if (this->command.index() == 0) {
531 std::vector<std::string> elems = std::get<0>(this->command);
532 char *argv[elems.size() + 1];
534 for (
int i = 0; i < elems.size(); i++) {
535 argv[i] = (
char *)elems[i].c_str();
538 argv[elems.size()] =
nullptr;
540 char *env[env_entries.size() + 1];
542 for (
int i = 0; i < env_entries.size(); i++) {
543 env[i] = (
char *)env_entries[i].c_str();
546 env[env_entries.size()] =
nullptr;
549 cpu_set_t affinity = is_profiler ? cpu_config.get_cpu_analysis_set() :
550 cpu_config.get_cpu_workflow_set();
552 if (sched_setaffinity(0,
sizeof(affinity), &affinity) == -1) {
557 execvpe(elems[0].c_str(), argv, env);
571 std::function<int()> func = std::get<1>(this->command);
573 for (
auto &entry : this->env) {
574 if (setenv(entry.first.c_str(), entry.second.c_str(), 1) == -1) {
583 if (this->notifiable) {
584 close_fd(this->notify_pipe[0]);
587 close_fd(this->stdin_pipe[0]);
589 if (this->stdout_redirect && this->stdout_fd !=
nullptr) {
590 close_fd(*(this->stdout_fd));
591 }
else if (!this->stdout_redirect) {
592 close_fd(this->stdout_pipe[1]);
596 if (this->notifiable) {
597 close_fd(this->notify_pipe[1]);
598 this->notifiable =
false;
604 this->started =
true;
608 this->notifiable =
false;