diff --git a/sys/amd64/linux/linux_sysvec.c b/sys/amd64/linux/linux_sysvec.c index 1134efd1c726..ca1608ab8ac8 100644 --- a/sys/amd64/linux/linux_sysvec.c +++ b/sys/amd64/linux/linux_sysvec.c @@ -705,7 +705,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 f42654967e8f..82b4b7522503 100644 --- a/sys/amd64/linux32/linux32_sysvec.c +++ b/sys/amd64/linux32/linux32_sysvec.c @@ -805,7 +805,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 9afb6fb143d6..0c441bf2d071 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 9ed7ef9f0aed..721353344b07 100644 --- a/sys/fs/devfs/devfs_vnops.c +++ b/sys/fs/devfs/devfs_vnops.c @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -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))