Page MenuHomeFreeBSD

D22572.id64948.diff
No OneTemporary

D22572.id64948.diff

Index: share/man/man4/tty.4
===================================================================
--- share/man/man4/tty.4
+++ share/man/man4/tty.4
@@ -28,7 +28,7 @@
.\" @(#)tty.4 8.3 (Berkeley) 4/19/94
.\" $FreeBSD$
.\"
-.Dd January 11, 2017
+.Dd November 27, 2019
.Dt TTY 4
.Os
.Sh NAME
@@ -194,7 +194,6 @@
Pretend as if the terminal received the character pointed to by
.Fa cp .
.It Dv TIOCNOTTY Fa void
-This call is obsolete but left for compatibility.
In the past, when a process that did not have a controlling terminal (see
.Em The Controlling Terminal
in
@@ -228,6 +227,14 @@
has the effect of disassociating it from the controlling terminal.
This is the new and preferred method for programs to lose their controlling
terminal.
+.Pp
+However, environmental restrictions may prohibit the process from being able to
+.Fn fork
+and call the
+.Fn setsid
+system call to disassociate it from the controlling terminal.
+In this case, it must use
+.Dv TIOCNOTTY .
.It Dv TIOCSTOP Fa void
Stop output on the terminal (like typing ^S at the keyboard).
.It Dv TIOCSTART Fa void
Index: sys/kern/tty.c
===================================================================
--- sys/kern/tty.c
+++ sys/kern/tty.c
@@ -1194,6 +1194,70 @@
tty_rel_free(tp);
}
+static int
+tty_drop_ctty(struct tty *tp, struct proc *p)
+{
+ struct tty *ctty;
+ struct session *session;
+ struct vnode *vp;
+
+ /* XXX This looks awful. */
+ tty_unlock(tp);
+ sx_xlock(&proctree_lock);
+ tty_lock(tp);
+
+ if (!SESS_LEADER(p)) {
+ sx_xunlock(&proctree_lock);
+ return (EPERM);
+ }
+
+ session = p->p_session;
+ /* Session doesn't have a controlling TTY, nothing to do here. */
+ if (session->s_ttyp == NULL && session->s_ttyvp == NULL &&
+ session->s_ttydp == NULL) {
+ sx_xunlock(&proctree_lock);
+ return (ENXIO);
+ }
+
+ /*
+ * Lock the controlling TTY as well, as needed. If we were called on
+ * the controlling TTY, which will be the case if the process had a
+ * controlling tty when /dev/tty was opened, then we don't need to
+ * re-lock. The tty we were called on could be some other TTY, though,
+ * in which case we also want to make sure to lock the
+ * controlling TTY.
+ */
+ ctty = session->s_ttyp;
+ if (ctty != tp)
+ tty_lock(ctty);
+
+ PROC_LOCK(p);
+ SESS_LOCK(session);
+ vp = session->s_ttyvp;
+ session->s_ttyp = NULL;
+ session->s_ttyvp = NULL;
+ session->s_ttydp = NULL;
+ SESS_UNLOCK(session);
+
+ ctty->t_sessioncnt--;
+ p->p_flag &= ~P_CONTROLT;
+ PROC_UNLOCK(p);
+ if (ctty != tp)
+ tty_unlock(ctty);
+ sx_xunlock(&proctree_lock);
+
+ /*
+ * If we had a vnode, release our reference. Ordinarily we manage these
+ * at the devfs layer, but TIOCNOTTY is not necessarily called on the
+ * controlling TTY -- in fact, the documentation explicitly states it
+ * must have been called on /dev/tty, but devfs cloning makes this
+ * awkward.
+ */
+ if (vp != NULL)
+ vrele(vp);
+ return (0);
+}
+
/*
* Exposing information about current TTY's through sysctl
*/
@@ -1708,6 +1772,13 @@
MPASS(tp->t_session);
*(int *)data = tp->t_session->s_sid;
return (0);
+ case TIOCNOTTY:
+
+ /*
+ * This is technically wrong. TIOCNOTTY should be called on
+ * /dev/tty, not whichever tty we can get ahold of.
+ */
+ return (tty_drop_ctty(tp, td->td_proc));
case TIOCSCTTY: {
struct proc *p = td->td_proc;

File Metadata

Mime Type
text/plain
Expires
Mon, Apr 6, 10:24 AM (9 m, 4 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30959287
Default Alt Text
D22572.id64948.diff (3 KB)

Event Timeline