Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/tty.c
Show First 20 Lines • Show All 1,697 Lines • ▼ Show 20 Lines | case TIOCGSID: | ||||
MPASS(tp->t_session); | MPASS(tp->t_session); | ||||
*(int *)data = tp->t_session->s_sid; | *(int *)data = tp->t_session->s_sid; | ||||
return (0); | return (0); | ||||
case TIOCSCTTY: { | case TIOCSCTTY: { | ||||
struct proc *p = td->td_proc; | struct proc *p = td->td_proc; | ||||
/* XXX: This looks awful. */ | /* XXX: This looks awful. */ | ||||
tty_unlock(tp); | tty_unlock(tp); | ||||
sx_xlock(&proctree_lock); | sx_xlock(&V_proctree_lock); | ||||
tty_lock(tp); | tty_lock(tp); | ||||
if (!SESS_LEADER(p)) { | if (!SESS_LEADER(p)) { | ||||
/* Only the session leader may do this. */ | /* Only the session leader may do this. */ | ||||
sx_xunlock(&proctree_lock); | sx_xunlock(&V_proctree_lock); | ||||
return (EPERM); | return (EPERM); | ||||
} | } | ||||
if (tp->t_session != NULL && tp->t_session == p->p_session) { | if (tp->t_session != NULL && tp->t_session == p->p_session) { | ||||
/* This is already our controlling TTY. */ | /* This is already our controlling TTY. */ | ||||
sx_xunlock(&proctree_lock); | sx_xunlock(&V_proctree_lock); | ||||
return (0); | return (0); | ||||
} | } | ||||
if (p->p_session->s_ttyp != NULL || | if (p->p_session->s_ttyp != NULL || | ||||
(tp->t_session != NULL && tp->t_session->s_ttyvp != NULL && | (tp->t_session != NULL && tp->t_session->s_ttyvp != NULL && | ||||
tp->t_session->s_ttyvp->v_type != VBAD)) { | tp->t_session->s_ttyvp->v_type != VBAD)) { | ||||
/* | /* | ||||
* There is already a relation between a TTY and | * There is already a relation between a TTY and | ||||
* a session, or the caller is not the session | * a session, or the caller is not the session | ||||
* leader. | * leader. | ||||
* | * | ||||
* Allow the TTY to be stolen when the vnode is | * Allow the TTY to be stolen when the vnode is | ||||
* invalid, but the reference to the TTY is | * invalid, but the reference to the TTY is | ||||
* still active. This allows immediate reuse of | * still active. This allows immediate reuse of | ||||
* TTYs of which the session leader has been | * TTYs of which the session leader has been | ||||
* killed or the TTY revoked. | * killed or the TTY revoked. | ||||
*/ | */ | ||||
sx_xunlock(&proctree_lock); | sx_xunlock(&V_proctree_lock); | ||||
return (EPERM); | return (EPERM); | ||||
} | } | ||||
/* Connect the session to the TTY. */ | /* Connect the session to the TTY. */ | ||||
tp->t_session = p->p_session; | tp->t_session = p->p_session; | ||||
tp->t_session->s_ttyp = tp; | tp->t_session->s_ttyp = tp; | ||||
tp->t_sessioncnt++; | tp->t_sessioncnt++; | ||||
sx_xunlock(&proctree_lock); | sx_xunlock(&V_proctree_lock); | ||||
/* Assign foreground process group. */ | /* Assign foreground process group. */ | ||||
tp->t_pgrp = p->p_pgrp; | tp->t_pgrp = p->p_pgrp; | ||||
PROC_LOCK(p); | PROC_LOCK(p); | ||||
p->p_flag |= P_CONTROLT; | p->p_flag |= P_CONTROLT; | ||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
return (0); | return (0); | ||||
} | } | ||||
case TIOCSPGRP: { | case TIOCSPGRP: { | ||||
struct pgrp *pg; | struct pgrp *pg; | ||||
/* | /* | ||||
* XXX: Temporarily unlock the TTY to locate the process | * XXX: Temporarily unlock the TTY to locate the process | ||||
* group. This code would be lot nicer if we would ever | * group. This code would be lot nicer if we would ever | ||||
* decompose proctree_lock. | * decompose proctree_lock. | ||||
*/ | */ | ||||
tty_unlock(tp); | tty_unlock(tp); | ||||
sx_slock(&proctree_lock); | sx_slock(&V_proctree_lock); | ||||
pg = pgfind(*(int *)data); | pg = pgfind(*(int *)data); | ||||
if (pg != NULL) | if (pg != NULL) | ||||
PGRP_UNLOCK(pg); | PGRP_UNLOCK(pg); | ||||
if (pg == NULL || pg->pg_session != td->td_proc->p_session) { | if (pg == NULL || pg->pg_session != td->td_proc->p_session) { | ||||
sx_sunlock(&proctree_lock); | sx_sunlock(&V_proctree_lock); | ||||
tty_lock(tp); | tty_lock(tp); | ||||
return (EPERM); | return (EPERM); | ||||
} | } | ||||
tty_lock(tp); | tty_lock(tp); | ||||
/* | /* | ||||
* Determine if this TTY is the controlling TTY after | * Determine if this TTY is the controlling TTY after | ||||
* relocking the TTY. | * relocking the TTY. | ||||
*/ | */ | ||||
if (!tty_is_ctty(tp, td->td_proc)) { | if (!tty_is_ctty(tp, td->td_proc)) { | ||||
sx_sunlock(&proctree_lock); | sx_sunlock(&V_proctree_lock); | ||||
return (ENOTTY); | return (ENOTTY); | ||||
} | } | ||||
tp->t_pgrp = pg; | tp->t_pgrp = pg; | ||||
sx_sunlock(&proctree_lock); | sx_sunlock(&V_proctree_lock); | ||||
/* Wake up the background process groups. */ | /* Wake up the background process groups. */ | ||||
cv_broadcast(&tp->t_bgwait); | cv_broadcast(&tp->t_bgwait); | ||||
return (0); | return (0); | ||||
} | } | ||||
case TIOCFLUSH: { | case TIOCFLUSH: { | ||||
int flags = *(int *)data; | int flags = *(int *)data; | ||||
▲ Show 20 Lines • Show All 558 Lines • Show Last 20 Lines |