|
@@ -155,7 +155,8 @@ int tty_ioctl(struct inode * inode, struct file * file,
|
|
|
unsigned int cmd, unsigned long arg);
|
|
|
static int tty_fasync(int fd, struct file * filp, int on);
|
|
|
static void release_tty(struct tty_struct *tty, int idx);
|
|
|
-static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty);
|
|
|
+static struct pid *__proc_set_tty(struct task_struct *tsk,
|
|
|
+ struct tty_struct *tty);
|
|
|
|
|
|
/**
|
|
|
* alloc_tty_struct - allocate a tty object
|
|
@@ -1110,17 +1111,17 @@ int tty_check_change(struct tty_struct * tty)
|
|
|
{
|
|
|
if (current->signal->tty != tty)
|
|
|
return 0;
|
|
|
- if (tty->pgrp <= 0) {
|
|
|
- printk(KERN_WARNING "tty_check_change: tty->pgrp <= 0!\n");
|
|
|
+ if (!tty->pgrp) {
|
|
|
+ printk(KERN_WARNING "tty_check_change: tty->pgrp == NULL!\n");
|
|
|
return 0;
|
|
|
}
|
|
|
- if (process_group(current) == tty->pgrp)
|
|
|
+ if (task_pgrp(current) == tty->pgrp)
|
|
|
return 0;
|
|
|
if (is_ignored(SIGTTOU))
|
|
|
return 0;
|
|
|
if (is_current_pgrp_orphaned())
|
|
|
return -EIO;
|
|
|
- (void) kill_pg(process_group(current), SIGTTOU, 1);
|
|
|
+ (void) kill_pgrp(task_pgrp(current), SIGTTOU, 1);
|
|
|
return -ERESTARTSYS;
|
|
|
}
|
|
|
|
|
@@ -1355,8 +1356,8 @@ static void do_tty_hangup(struct work_struct *work)
|
|
|
tty_release is called */
|
|
|
|
|
|
read_lock(&tasklist_lock);
|
|
|
- if (tty->session > 0) {
|
|
|
- do_each_task_pid(tty->session, PIDTYPE_SID, p) {
|
|
|
+ if (tty->session) {
|
|
|
+ do_each_pid_task(tty->session, PIDTYPE_SID, p) {
|
|
|
spin_lock_irq(&p->sighand->siglock);
|
|
|
if (p->signal->tty == tty)
|
|
|
p->signal->tty = NULL;
|
|
@@ -1366,16 +1367,17 @@ static void do_tty_hangup(struct work_struct *work)
|
|
|
}
|
|
|
__group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p);
|
|
|
__group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p);
|
|
|
- if (tty->pgrp > 0)
|
|
|
- p->signal->tty_old_pgrp = tty->pgrp;
|
|
|
+ put_pid(p->signal->tty_old_pgrp); /* A noop */
|
|
|
+ if (tty->pgrp)
|
|
|
+ p->signal->tty_old_pgrp = get_pid(tty->pgrp);
|
|
|
spin_unlock_irq(&p->sighand->siglock);
|
|
|
- } while_each_task_pid(tty->session, PIDTYPE_SID, p);
|
|
|
+ } while_each_pid_task(tty->session, PIDTYPE_SID, p);
|
|
|
}
|
|
|
read_unlock(&tasklist_lock);
|
|
|
|
|
|
tty->flags = 0;
|
|
|
- tty->session = 0;
|
|
|
- tty->pgrp = -1;
|
|
|
+ tty->session = NULL;
|
|
|
+ tty->pgrp = NULL;
|
|
|
tty->ctrl_status = 0;
|
|
|
/*
|
|
|
* If one of the devices matches a console pointer, we
|
|
@@ -1460,12 +1462,12 @@ int tty_hung_up_p(struct file * filp)
|
|
|
|
|
|
EXPORT_SYMBOL(tty_hung_up_p);
|
|
|
|
|
|
-static void session_clear_tty(pid_t session)
|
|
|
+static void session_clear_tty(struct pid *session)
|
|
|
{
|
|
|
struct task_struct *p;
|
|
|
- do_each_task_pid(session, PIDTYPE_SID, p) {
|
|
|
+ do_each_pid_task(session, PIDTYPE_SID, p) {
|
|
|
proc_clear_tty(p);
|
|
|
- } while_each_task_pid(session, PIDTYPE_SID, p);
|
|
|
+ } while_each_pid_task(session, PIDTYPE_SID, p);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -1495,48 +1497,54 @@ static void session_clear_tty(pid_t session)
|
|
|
void disassociate_ctty(int on_exit)
|
|
|
{
|
|
|
struct tty_struct *tty;
|
|
|
- int tty_pgrp = -1;
|
|
|
+ struct pid *tty_pgrp = NULL;
|
|
|
|
|
|
lock_kernel();
|
|
|
|
|
|
mutex_lock(&tty_mutex);
|
|
|
tty = get_current_tty();
|
|
|
if (tty) {
|
|
|
- tty_pgrp = tty->pgrp;
|
|
|
+ tty_pgrp = get_pid(tty->pgrp);
|
|
|
mutex_unlock(&tty_mutex);
|
|
|
/* XXX: here we race, there is nothing protecting tty */
|
|
|
if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY)
|
|
|
tty_vhangup(tty);
|
|
|
} else if (on_exit) {
|
|
|
- pid_t old_pgrp;
|
|
|
+ struct pid *old_pgrp;
|
|
|
spin_lock_irq(¤t->sighand->siglock);
|
|
|
old_pgrp = current->signal->tty_old_pgrp;
|
|
|
- current->signal->tty_old_pgrp = 0;
|
|
|
+ current->signal->tty_old_pgrp = NULL;
|
|
|
spin_unlock_irq(¤t->sighand->siglock);
|
|
|
if (old_pgrp) {
|
|
|
- kill_pg(old_pgrp, SIGHUP, on_exit);
|
|
|
- kill_pg(old_pgrp, SIGCONT, on_exit);
|
|
|
+ kill_pgrp(old_pgrp, SIGHUP, on_exit);
|
|
|
+ kill_pgrp(old_pgrp, SIGCONT, on_exit);
|
|
|
+ put_pid(old_pgrp);
|
|
|
}
|
|
|
mutex_unlock(&tty_mutex);
|
|
|
unlock_kernel();
|
|
|
return;
|
|
|
}
|
|
|
- if (tty_pgrp > 0) {
|
|
|
- kill_pg(tty_pgrp, SIGHUP, on_exit);
|
|
|
+ if (tty_pgrp) {
|
|
|
+ kill_pgrp(tty_pgrp, SIGHUP, on_exit);
|
|
|
if (!on_exit)
|
|
|
- kill_pg(tty_pgrp, SIGCONT, on_exit);
|
|
|
+ kill_pgrp(tty_pgrp, SIGCONT, on_exit);
|
|
|
+ put_pid(tty_pgrp);
|
|
|
}
|
|
|
|
|
|
spin_lock_irq(¤t->sighand->siglock);
|
|
|
+ tty_pgrp = current->signal->tty_old_pgrp;
|
|
|
current->signal->tty_old_pgrp = 0;
|
|
|
spin_unlock_irq(¤t->sighand->siglock);
|
|
|
+ put_pid(tty_pgrp);
|
|
|
|
|
|
mutex_lock(&tty_mutex);
|
|
|
/* It is possible that do_tty_hangup has free'd this tty */
|
|
|
tty = get_current_tty();
|
|
|
if (tty) {
|
|
|
- tty->session = 0;
|
|
|
- tty->pgrp = 0;
|
|
|
+ put_pid(tty->session);
|
|
|
+ put_pid(tty->pgrp);
|
|
|
+ tty->session = NULL;
|
|
|
+ tty->pgrp = NULL;
|
|
|
} else {
|
|
|
#ifdef TTY_DEBUG_HANGUP
|
|
|
printk(KERN_DEBUG "error attempted to write to tty [0x%p]"
|
|
@@ -1547,7 +1555,7 @@ void disassociate_ctty(int on_exit)
|
|
|
|
|
|
/* Now clear signal->tty under the lock */
|
|
|
read_lock(&tasklist_lock);
|
|
|
- session_clear_tty(process_session(current));
|
|
|
+ session_clear_tty(task_session(current));
|
|
|
read_unlock(&tasklist_lock);
|
|
|
unlock_kernel();
|
|
|
}
|
|
@@ -2484,6 +2492,7 @@ static int tty_open(struct inode * inode, struct file * filp)
|
|
|
int index;
|
|
|
dev_t device = inode->i_rdev;
|
|
|
unsigned short saved_flags = filp->f_flags;
|
|
|
+ struct pid *old_pgrp;
|
|
|
|
|
|
nonseekable_open(inode, filp);
|
|
|
|
|
@@ -2577,15 +2586,17 @@ got_driver:
|
|
|
goto retry_open;
|
|
|
}
|
|
|
|
|
|
+ old_pgrp = NULL;
|
|
|
mutex_lock(&tty_mutex);
|
|
|
spin_lock_irq(¤t->sighand->siglock);
|
|
|
if (!noctty &&
|
|
|
current->signal->leader &&
|
|
|
!current->signal->tty &&
|
|
|
- tty->session == 0)
|
|
|
- __proc_set_tty(current, tty);
|
|
|
+ tty->session == NULL)
|
|
|
+ old_pgrp = __proc_set_tty(current, tty);
|
|
|
spin_unlock_irq(¤t->sighand->siglock);
|
|
|
mutex_unlock(&tty_mutex);
|
|
|
+ put_pid(old_pgrp);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
@@ -2724,9 +2735,18 @@ static int tty_fasync(int fd, struct file * filp, int on)
|
|
|
return retval;
|
|
|
|
|
|
if (on) {
|
|
|
+ enum pid_type type;
|
|
|
+ struct pid *pid;
|
|
|
if (!waitqueue_active(&tty->read_wait))
|
|
|
tty->minimum_to_wake = 1;
|
|
|
- retval = f_setown(filp, (-tty->pgrp) ? : current->pid, 0);
|
|
|
+ if (tty->pgrp) {
|
|
|
+ pid = tty->pgrp;
|
|
|
+ type = PIDTYPE_PGID;
|
|
|
+ } else {
|
|
|
+ pid = task_pid(current);
|
|
|
+ type = PIDTYPE_PID;
|
|
|
+ }
|
|
|
+ retval = __f_setown(filp, pid, type, 0);
|
|
|
if (retval)
|
|
|
return retval;
|
|
|
} else {
|
|
@@ -2828,10 +2848,10 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty,
|
|
|
}
|
|
|
}
|
|
|
#endif
|
|
|
- if (tty->pgrp > 0)
|
|
|
- kill_pg(tty->pgrp, SIGWINCH, 1);
|
|
|
- if ((real_tty->pgrp != tty->pgrp) && (real_tty->pgrp > 0))
|
|
|
- kill_pg(real_tty->pgrp, SIGWINCH, 1);
|
|
|
+ if (tty->pgrp)
|
|
|
+ kill_pgrp(tty->pgrp, SIGWINCH, 1);
|
|
|
+ if ((real_tty->pgrp != tty->pgrp) && real_tty->pgrp)
|
|
|
+ kill_pgrp(real_tty->pgrp, SIGWINCH, 1);
|
|
|
tty->winsize = tmp_ws;
|
|
|
real_tty->winsize = tmp_ws;
|
|
|
done:
|
|
@@ -2916,8 +2936,7 @@ static int fionbio(struct file *file, int __user *p)
|
|
|
static int tiocsctty(struct tty_struct *tty, int arg)
|
|
|
{
|
|
|
int ret = 0;
|
|
|
- if (current->signal->leader &&
|
|
|
- (process_session(current) == tty->session))
|
|
|
+ if (current->signal->leader && (task_session(current) == tty->session))
|
|
|
return ret;
|
|
|
|
|
|
mutex_lock(&tty_mutex);
|
|
@@ -2930,7 +2949,7 @@ static int tiocsctty(struct tty_struct *tty, int arg)
|
|
|
goto unlock;
|
|
|
}
|
|
|
|
|
|
- if (tty->session > 0) {
|
|
|
+ if (tty->session) {
|
|
|
/*
|
|
|
* This tty is already the controlling
|
|
|
* tty for another session group!
|
|
@@ -2973,7 +2992,7 @@ static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
|
|
|
*/
|
|
|
if (tty == real_tty && current->signal->tty != real_tty)
|
|
|
return -ENOTTY;
|
|
|
- return put_user(real_tty->pgrp, p);
|
|
|
+ return put_user(pid_nr(real_tty->pgrp), p);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -3000,7 +3019,7 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
|
|
|
return retval;
|
|
|
if (!current->signal->tty ||
|
|
|
(current->signal->tty != real_tty) ||
|
|
|
- (real_tty->session != process_session(current)))
|
|
|
+ (real_tty->session != task_session(current)))
|
|
|
return -ENOTTY;
|
|
|
if (get_user(pgrp_nr, p))
|
|
|
return -EFAULT;
|
|
@@ -3015,7 +3034,8 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
|
|
|
if (session_of_pgrp(pgrp) != task_session(current))
|
|
|
goto out_unlock;
|
|
|
retval = 0;
|
|
|
- real_tty->pgrp = pgrp_nr;
|
|
|
+ put_pid(real_tty->pgrp);
|
|
|
+ real_tty->pgrp = get_pid(pgrp);
|
|
|
out_unlock:
|
|
|
rcu_read_unlock();
|
|
|
return retval;
|
|
@@ -3041,9 +3061,9 @@ static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t _
|
|
|
*/
|
|
|
if (tty == real_tty && current->signal->tty != real_tty)
|
|
|
return -ENOTTY;
|
|
|
- if (real_tty->session <= 0)
|
|
|
+ if (!real_tty->session)
|
|
|
return -ENOTTY;
|
|
|
- return put_user(real_tty->session, p);
|
|
|
+ return put_user(pid_nr(real_tty->session), p);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -3343,7 +3363,7 @@ void __do_SAK(struct tty_struct *tty)
|
|
|
tty_hangup(tty);
|
|
|
#else
|
|
|
struct task_struct *g, *p;
|
|
|
- int session;
|
|
|
+ struct pid *session;
|
|
|
int i;
|
|
|
struct file *filp;
|
|
|
struct fdtable *fdt;
|
|
@@ -3359,12 +3379,12 @@ void __do_SAK(struct tty_struct *tty)
|
|
|
|
|
|
read_lock(&tasklist_lock);
|
|
|
/* Kill the entire session */
|
|
|
- do_each_task_pid(session, PIDTYPE_SID, p) {
|
|
|
+ do_each_pid_task(session, PIDTYPE_SID, p) {
|
|
|
printk(KERN_NOTICE "SAK: killed process %d"
|
|
|
" (%s): process_session(p)==tty->session\n",
|
|
|
p->pid, p->comm);
|
|
|
send_sig(SIGKILL, p, 1);
|
|
|
- } while_each_task_pid(session, PIDTYPE_SID, p);
|
|
|
+ } while_each_pid_task(session, PIDTYPE_SID, p);
|
|
|
/* Now kill any processes that happen to have the
|
|
|
* tty open.
|
|
|
*/
|
|
@@ -3533,7 +3553,8 @@ static void initialize_tty_struct(struct tty_struct *tty)
|
|
|
memset(tty, 0, sizeof(struct tty_struct));
|
|
|
tty->magic = TTY_MAGIC;
|
|
|
tty_ldisc_assign(tty, tty_ldisc_get(N_TTY));
|
|
|
- tty->pgrp = -1;
|
|
|
+ tty->session = NULL;
|
|
|
+ tty->pgrp = NULL;
|
|
|
tty->overrun_time = jiffies;
|
|
|
tty->buf.head = tty->buf.tail = NULL;
|
|
|
tty_buffer_init(tty);
|
|
@@ -3804,21 +3825,28 @@ void proc_clear_tty(struct task_struct *p)
|
|
|
}
|
|
|
EXPORT_SYMBOL(proc_clear_tty);
|
|
|
|
|
|
-static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
|
|
|
+static struct pid *__proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
|
|
|
{
|
|
|
+ struct pid *old_pgrp;
|
|
|
if (tty) {
|
|
|
- tty->session = process_session(tsk);
|
|
|
- tty->pgrp = process_group(tsk);
|
|
|
+ tty->session = get_pid(task_session(tsk));
|
|
|
+ tty->pgrp = get_pid(task_pgrp(tsk));
|
|
|
}
|
|
|
+ old_pgrp = tsk->signal->tty_old_pgrp;
|
|
|
tsk->signal->tty = tty;
|
|
|
- tsk->signal->tty_old_pgrp = 0;
|
|
|
+ tsk->signal->tty_old_pgrp = NULL;
|
|
|
+ return old_pgrp;
|
|
|
}
|
|
|
|
|
|
void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
|
|
|
{
|
|
|
+ struct pid *old_pgrp;
|
|
|
+
|
|
|
spin_lock_irq(&tsk->sighand->siglock);
|
|
|
- __proc_set_tty(tsk, tty);
|
|
|
+ old_pgrp = __proc_set_tty(tsk, tty);
|
|
|
spin_unlock_irq(&tsk->sighand->siglock);
|
|
|
+
|
|
|
+ put_pid(old_pgrp);
|
|
|
}
|
|
|
|
|
|
struct tty_struct *get_current_tty(void)
|