Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F140482841
D22572.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D22572.diff
View Options
Index: head/share/man/man4/tty.4
===================================================================
--- head/share/man/man4/tty.4
+++ head/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
@@ -203,7 +202,7 @@
controlling terminal.
For some programs this was a hazard as they
did not want a controlling terminal in the first place, and this
-provided a mechanism to disassociate the controlling terminal from
+provides a mechanism to disassociate the controlling terminal from
the calling process.
It
.Em must
@@ -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: head/sys/fs/devfs/devfs_vnops.c
===================================================================
--- head/sys/fs/devfs/devfs_vnops.c
+++ head/sys/fs/devfs/devfs_vnops.c
@@ -829,9 +829,16 @@
error = ENOTTY;
if (error == 0 && com == TIOCSCTTY) {
- /* Do nothing if reassigning same control tty */
+ /*
+ * Do nothing if reassigning same control tty, or if the
+ * control tty has already disappeared. If it disappeared,
+ * it's because we were racing with TIOCNOTTY. TIOCNOTTY
+ * already took care of releasing the old vnode and we have
+ * nothing left to do.
+ */
sx_slock(&proctree_lock);
- if (td->td_proc->p_session->s_ttyvp == vp) {
+ if (td->td_proc->p_session->s_ttyvp == vp ||
+ td->td_proc->p_session->s_ttyp == NULL) {
sx_sunlock(&proctree_lock);
return (0);
}
Index: head/sys/kern/tty.c
===================================================================
--- head/sys/kern/tty.c
+++ head/sys/kern/tty.c
@@ -1195,6 +1195,71 @@
tty_rel_free(tp);
}
+static int
+tty_drop_ctty(struct tty *tp, struct proc *p)
+{
+ struct session *session;
+ struct vnode *vp;
+
+ /*
+ * This looks terrible, but it's generally safe as long as the tty
+ * hasn't gone away while we had the lock dropped. All of our sanity
+ * checking that this operation is OK happens after we've picked it back
+ * up, so other state changes are generally not fatal and the potential
+ * for this particular operation to happen out-of-order in a
+ * multithreaded scenario is likely a non-issue.
+ */
+ tty_unlock(tp);
+ sx_xlock(&proctree_lock);
+ tty_lock(tp);
+ if (tty_gone(tp)) {
+ sx_xunlock(&proctree_lock);
+ return (ENODEV);
+ }
+
+ /*
+ * If the session doesn't have a controlling TTY, or if we weren't
+ * invoked on the controlling TTY, we'll return ENOIOCTL as we've
+ * historically done.
+ */
+ session = p->p_session;
+ if (session->s_ttyp == NULL || session->s_ttyp != tp) {
+ sx_xunlock(&proctree_lock);
+ return (ENOTTY);
+ }
+
+ if (!SESS_LEADER(p)) {
+ sx_xunlock(&proctree_lock);
+ return (EPERM);
+ }
+
+ 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);
+
+ tp->t_sessioncnt--;
+ p->p_flag &= ~P_CONTROLT;
+ PROC_UNLOCK(p);
+ sx_xunlock(&proctree_lock);
+
+ /*
+ * If we did have a vnode, release our reference. Ordinarily we manage
+ * these at the devfs layer, but we can't necessarily know that we were
+ * invoked on the vnode referenced in the session (i.e. the vnode we
+ * hold a reference to). We explicitly don't check VBAD/VI_DOOMED here
+ * to avoid a vnode leak -- in circumstances elsewhere where we'd hit a
+ * VI_DOOMED vnode, release has been deferred until the controlling TTY
+ * is either changed or released.
+ */
+ if (vp != NULL)
+ vrele(vp);
+ return (0);
+}
+
/*
* Exposing information about current TTY's through sysctl
*/
@@ -1709,6 +1774,8 @@
MPASS(tp->t_session);
*(int *)data = tp->t_session->s_sid;
return (0);
+ case TIOCNOTTY:
+ return (tty_drop_ctty(tp, td->td_proc));
case TIOCSCTTY: {
struct proc *p = td->td_proc;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Dec 25, 11:43 AM (4 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27246942
Default Alt Text
D22572.diff (4 KB)
Attached To
Mode
D22572: (RFC) Implement TIOCNOTTY
Attached
Detach File
Event Timeline
Log In to Comment