409 bool is_analysis, fs::path working_path = fs::current_path()) {
410 if (wait_for_notify) {
411 this->notifiable =
true;
415 if (this->stdout_redirect && this->stdout_fd !=
nullptr &&
416 *(this->stdout_fd) == -1) {
420 std::vector<std::string> env_entries;
422 for (
auto &entry : this->env) {
423 env_entries.push_back(entry.first +
"=" + entry.second);
426 if (this->notifiable && pipe(this->notify_pipe) == -1) {
430 if (!this->stdout_redirect) {
431 if (pipe(this->stdout_pipe) == -1) {
432 if (this->notifiable) {
433 close_fd(this->notify_pipe[0]);
434 close_fd(this->notify_pipe[1]);
435 this->notifiable =
false;
441 this->stdout_reader = std::make_unique<FileDescriptor>(this->stdout_pipe,
446 if (pipe(this->stdin_pipe) == -1) {
447 if (this->notifiable) {
448 close_fd(this->notify_pipe[0]);
449 close_fd(this->notify_pipe[1]);
450 this->notifiable =
false;
453 if (!this->stdout_redirect) {
454 close_fd(this->stdout_pipe[0]);
455 close_fd(this->stdout_pipe[1]);
461 if (this->writable) {
462 this->stdin_writer = std::make_unique<FileDescriptor>(
nullptr,
467 pid_t forked = fork();
473 if (this->notifiable) {
474 close_fd(this->notify_pipe[1]);
477 int received = ::read(this->notify_pipe[0], &buf, 1);
478 close_fd(this->notify_pipe[0]);
480 if (received <= 0 || buf != 0x03) {
485 close_fd(this->stdin_pipe[1]);
486 close_fd(this->stdout_pipe[0]);
488 fs::current_path(working_path);
490 if (this->stderr_redirect) {
491 int stderr_fd = creat(this->stderr_path.c_str(),
492 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
494 if (stderr_fd == -1) {
498 if (dup2(stderr_fd, STDERR_FILENO) == -1) {
505 if (this->stdout_redirect) {
506 if (!this->stdout_terminal) {
509 if (this->stdout_fd ==
nullptr) {
510 stdout_fd = creat(this->stdout_path.c_str(),
511 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
513 if (stdout_fd == -1) {
517 stdout_fd = *(this->stdout_fd);
520 if (dup2(stdout_fd, STDOUT_FILENO) == -1) {
527 if (dup2(this->stdout_pipe[1], STDOUT_FILENO) == -1) {
531 close_fd(this->stdout_pipe[1]);
534 if (dup2(this->stdin_pipe[0], STDIN_FILENO) == -1) {
538 close_fd(this->stdin_pipe[0]);
540 if (this->command.index() == 0) {
541 std::vector<std::string> elems = std::get<0>(this->command);
542 char *argv[elems.size() + 1];
544 for (
int i = 0; i < elems.size(); i++) {
545 argv[i] = (
char *)elems[i].c_str();
548 argv[elems.size()] =
nullptr;
550 char *env[env_entries.size() + 1];
552 for (
int i = 0; i < env_entries.size(); i++) {
553 env[i] = (
char *)env_entries[i].c_str();
556 env[env_entries.size()] =
nullptr;
559 cpu_set_t affinity = is_analysis ? cpu_config.get_cpu_analysis_set() :
560 cpu_config.get_cpu_workflow_set();
562 if (sched_setaffinity(0,
sizeof(affinity), &affinity) == -1) {
567 execvpe(elems[0].c_str(), argv, env);
581 std::function<int()> func = std::get<1>(this->command);
583 for (
auto &entry : this->env) {
584 if (setenv(entry.first.c_str(), entry.second.c_str(), 1) == -1) {
593 if (this->notifiable) {
594 close_fd(this->notify_pipe[0]);
597 close_fd(this->stdin_pipe[0]);
599 if (this->stdout_redirect && this->stdout_fd !=
nullptr) {
600 close_fd(*(this->stdout_fd));
601 }
else if (!this->stdout_redirect) {
602 close_fd(this->stdout_pipe[1]);
606 if (this->notifiable) {
607 close_fd(this->notify_pipe[1]);
608 this->notifiable =
false;
614 this->started =
true;
618 this->notifiable =
false;