From 53918364683d1110916f0533e921c00737cbadae Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Thu, 6 May 2021 13:52:46 +0100 Subject: [PATCH] LibC: Remove 'int* aslave' parameter from forkpty() Only keep track of that (and eventually close() it) internally instead. This argument is not present on other systems, so we were running into compatibility issues with ports. Also bring the implementation closer to Linux and OpenBSD by making sure to close the slave pty fd in the fork()'d child as well as _exit()'ing on login_tty() failure - it's non-POSIX, so those are our references here. :^) --- Userland/Applications/Terminal/main.cpp | 6 ++--- Userland/Libraries/LibC/pty.cpp | 30 ++++++++++++++++--------- Userland/Libraries/LibC/pty.h | 2 +- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/Userland/Applications/Terminal/main.cpp b/Userland/Applications/Terminal/main.cpp index 0292207769..191a0ada89 100644 --- a/Userland/Applications/Terminal/main.cpp +++ b/Userland/Applications/Terminal/main.cpp @@ -261,8 +261,8 @@ int main(int argc, char** argv) RefPtr config = Core::ConfigFile::get_for_app("Terminal"); Core::File::ensure_parent_directories(config->filename()); - int ptm_fd, pts_fd; - pid_t shell_pid = forkpty(&ptm_fd, &pts_fd, nullptr, nullptr, nullptr); + int ptm_fd; + pid_t shell_pid = forkpty(&ptm_fd, nullptr, nullptr, nullptr); if (shell_pid < 0) { perror("forkpty"); return 1; @@ -276,8 +276,6 @@ int main(int argc, char** argv) VERIFY_NOT_REACHED(); } - close(pts_fd); - auto* pts_name = ptsname(ptm_fd); utmp_update(pts_name, shell_pid, true); diff --git a/Userland/Libraries/LibC/pty.cpp b/Userland/Libraries/LibC/pty.cpp index 0b13b2c8b1..0c72a31ef2 100644 --- a/Userland/Libraries/LibC/pty.cpp +++ b/Userland/Libraries/LibC/pty.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2018-2020, Andreas Kling * Copyright (c) 2021, Gunnar Beutner + * Copyright (c) 2021, Linus Groh * * SPDX-License-Identifier: BSD-2-Clause */ @@ -66,20 +67,27 @@ int openpty(int* amaster, int* aslave, char* name, const struct termios* termp, return 0; } -pid_t forkpty(int* amaster, int* aslave, char* name, const struct termios* termp, const struct winsize* winp) +pid_t forkpty(int* amaster, char* name, const struct termios* termp, const struct winsize* winp) { - int rc = openpty(amaster, aslave, name, termp, winp); - if (rc < 0) - return rc; - rc = fork(); - if (rc < 0) { - close(*amaster); - close(*aslave); + int master; + int slave; + if (openpty(&master, &slave, name, termp, winp) < 0) + return -1; + pid_t pid = fork(); + if (pid < 0) { + close(master); + close(slave); return -1; } - if (rc == 0) - rc = login_tty(*aslave); - return rc; + if (pid == 0) { + close(master); + if (login_tty(slave) < 0) + _exit(1); + return 0; + } + *amaster = master; + close(slave); + return pid; } int login_tty(int fd) diff --git a/Userland/Libraries/LibC/pty.h b/Userland/Libraries/LibC/pty.h index 45681620bf..e2068f1105 100644 --- a/Userland/Libraries/LibC/pty.h +++ b/Userland/Libraries/LibC/pty.h @@ -12,7 +12,7 @@ __BEGIN_DECLS int openpty(int* amaster, int* aslave, char* name, const struct termios* termp, const struct winsize* winp); -pid_t forkpty(int* amaster, int* aslave, char* name, const struct termios* termp, const struct winsize* winp); +pid_t forkpty(int* amaster, char* name, const struct termios* termp, const struct winsize* winp); int login_tty(int fd); __END_DECLS