Асинхронный запуск и управление процессом в отдельном терминале с получением кода возврата

Мне надо портировать часть кода, написанного для Windows, под Linux, сохранив поведение. В Windows можно из программы запустить отдельный процесс, получить его хэндл и по этому хэндлу ждать завершения процесса и получить его код возврата. Примерно так:

CreateProcessA(NULL, "YourCommandLine", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)
WaitForSingleObject(pi.hProcess, INFINITE);
GetExitCodeProcess(pi.hProcess, &exitCode);

Эти действия происходят асинхронно, не блокируя вызывающий поток. И, что важно, при этом вывод запущенного исполняемого файла не будет перенаправлен в консоль основного процесса. Т.е. если запускается консольное приложение, то для него будет запущена отдельная консоль, в которую и пойдет вывод.

Как добиться аналогичного поведения под Linux?

Я пробовал posix_spawn. Он не блокирует, возвращает pid запущенного процесса, по которому можно ждать его завершения, но не позволяет получить код возврата.

Std::system позволяет получить код возврата, но не выдает никакого идентификатора созданного процесса, поскольку блокирует вызывающий поток. И вывод запущенной на исполнение команды идет в терминал основного процесса.

Я попробовал скомбинировать std::system с std::async, чтобы вместо блокировки основного потока блокировался дочерний.

std::future<int> res = std::async(std::launch::async, [&]() {
    return std::system(commandLine.c_str());
    });

Это позволяет асинхронно ждать завершения процесса и получить его код возврата, но вывод сообщений все равно пойдет в терминал родительского процесса, а не в отдельный терминал.

Самое близкое, что я нашел, это boost:process:child. Есть хэндл, есть возможность асинхронно ждать завершения и получить код возврата, но вывод идет не туда, куда хотелось бы. Правда, есть возможность полностью перенаправить поток вывода в файл или другой поток, но это не совсем то, что нужно.

return boost::process::child(exeName, boost::process::std_out > "output.txt", boost::process::start_dir = workDir);

Можно вообще как-то добиться желаемого поведения?


Ответы (0 шт):