diff options
author | Tom <tomut@yahoo.com> | 2020-11-29 21:03:42 -0700 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-11-30 11:34:08 +0100 |
commit | 4c8c1496124cef9a3757e33f233829a70a7d65cd (patch) | |
tree | 006e4978b2467568ccdaf781dca8d8904e40b7c4 | |
parent | 65eef944ab35ca85be178615ffc32834d430f4e3 (diff) | |
download | serenity-4c8c1496124cef9a3757e33f233829a70a7d65cd.zip |
Terminal: Wait on the utmpupdate process to finish
This solves utmpupdate zombies hanging around until Terminal
terminates.
-rw-r--r-- | Applications/Terminal/main.cpp | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/Applications/Terminal/main.cpp b/Applications/Terminal/main.cpp index f47a7eaf07..64dbb2193d 100644 --- a/Applications/Terminal/main.cpp +++ b/Applications/Terminal/main.cpp @@ -55,6 +55,7 @@ #include <string.h> #include <sys/ioctl.h> #include <sys/select.h> +#include <sys/wait.h> #include <unistd.h> static void utmp_update(const char* tty, pid_t pid, bool create) @@ -66,10 +67,28 @@ static void utmp_update(const char* tty, pid_t pid, bool create) perror("fork"); return; } - if (utmpupdate_pid) - return; - const auto shell_pid_string = String::formatted("{}", pid); - execl("/bin/utmpupdate", "/bin/utmpupdate", "-f", "Terminal", "-p", shell_pid_string.characters(), (create ? "-c" : "-d"), tty, nullptr); + if (utmpupdate_pid == 0) { + // Be careful here! Because fork() only clones one thread it's + // possible that we deadlock on anything involving a mutex, + // including the heap! So resort to low-level APIs + char pid_str[32]; + snprintf(pid_str, sizeof(pid_str), "%d", pid); + execl("/bin/utmpupdate", "/bin/utmpupdate", "-f", "Terminal", "-p", pid_str, (create ? "-c" : "-d"), tty, nullptr); + } else { + wait_again: + int status = 0; + if (waitpid(utmpupdate_pid, &status, 0) < 0) { + int err = errno; + if (err == EINTR) + goto wait_again; + perror("waitpid"); + return; + } + if (WIFEXITED(status) && WEXITSTATUS(status) != 0) + dbgln("Terminal: utmpupdate exited with status {}", WEXITSTATUS(status)); + else if (WIFSIGNALED(status)) + dbgln("Terminal: utmpupdate exited due to unhandled signal {}", WTERMSIG(status)); + } } static pid_t run_command(int ptm_fd, String command) |