git: 9dcc20504c8b - stable/15 - devfs: make persistent controlling terminal an ABI property
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 26 Oct 2026 03:40:15 UTC
The branch stable/15 has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=9dcc20504c8bee707bcd8cb01a0b1ef07e41c3c0
commit 9dcc20504c8bee707bcd8cb01a0b1ef07e41c3c0
Author: Vladimir Grebenshchikov <vova@zote.me>
AuthorDate: 2026-10-13 23:04:27 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-10-26 03:38:18 +0000
devfs: make persistent controlling terminal an ABI property
(cherry picked from commit e8923c7346a882418352683f72e7c4f8e68d6907)
---
sys/amd64/linux/linux_sysvec.c | 2 +-
sys/amd64/linux32/linux32_sysvec.c | 3 ++-
sys/arm64/linux/linux_sysvec.c | 2 +-
sys/fs/devfs/devfs_vnops.c | 8 +++++++-
sys/i386/linux/linux_sysvec.c | 5 +++--
sys/sys/sysent.h | 1 +
6 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/sys/amd64/linux/linux_sysvec.c b/sys/amd64/linux/linux_sysvec.c
index 210c3e127de3..8ba0673a2cc2 100644
--- a/sys/amd64/linux/linux_sysvec.c
+++ b/sys/amd64/linux/linux_sysvec.c
@@ -701,7 +701,7 @@ struct sysentvec elf_linux_sysvec = {
.sv_fixlimit = NULL,
.sv_maxssiz = NULL,
.sv_flags = SV_ABI_LINUX | SV_LP64 | SV_SHP | SV_SIG_DISCIGN |
- SV_SIG_WAITNDQ | SV_TIMEKEEP,
+ SV_SIG_WAITNDQ | SV_TIMEKEEP | SV_PERSISTENT_CTTY,
.sv_set_syscall_retval = linux_set_syscall_retval,
.sv_fetch_syscall_args = linux_fetch_syscall_args,
.sv_syscallnames = linux_syscallnames,
diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c
index a61039a2dc16..5934aaee9a80 100644
--- a/sys/amd64/linux32/linux32_sysvec.c
+++ b/sys/amd64/linux32/linux32_sysvec.c
@@ -801,7 +801,8 @@ struct sysentvec elf_linux_sysvec = {
.sv_fixlimit = linux32_fixlimit,
.sv_maxssiz = &linux32_maxssiz,
.sv_flags = SV_ABI_LINUX | SV_ILP32 | SV_SHP |
- SV_SIG_DISCIGN | SV_SIG_WAITNDQ | SV_TIMEKEEP,
+ SV_SIG_DISCIGN | SV_SIG_WAITNDQ | SV_TIMEKEEP |
+ SV_PERSISTENT_CTTY,
.sv_set_syscall_retval = linux32_set_syscall_retval,
.sv_fetch_syscall_args = linux32_fetch_syscall_args,
.sv_syscallnames = linux32_syscallnames,
diff --git a/sys/arm64/linux/linux_sysvec.c b/sys/arm64/linux/linux_sysvec.c
index ac05820f89bc..03e86307dc34 100644
--- a/sys/arm64/linux/linux_sysvec.c
+++ b/sys/arm64/linux/linux_sysvec.c
@@ -449,7 +449,7 @@ struct sysentvec elf_linux_sysvec = {
.sv_fixlimit = NULL,
.sv_maxssiz = NULL,
.sv_flags = SV_ABI_LINUX | SV_LP64 | SV_SHP | SV_SIG_DISCIGN |
- SV_SIG_WAITNDQ | SV_TIMEKEEP,
+ SV_SIG_WAITNDQ | SV_TIMEKEEP | SV_PERSISTENT_CTTY,
.sv_set_syscall_retval = linux_set_syscall_retval,
.sv_fetch_syscall_args = linux_fetch_syscall_args,
.sv_syscallnames = linux_syscallnames,
diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c
index bb708afad103..643a966a08a5 100644
--- a/sys/fs/devfs/devfs_vnops.c
+++ b/sys/fs/devfs/devfs_vnops.c
@@ -59,6 +59,7 @@
#include <sys/stat.h>
#include <sys/sx.h>
#include <sys/sysctl.h>
+#include <sys/sysent.h>
#include <sys/time.h>
#include <sys/ttycom.h>
#include <sys/unistd.h>
@@ -716,8 +717,13 @@ devfs_close(struct vop_close_args *ap)
* process' controlling terminal. In that case,
* if the reference count is 2 (this last descriptor
* plus the session), release the reference from the session.
+ *
+ * Some ABIs keep the controlling terminal after the last
+ * slave descriptor is closed. A closer with SV_PERSISTENT_CTTY
+ * leaves the session reference in place.
*/
- if (de->de_usecount == 2 && td != NULL) {
+ if (!SV_PROC_FLAG(curproc, SV_PERSISTENT_CTTY) &&
+ de->de_usecount == 2 && td != NULL) {
p = td->td_proc;
PROC_LOCK(p);
if (vp == p->p_session->s_ttyvp) {
diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c
index 14b5f64388d2..333f8d21cdb3 100644
--- a/sys/i386/linux/linux_sysvec.c
+++ b/sys/i386/linux/linux_sysvec.c
@@ -597,7 +597,7 @@ struct sysentvec linux_sysvec = {
.sv_fixlimit = NULL,
.sv_maxssiz = NULL,
.sv_flags = SV_ABI_LINUX | SV_AOUT | SV_ILP32 |
- SV_SIG_DISCIGN | SV_SIG_WAITNDQ,
+ SV_SIG_DISCIGN | SV_SIG_WAITNDQ | SV_PERSISTENT_CTTY,
.sv_set_syscall_retval = linux_set_syscall_retval,
.sv_fetch_syscall_args = linux_fetch_syscall_args,
.sv_syscallnames = linux_syscallnames,
@@ -641,7 +641,8 @@ struct sysentvec elf_linux_sysvec = {
.sv_fixlimit = NULL,
.sv_maxssiz = NULL,
.sv_flags = SV_ABI_LINUX | SV_ILP32 | SV_SHP |
- SV_SIG_DISCIGN | SV_SIG_WAITNDQ | SV_TIMEKEEP,
+ SV_SIG_DISCIGN | SV_SIG_WAITNDQ | SV_TIMEKEEP |
+ SV_PERSISTENT_CTTY,
.sv_set_syscall_retval = linux_set_syscall_retval,
.sv_fetch_syscall_args = linux_fetch_syscall_args,
.sv_syscallnames = NULL,
diff --git a/sys/sys/sysent.h b/sys/sys/sysent.h
index b2a559da7844..8b45d0cb4dff 100644
--- a/sys/sys/sysent.h
+++ b/sys/sys/sysent.h
@@ -175,6 +175,7 @@ struct sysentvec {
#define SV_SIG_DISCIGN 0x200000 /* Do not discard ignored signals */
#define SV_SIG_WAITNDQ 0x400000 /* Wait does not dequeue SIGCHLD */
#define SV_DSO_SIG 0x800000 /* Signal trampoline packed in dso */
+#define SV_PERSISTENT_CTTY 0x1000000 /* Keep ctty after the last close */
#define SV_ABI_MASK 0xff
#define SV_PROC_FLAG(p, x) ((p)->p_sysent->sv_flags & (x))