summaryrefslogtreecommitdiff
path: root/Kernel/TTY
diff options
context:
space:
mode:
authorAnotherTest <ali.mpfard@gmail.com>2020-08-15 23:43:19 +0430
committerAndreas Kling <kling@serenityos.org>2020-08-19 21:21:34 +0200
commit688e54eac739405f9fe848e986a1194f29483f14 (patch)
tree259d0a1138e1688f9e2802272c2bb7aa2e569422 /Kernel/TTY
parentcf18bff72ac23afa84b766240acd7dbd4370bae5 (diff)
downloadserenity-688e54eac739405f9fe848e986a1194f29483f14.zip
Kernel: Distinguish between new and old process groups with equal pgids
This does not add any behaviour change to the processes, but it ties a TTY to an active process group via TIOCSPGRP, and returns the TTY to the kernel when all processes in the process group die. Also makes the TTY keep a link to the original controlling process' parent (for SIGCHLD) instead of the process itself.
Diffstat (limited to 'Kernel/TTY')
-rw-r--r--Kernel/TTY/TTY.cpp30
-rw-r--r--Kernel/TTY/TTY.h6
2 files changed, 22 insertions, 14 deletions
diff --git a/Kernel/TTY/TTY.cpp b/Kernel/TTY/TTY.cpp
index 28e781927e..6ffce4dbff 100644
--- a/Kernel/TTY/TTY.cpp
+++ b/Kernel/TTY/TTY.cpp
@@ -155,10 +155,8 @@ void TTY::emit(u8 ch)
if (ch == m_termios.c_cc[VSUSP]) {
dbg() << tty_name() << ": VSUSP pressed!";
generate_signal(SIGTSTP);
- if (m_process) {
- if (auto parent = Process::from_pid(m_process->ppid()))
- (void)parent->send_signal(SIGCHLD, m_process);
- }
+ if (m_original_process_parent)
+ (void)m_original_process_parent->send_signal(SIGCHLD, nullptr);
// TODO: Else send it to the session leader maybe?
return;
}
@@ -310,13 +308,27 @@ int TTY::ioctl(FileDescription&, unsigned request, FlatPtr arg)
if (pgid <= 0)
return -EINVAL;
InterruptDisabler disabler;
- auto process = Process::from_pid(pgid.value());
+ auto process_group = ProcessGroup::from_pgid(pgid);
+ // Disallow setting a nonexistent PGID.
+ if (!process_group)
+ return -EINVAL;
+
+ auto process = Process::from_pid(ProcessID(pgid.value()));
SessionID new_sid = process ? process->sid() : Process::get_sid_from_pgid(pgid);
if (!new_sid || new_sid != current_process.sid())
return -EPERM;
if (process && pgid != process->pgid())
return -EPERM;
- m_process = process ? process->make_weak_ptr() : WeakPtr<Process>();
+ m_pg = process_group->make_weak_ptr();
+
+ if (process) {
+ if (auto parent = Process::from_pid(process->ppid())) {
+ m_original_process_parent = parent->make_weak_ptr();
+ return 0;
+ }
+ }
+
+ m_original_process_parent = nullptr;
return 0;
}
case TCGETS: {
@@ -392,10 +404,4 @@ void TTY::hang_up()
{
generate_signal(SIGHUP);
}
-
-ProcessGroupID TTY::pgid() const
-{
- return m_process ? m_process->pgid() : 0;
-}
-
}
diff --git a/Kernel/TTY/TTY.h b/Kernel/TTY/TTY.h
index e8febbd079..d858aa68a6 100644
--- a/Kernel/TTY/TTY.h
+++ b/Kernel/TTY/TTY.h
@@ -30,6 +30,7 @@
#include <AK/WeakPtr.h>
#include <Kernel/Devices/CharacterDevice.h>
#include <Kernel/DoubleBuffer.h>
+#include <Kernel/ProcessGroup.h>
#include <Kernel/UnixTypes.h>
namespace Kernel {
@@ -50,7 +51,7 @@ public:
unsigned short rows() const { return m_rows; }
unsigned short columns() const { return m_columns; }
- ProcessGroupID pgid() const;
+ ProcessGroupID pgid() const { return m_pg ? m_pg->pgid() : 0; }
void set_termios(const termios&);
bool should_generate_signals() const { return m_termios.c_lflag & ISIG; }
@@ -91,7 +92,8 @@ private:
virtual bool is_tty() const final override { return true; }
CircularDeque<u8, 1024> m_input_buffer;
- WeakPtr<Process> m_process;
+ WeakPtr<Process> m_original_process_parent;
+ WeakPtr<ProcessGroup> m_pg;
termios m_termios;
unsigned short m_rows { 0 };
unsigned short m_columns { 0 };