13 #ifndef __STOUT_OS_POSIX_FORK_HPP__ 14 #define __STOUT_OS_POSIX_FORK_HPP__ 23 #include <sys/types.h> 103 Exec(
const std::string& _command)
118 : function(_function),
127 : function(_function)
135 : function(_function),
144 : function(_function),
157 : function(_function)
167 : function(_function),
178 : function(_function),
194 : function(_function)
206 : function(_function),
219 : function(_function),
241 std::atomic_bool
set;
244 std::shared_ptr<Memory>
memory;
262 struct SharedMemoryDeleter
264 SharedMemoryDeleter(
int _fd) : fd(_fd) {}
271 if (::
close(fd) == -1) {
272 ABORT(std::string(
"Failed to close shared memory file descriptor: ") +
283 static std::atomic_int forks(0);
287 int instance = forks.fetch_add(1);
292 int fd = shm_open(name.c_str(), O_CREAT | O_RDWR,
S_IRUSR |
S_IWUSR);
295 return ErrnoError(
"Failed to open a shared memory object");
301 "Failed to set size of shared memory object: " + truncated.
error());
307 PROT_READ | PROT_WRITE, MAP_SHARED,
311 if (memory == MAP_FAILED) {
312 return ErrnoError(
"Failed to map shared memory object");
315 if (shm_unlink(name.c_str()) == -1) {
316 return ErrnoError(
"Failed to unlink shared memory object");
319 SharedMemoryDeleter deleter(fd);
322 tree.memory = std::shared_ptr<Tree::Memory>((
Tree::Memory*)memory, deleter);
323 tree.memory->set.store(
false);
325 for (
size_t i = 0; i <
children.size(); i++) {
330 tree.children.push_back(tree_.
get());
338 pid_t instantiate(
const Tree& tree)
const 340 pid_t pid = ::fork();
346 tree.memory->pid = getpid();
347 tree.memory->parent = getppid();
348 tree.memory->group = getpgid(0);
349 tree.memory->session = getsid(0);
350 tree.memory->set.store(
true);
353 if (
function.isSome()) {
358 CHECK(
children.size() == tree.children.size());
359 std::set<pid_t>
pids;
360 for (
size_t i = 0; i <
children.size(); i++) {
361 pids.insert(
children[i].instantiate(tree.children[i]));
367 const char*
command = exec->command.c_str();
368 execlp(
"sh",
"sh",
"-c", command, (
char*)
nullptr);
370 <<
"Failed to execute '" << command <<
"': " <<
os::strerror(errno);
371 }
else if (
wait.isSome()) {
372 foreach (
pid_t pid, pids) {
389 while (!tree.memory->set.load());
401 tree.memory->session,
405 self.isSome() ? self->command :
"",
409 for (
size_t i = 0; i < tree.children.size(); i++) {
414 children.push_back(child.
get());
433 return Error(pid.error());
436 return coordinate(tree.
get());
448 #endif // __STOUT_OS_POSIX_FORK_HPP__
Fork(const Option< void(*)()> &_function, const Fork &fork1, const Fork &fork2)
Definition: fork.hpp:154
std::string strerror(int errno_)
A thread-safe version of strerror.
Definition: strerror.hpp:30
Definition: errorbase.hpp:36
Definition: option.hpp:29
#define ABORT(...)
Definition: abort.hpp:40
Fork(const Option< void(*)()> &_function, const Fork &fork1, const Fork &fork2, const Exec &_exec)
Definition: fork.hpp:163
T & get()&
Definition: try.hpp:80
const mode_t S_IWUSR
Definition: windows.hpp:306
pid_t session
Definition: fork.hpp:239
#define EXIT(status)
Definition: exit.hpp:31
Definition: errorbase.hpp:50
Definition: posix_signalhandler.hpp:23
const mode_t S_IRUSR
Definition: windows.hpp:305
Fork(const Option< void(*)()> &_function, const Fork &fork1)
Definition: fork.hpp:125
Fork(const Option< void(*)()> &_function, const Exec &_exec)
Definition: fork.hpp:116
Fork(const Option< void(*)()> &_function, const Fork &fork1, const Fork &fork2, const Fork &fork3)
Definition: fork.hpp:190
Fork(const Option< void(*)()> &_function, const Fork &fork1, const Fork &fork2, const Fork &fork3, const Exec &_exec)
Definition: fork.hpp:201
Fork(const Exec &_exec)
Definition: fork.hpp:121
DWORD pid_t
Definition: windows.hpp:181
Definition: process.hpp:32
Try< ProcessTree > operator()() const
Definition: fork.hpp:422
Try< Nothing > close(int fd)
Definition: close.hpp:24
Fork(const Option< void(*)()> &_function, const Fork &fork1, const Fork &fork2, const Fork &fork3, const Wait &_wait)
Definition: fork.hpp:214
Result< pid_t > waitpid(pid_t pid, int *status, int options)
Definition: os.hpp:141
static Try error(const E &e)
Definition: try.hpp:43
bool wait(const UPID &pid, const Duration &duration=Seconds(-1))
Wait for the process to exit for no more than the specified seconds.
pid_t pid
Definition: fork.hpp:236
pid_t group
Definition: fork.hpp:238
Result< Process > process(pid_t pid)
Definition: freebsd.hpp:30
bool isError() const
Definition: try.hpp:78
std::set< pid_t > children(pid_t, const std::list< Process > &, bool)
Definition: os.hpp:217
Definition: executor.hpp:48
const std::string command
Definition: fork.hpp:106
pid_t parent
Definition: fork.hpp:237
Fork(const Option< void(*)()> &_function, const Fork &fork1, const Fork &fork2, const Wait &_wait)
Definition: fork.hpp:174
Try< std::string > prepare(const std::string &baseHierarchy, const std::string &subsystem, const std::string &cgroup)
std::string stringify(int flags)
Try< Memory > memory()
Definition: freebsd.hpp:78
Fork(const Option< void(*)()> &_function, const Fork &fork1, const Exec &_exec)
Definition: fork.hpp:132
Definition: process.hpp:74
Try< std::set< pid_t > > pids()
Definition: freebsd.hpp:62
Exec(const std::string &_command)
Definition: fork.hpp:103
Fork(const Option< void(*)()> &_function, const Fork &fork1, const Wait &_wait)
Definition: fork.hpp:141
constexpr const char * name
Definition: shell.hpp:41
Try< Nothing > ftruncate(int fd, off_t length)
Definition: ftruncate.hpp:26