Skip to content

Commit

Permalink
plugin: use posix_spawn() instead of fork()/execv()
Browse files Browse the repository at this point in the history
This is easier to use and somewhat more portable.  And it's sometimes
even faster because it can use vfork().
  • Loading branch information
MaxKellermann committed Apr 6, 2023
1 parent bfe7870 commit e9c6eac
Showing 1 changed file with 12 additions and 19 deletions.
31 changes: 12 additions & 19 deletions src/plugin.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include <assert.h>
#include <stdlib.h>
#include <spawn.h>
#include <unistd.h>
#include <dirent.h>
#include <signal.h>
Expand Down Expand Up @@ -248,27 +249,19 @@ PluginCycle::LaunchPlugin(const char *plugin_path) noexcept
!UniqueFileDescriptor::CreatePipe(stderr_r, stderr_w))
return -1;

pid = fork();
posix_spawn_file_actions_t file_actions;
posix_spawn_file_actions_init(&file_actions);
AtScopeExit(&file_actions) { posix_spawn_file_actions_destroy(&file_actions); };

if (pid < 0)
return -1;

if (pid == 0) {
stdout_w.Duplicate(FileDescriptor(STDOUT_FILENO));
stderr_w.Duplicate(FileDescriptor(STDERR_FILENO));

stdout_r.Close();
stdout_w.Close();
stderr_r.Close();
stderr_w.Close();
close(0);
/* XXX close other fds? */
posix_spawn_file_actions_addclose(&file_actions, STDIN_FILENO);
posix_spawn_file_actions_adddup2(&file_actions, stdout_w.Get(),
STDOUT_FILENO);
posix_spawn_file_actions_adddup2(&file_actions, stderr_w.Get(),
STDERR_FILENO);

execv(plugin_path, argv.get());
_exit(1);
}

/* XXX CLOEXEC? */
if (posix_spawn(&pid, plugin_path, &file_actions, nullptr,
argv.get(), environ) != 0)
return -1;

pipe_stdout.Start(std::move(stdout_r));
pipe_stderr.Start(std::move(stderr_r));
Expand Down

0 comments on commit e9c6eac

Please sign in to comment.