1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 07:08:10 +00:00

Everywhere: Replace some uses of fork/exec with posix_spawn

It's less code, and it's potentially more efficient once
posix_spawn is a real syscall.
This commit is contained in:
Nico Weber 2020-06-28 13:40:10 -04:00 committed by Andreas Kling
parent 301ac3c7e5
commit 12cbc4ad0d
11 changed files with 65 additions and 101 deletions

View file

@ -58,6 +58,7 @@
#include <LibGUI/Window.h> #include <LibGUI/Window.h>
#include <LibGfx/Palette.h> #include <LibGfx/Palette.h>
#include <signal.h> #include <signal.h>
#include <spawn.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
@ -337,16 +338,13 @@ int run_in_windowed_mode(RefPtr<Core::ConfigFile> config, String initial_locatio
}); });
auto open_terminal_action = GUI::Action::create("Open Terminal here...", Gfx::Bitmap::load_from_file("/res/icons/16x16/app-terminal.png"), [&](const GUI::Action&) { auto open_terminal_action = GUI::Action::create("Open Terminal here...", Gfx::Bitmap::load_from_file("/res/icons/16x16/app-terminal.png"), [&](const GUI::Action&) {
if (!fork()) { posix_spawn_file_actions_t spawn_actions;
if (chdir(directory_view.path().characters()) < 0) { posix_spawn_file_actions_init(&spawn_actions);
perror("chdir"); posix_spawn_file_actions_addchdir(&spawn_actions, directory_view.path().characters());
exit(1); pid_t pid;
} const char* argv[] = { "Terminal", nullptr };
posix_spawn(&pid, "/bin/Terminal", &spawn_actions, nullptr, const_cast<char**>(argv), environ);
if (execl("/bin/Terminal", "Terminal", nullptr) < 0) posix_spawn_file_actions_destroy(&spawn_actions);
perror("execl");
exit(1);
}
}); });
RefPtr<GUI::Action> view_as_table_action; RefPtr<GUI::Action> view_as_table_action;
@ -719,13 +717,10 @@ int run_in_windowed_mode(RefPtr<Core::ConfigFile> config, String initial_locatio
}; };
auto open_in_text_editor_action = GUI::Action::create("Open in TextEditor...", Gfx::Bitmap::load_from_file("/res/icons/TextEditor16.png"), [&](auto&) { auto open_in_text_editor_action = GUI::Action::create("Open in TextEditor...", Gfx::Bitmap::load_from_file("/res/icons/TextEditor16.png"), [&](auto&) {
pid_t child;
for (auto& path : selected_file_paths()) { for (auto& path : selected_file_paths()) {
if (!fork()) { const char* argv[] = { "TextEditor", path.characters(), nullptr };
int rc = execl("/bin/TextEditor", "TextEditor", path.characters(), nullptr); posix_spawn(&child, "/bin/TextEditor", nullptr, nullptr, const_cast<char**>(argv), environ);
if (rc < 0)
perror("execl");
exit(1);
}
} }
}); });

View file

@ -40,6 +40,7 @@
#include <LibGUI/MessageBox.h> #include <LibGUI/MessageBox.h>
#include <LibGUI/WindowServerConnection.h> #include <LibGUI/WindowServerConnection.h>
#include <LibKeyboard/CharacterMap.h> #include <LibKeyboard/CharacterMap.h>
#include <spawn.h>
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
@ -123,18 +124,12 @@ int main(int argc, char** argv)
GUI::MessageBox::show("Please select character mapping file.", "Keyboard settings", GUI::MessageBox::Type::Error, GUI::MessageBox::InputType::OK, window); GUI::MessageBox::show("Please select character mapping file.", "Keyboard settings", GUI::MessageBox::Type::Error, GUI::MessageBox::InputType::OK, window);
return; return;
} }
pid_t child_pid;
pid_t child_pid = fork(); const char* argv[] = { "/bin/keymap", character_map_file.characters(), nullptr };
if (child_pid < 0) { if ((errno = posix_spawn(&child_pid, "/bin/keymap", nullptr, nullptr, const_cast<char**>(argv), environ))) {
perror("fork"); perror("posix_spawn");
exit(1); exit(1);
} }
if (child_pid == 0) {
if (execl("/bin/keymap", "/bin/keymap", character_map_file.characters(), nullptr) < 0) {
perror("execl");
exit(1);
}
}
if (quit) if (quit)
app.quit(); app.quit();
}; };

View file

@ -44,6 +44,7 @@
#include <LibGfx/Bitmap.h> #include <LibGfx/Bitmap.h>
#include <LibGfx/Palette.h> #include <LibGfx/Palette.h>
#include <LibGfx/Rect.h> #include <LibGfx/Rect.h>
#include <spawn.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -110,11 +111,10 @@ int main(int argc, char** argv)
widget.load_from_file(url.path()); widget.load_from_file(url.path());
} }
pid_t child;
for (size_t i = 1; i < urls.size(); ++i) { for (size_t i = 1; i < urls.size(); ++i) {
if (fork() == 0) { const char* argv[] = { "/bin/QuickShow", urls[i].path().characters(), nullptr };
execl("/bin/QuickShow", "/bin/QuickShow", urls[i].path().characters(), nullptr); posix_spawn(&child, "/bin/QuickShow", nullptr, nullptr, const_cast<char**>(argv), environ);
ASSERT_NOT_REACHED();
}
} }
} }
}; };

View file

@ -47,6 +47,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <pwd.h> #include <pwd.h>
#include <signal.h> #include <signal.h>
#include <spawn.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -257,10 +258,9 @@ int main(int argc, char** argv)
auto& app_menu = menubar->add_menu("Terminal"); auto& app_menu = menubar->add_menu("Terminal");
app_menu.add_action(GUI::Action::create("Open new terminal", { Mod_Ctrl | Mod_Shift, Key_N }, Gfx::Bitmap::load_from_file("/res/icons/16x16/app-terminal.png"), [&](auto&) { app_menu.add_action(GUI::Action::create("Open new terminal", { Mod_Ctrl | Mod_Shift, Key_N }, Gfx::Bitmap::load_from_file("/res/icons/16x16/app-terminal.png"), [&](auto&) {
if (!fork()) { pid_t child;
execl("/bin/Terminal", "Terminal", nullptr); const char* argv[] = { "Terminal", nullptr };
exit(1); posix_spawn(&child, "/bin/Terminal", nullptr, nullptr, const_cast<char**>(argv), environ);
}
})); }));
app_menu.add_action(GUI::Action::create("Settings...", Gfx::Bitmap::load_from_file("/res/icons/gear16.png"), app_menu.add_action(GUI::Action::create("Settings...", Gfx::Bitmap::load_from_file("/res/icons/gear16.png"),
[&](const GUI::Action&) { [&](const GUI::Action&) {

View file

@ -71,6 +71,7 @@
#include <LibThread/Lock.h> #include <LibThread/Lock.h>
#include <LibThread/Thread.h> #include <LibThread/Thread.h>
#include <LibVT/TerminalWidget.h> #include <LibVT/TerminalWidget.h>
#include <spawn.h>
#include <stdio.h> #include <stdio.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <unistd.h> #include <unistd.h>
@ -766,15 +767,11 @@ void open_file(const String& filename)
bool make_is_available() bool make_is_available()
{ {
auto pid = fork(); pid_t pid;
if (pid < 0) const char* argv[] = { "make", "--version", nullptr };
if ((errno = posix_spawnp(&pid, "make", nullptr, nullptr, const_cast<char**>(argv), environ))) {
perror("posix_spawn");
return false; return false;
if (!pid) {
int rc = execlp("make", "make", "--version", nullptr);
ASSERT(rc < 0);
perror("execl");
exit(127);
} }
int wstatus; int wstatus;

View file

@ -36,6 +36,7 @@
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
#include <signal.h> #include <signal.h>
#include <spawn.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -706,16 +707,10 @@ int system(const char* command)
if (!command) if (!command)
return 1; return 1;
auto child = fork(); pid_t child;
if (child < 0) const char* argv[] = { "sh", "-c", command, nullptr };
if ((errno = posix_spawn(&child, "/bin/sh", nullptr, nullptr, const_cast<char**>(argv), environ)))
return -1; return -1;
if (!child) {
int rc = execl("/bin/sh", "sh", "-c", command, nullptr);
ASSERT(rc < 0);
perror("execl");
exit(127);
}
int wstatus; int wstatus;
waitpid(child, &wstatus, 0); waitpid(child, &wstatus, 0);
return WEXITSTATUS(wstatus); return WEXITSTATUS(wstatus);

View file

@ -35,6 +35,7 @@
#include <LibGUI/Painter.h> #include <LibGUI/Painter.h>
#include <LibGUI/Window.h> #include <LibGUI/Window.h>
#include <LibGfx/Palette.h> #include <LibGfx/Palette.h>
#include <spawn.h>
#include <stdio.h> #include <stdio.h>
enum class GraphType { enum class GraphType {
@ -106,14 +107,10 @@ private:
{ {
if (event.button() != GUI::MouseButton::Left) if (event.button() != GUI::MouseButton::Left)
return; return;
pid_t pid = fork(); pid_t child_pid;
if (pid < 0) { const char* argv[] = { "SystemMonitor", nullptr };
perror("fork"); if ((errno = posix_spawn(&child_pid, "/bin/SystemMonitor", nullptr, nullptr, const_cast<char**>(argv), environ)))
} else if (pid == 0) { perror("posix_spawn");
execl("/bin/SystemMonitor", "SystemMonitor", nullptr);
perror("execl");
ASSERT_NOT_REACHED();
}
} }
static void get_cpu_usage(unsigned& busy, unsigned& idle) static void get_cpu_usage(unsigned& busy, unsigned& idle)

View file

@ -29,6 +29,7 @@
#include <AK/LexicalPath.h> #include <AK/LexicalPath.h>
#include <LibCore/ConfigFile.h> #include <LibCore/ConfigFile.h>
#include <LibCore/DirIterator.h> #include <LibCore/DirIterator.h>
#include <spawn.h>
#include <stdio.h> #include <stdio.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -125,18 +126,12 @@ bool Launcher::open_with_handler_name(const URL& url, const String& handler_name
bool spawn(String executable, String argument) bool spawn(String executable, String argument)
{ {
pid_t child_pid = fork(); pid_t child_pid;
if (child_pid < 0) { const char* argv[] = { executable.characters(), argument.characters(), nullptr };
perror("fork"); if ((errno = posix_spawn(&child_pid, executable.characters(), nullptr, nullptr, const_cast<char**>(argv), environ))) {
perror("posix_spawn");
return false; return false;
} }
if (child_pid == 0) {
if (execl(executable.characters(), executable.characters(), argument.characters(), nullptr) < 0) {
perror("execl");
return false;
}
ASSERT_NOT_REACHED();
}
return true; return true;
} }

View file

@ -36,6 +36,7 @@
#include <LibGUI/Menu.h> #include <LibGUI/Menu.h>
#include <LibGUI/WindowServerConnection.h> #include <LibGUI/WindowServerConnection.h>
#include <LibGfx/Bitmap.h> #include <LibGfx/Bitmap.h>
#include <spawn.h>
//#define SYSTEM_MENU_DEBUG //#define SYSTEM_MENU_DEBUG
@ -149,12 +150,11 @@ NonnullRefPtr<GUI::Menu> build_system_menu()
auto parent_menu = g_app_category_menus.get(app.category).value_or(*system_menu); auto parent_menu = g_app_category_menus.get(app.category).value_or(*system_menu);
parent_menu->add_action(GUI::Action::create(app.name, icon.ptr(), [app_identifier](auto&) { parent_menu->add_action(GUI::Action::create(app.name, icon.ptr(), [app_identifier](auto&) {
dbg() << "Activated app with ID " << app_identifier; dbg() << "Activated app with ID " << app_identifier;
if (fork() == 0) { const auto& bin = g_apps[app_identifier].executable;
const auto& bin = g_apps[app_identifier].executable; pid_t child_pid;
if (execl(bin.characters(), bin.characters(), nullptr) < 0) const char* argv[] = { bin.characters(), nullptr };
perror("execl"); if ((errno = posix_spawn(&child_pid, bin.characters(), nullptr, nullptr, const_cast<char**>(argv), environ)))
ASSERT_NOT_REACHED(); perror("posix_spawn");
}
})); }));
++app_identifier; ++app_identifier;
} }
@ -197,10 +197,9 @@ NonnullRefPtr<GUI::Menu> build_system_menu()
system_menu->add_separator(); system_menu->add_separator();
system_menu->add_action(GUI::Action::create("About...", Gfx::Bitmap::load_from_file("/res/icons/16x16/ladybug.png"), [](auto&) { system_menu->add_action(GUI::Action::create("About...", Gfx::Bitmap::load_from_file("/res/icons/16x16/ladybug.png"), [](auto&) {
if (fork() == 0) { pid_t child_pid;
execl("/bin/About", "/bin/About", nullptr); const char* argv[] = { "/bin/About", nullptr };
ASSERT_NOT_REACHED(); posix_spawn(&child_pid, "/bin/About", nullptr, nullptr, const_cast<char**>(argv), environ);
}
})); }));
system_menu->add_separator(); system_menu->add_separator();
system_menu->add_action(GUI::Action::create("Exit...", [](auto&) { system_menu->add_action(GUI::Action::create("Exit...", [](auto&) {
@ -209,10 +208,8 @@ NonnullRefPtr<GUI::Menu> build_system_menu()
if (command.size() == 0) if (command.size() == 0)
return; return;
if (fork() == 0) { pid_t child_pid;
execv(command[0], const_cast<char* const*>(command.data())); posix_spawn(&child_pid, command[0], nullptr, nullptr, const_cast<char**>(command.data()), environ);
ASSERT_NOT_REACHED();
}
})); }));
return system_menu; return system_menu;

View file

@ -24,6 +24,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <spawn.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/wait.h> #include <sys/wait.h>
@ -36,15 +37,14 @@ int main(int argc, char** argv)
return 0; return 0;
} }
if (!fork()) { pid_t child_pid;
if (execvp(argv[2], &argv[2]) < 0) { if ((errno = posix_spawnp(&child_pid, argv[2], nullptr, nullptr, &argv[2], environ))) {
perror("execvp"); perror("posix_spawn");
exit(1); return 1;
}
} }
int status; int status;
if (waitpid(-1, &status, 0) < 0) { if (waitpid(child_pid, &status, 0) < 0) {
perror("waitpid"); perror("waitpid");
return 1; return 1;
} }

View file

@ -31,6 +31,7 @@
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
#include <pwd.h> #include <pwd.h>
#include <spawn.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -121,20 +122,12 @@ int main(int argc, char** argv)
} }
if (access(home_directory.characters(), F_OK) != -1) { if (access(home_directory.characters(), F_OK) != -1) {
auto child = fork(); pid_t child;
const char* argv[] = { "rm", "-r", home_directory.characters(), nullptr };
if (child < 0) { if ((errno = posix_spawn(&child, "/bin/rm", nullptr, nullptr, const_cast<char**>(argv), environ))) {
perror("fork"); perror("posix_spawn");
return 12; return 12;
} }
if (!child) {
int rc = execl("/bin/rm", "rm", "-r", home_directory.characters(), nullptr);
ASSERT(rc < 0);
perror("execl");
exit(127);
}
int wstatus; int wstatus;
if (waitpid(child, &wstatus, 0) < 0) { if (waitpid(child, &wstatus, 0) < 0) {
perror("waitpid"); perror("waitpid");