summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom <tomut@yahoo.com>2020-11-29 21:03:42 -0700
committerAndreas Kling <kling@serenityos.org>2020-11-30 11:34:08 +0100
commit4c8c1496124cef9a3757e33f233829a70a7d65cd (patch)
tree006e4978b2467568ccdaf781dca8d8904e40b7c4
parent65eef944ab35ca85be178615ffc32834d430f4e3 (diff)
downloadserenity-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.cpp27
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)