Browse Source

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.
Nico Weber 5 years ago
parent
commit
12cbc4ad0d

+ 11 - 16
Applications/FileManager/main.cpp

@@ -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()) {
-            if (chdir(directory_view.path().characters()) < 0) {
-                perror("chdir");
-                exit(1);
-            }
-
-            if (execl("/bin/Terminal", "Terminal", nullptr) < 0)
-                perror("execl");
-            exit(1);
-        }
+        posix_spawn_file_actions_t spawn_actions;
+        posix_spawn_file_actions_init(&spawn_actions);
+        posix_spawn_file_actions_addchdir(&spawn_actions, directory_view.path().characters());
+        pid_t pid;
+        const char* argv[] = { "Terminal", nullptr };
+        posix_spawn(&pid, "/bin/Terminal", &spawn_actions, nullptr, const_cast<char**>(argv), environ);
+        posix_spawn_file_actions_destroy(&spawn_actions);
     });
     });
 
 
     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()) {
-                int rc = execl("/bin/TextEditor", "TextEditor", path.characters(), nullptr);
-                if (rc < 0)
-                    perror("execl");
-                exit(1);
-            }
+            const char* argv[] = { "TextEditor", path.characters(), nullptr };
+            posix_spawn(&child, "/bin/TextEditor", nullptr, nullptr, const_cast<char**>(argv), environ);
         }
         }
     });
     });
 
 

+ 5 - 10
Applications/KeyboardSettings/main.cpp

@@ -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 = fork();
-        if (child_pid < 0) {
-            perror("fork");
+        pid_t child_pid;
+        const char* argv[] = { "/bin/keymap", character_map_file.characters(), nullptr };
+        if ((errno = posix_spawn(&child_pid, "/bin/keymap", nullptr, nullptr, const_cast<char**>(argv), environ))) {
+            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();
     };
     };

+ 4 - 4
Applications/QuickShow/main.cpp

@@ -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) {
-                    execl("/bin/QuickShow", "/bin/QuickShow", urls[i].path().characters(), nullptr);
-                    ASSERT_NOT_REACHED();
-                }
+                const char* argv[] = { "/bin/QuickShow", urls[i].path().characters(), nullptr };
+                posix_spawn(&child, "/bin/QuickShow", nullptr, nullptr, const_cast<char**>(argv), environ);
             }
             }
         }
         }
     };
     };

+ 4 - 4
Applications/Terminal/main.cpp

@@ -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()) {
-            execl("/bin/Terminal", "Terminal", nullptr);
-            exit(1);
-        }
+        pid_t child;
+        const char* argv[] = { "Terminal", nullptr };
+        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&) {

+ 5 - 8
DevTools/HackStudio/main.cpp

@@ -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();
-    if (pid < 0)
+    pid_t pid;
+    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;

+ 4 - 9
Libraries/LibC/stdlib.cpp

@@ -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();
-    if (child < 0)
+    pid_t child;
+    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);

+ 5 - 8
MenuApplets/ResourceGraph/main.cpp

@@ -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();
-        if (pid < 0) {
-            perror("fork");
-        } else if (pid == 0) {
-            execl("/bin/SystemMonitor", "SystemMonitor", nullptr);
-            perror("execl");
-            ASSERT_NOT_REACHED();
-        }
+        pid_t child_pid;
+        const char* argv[] = { "SystemMonitor", nullptr };
+        if ((errno = posix_spawn(&child_pid, "/bin/SystemMonitor", nullptr, nullptr, const_cast<char**>(argv), environ)))
+            perror("posix_spawn");
     }
     }
 
 
     static void get_cpu_usage(unsigned& busy, unsigned& idle)
     static void get_cpu_usage(unsigned& busy, unsigned& idle)

+ 5 - 10
Services/LaunchServer/Launcher.cpp

@@ -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();
-    if (child_pid < 0) {
-        perror("fork");
+    pid_t child_pid;
+    const char* argv[] = { executable.characters(), argument.characters(), nullptr };
+    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;
 }
 }
 
 

+ 11 - 14
Services/SystemMenu/main.cpp

@@ -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;
-                if (execl(bin.characters(), bin.characters(), nullptr) < 0)
-                    perror("execl");
-                ASSERT_NOT_REACHED();
-            }
+            const auto& bin = g_apps[app_identifier].executable;
+            pid_t child_pid;
+            const char* argv[] = { bin.characters(), nullptr };
+            if ((errno = posix_spawn(&child_pid, bin.characters(), nullptr, nullptr, const_cast<char**>(argv), environ)))
+                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) {
-            execl("/bin/About", "/bin/About", nullptr);
-            ASSERT_NOT_REACHED();
-        }
+        pid_t child_pid;
+        const char* argv[] = { "/bin/About", nullptr };
+        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) {
-            execv(command[0], const_cast<char* const*>(command.data()));
-            ASSERT_NOT_REACHED();
-        }
+        pid_t child_pid;
+        posix_spawn(&child_pid, command[0], nullptr, nullptr, const_cast<char**>(command.data()), environ);
     }));
     }));
 
 
     return system_menu;
     return system_menu;

+ 6 - 6
Userland/flock.cpp

@@ -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()) {
-        if (execvp(argv[2], &argv[2]) < 0) {
-            perror("execvp");
-            exit(1);
-        }
+    pid_t child_pid;
+    if ((errno = posix_spawnp(&child_pid, argv[2], nullptr, nullptr, &argv[2], environ))) {
+        perror("posix_spawn");
+        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;
     }
     }

+ 5 - 12
Userland/userdel.cpp

@@ -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();
-
-            if (child < 0) {
-                perror("fork");
+            pid_t child;
+            const char* argv[] = { "rm", "-r", home_directory.characters(), nullptr };
+            if ((errno = posix_spawn(&child, "/bin/rm", nullptr, nullptr, const_cast<char**>(argv), environ))) {
+                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");