Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 47945
b: refs/heads/master
c: ab521dc
h: refs/heads/master
i:
  47943: 0454c12
v: v3
  • Loading branch information
Eric W. Biederman authored and Linus Torvalds committed Feb 12, 2007
1 parent f1326b6 commit 3f08f08
Show file tree
Hide file tree
Showing 12 changed files with 97 additions and 70 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3e7cd6c413c9e6fbb5e1ee2acdadb4ababd2d474
refs/heads/master: ab521dc0f8e117fd808d3e425216864d60390500
2 changes: 1 addition & 1 deletion trunk/arch/um/drivers/line.c
Original file line number Diff line number Diff line change
Expand Up @@ -774,7 +774,7 @@ static irqreturn_t winch_interrupt(int irq, void *data)
line = tty->driver_data;
chan_window_size(&line->chan_list, &tty->winsize.ws_row,
&tty->winsize.ws_col);
kill_pg(tty->pgrp, SIGWINCH, 1);
kill_pgrp(tty->pgrp, SIGWINCH, 1);
}
out:
if(winch->fd != -1)
Expand Down
4 changes: 2 additions & 2 deletions trunk/drivers/char/ip2/ip2main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1271,8 +1271,8 @@ static void do_input(struct work_struct *work)
// code duplicated from n_tty (ldisc)
static inline void isig(int sig, struct tty_struct *tty, int flush)
{
if (tty->pgrp > 0)
kill_pg(tty->pgrp, sig, 1);
if (tty->pgrp)
kill_pgrp(tty->pgrp, sig, 1);
if (flush || !L_NOFLSH(tty)) {
if ( tty->ldisc.flush_buffer )
tty->ldisc.flush_buffer(tty);
Expand Down
12 changes: 6 additions & 6 deletions trunk/drivers/char/n_tty.c
Original file line number Diff line number Diff line change
Expand Up @@ -579,8 +579,8 @@ static void eraser(unsigned char c, struct tty_struct *tty)

static inline void isig(int sig, struct tty_struct *tty, int flush)
{
if (tty->pgrp > 0)
kill_pg(tty->pgrp, sig, 1);
if (tty->pgrp)
kill_pgrp(tty->pgrp, sig, 1);
if (flush || !L_NOFLSH(tty)) {
n_tty_flush_buffer(tty);
if (tty->driver->flush_buffer)
Expand Down Expand Up @@ -1184,13 +1184,13 @@ static int job_control(struct tty_struct *tty, struct file *file)
/* don't stop on /dev/console */
if (file->f_op->write != redirected_tty_write &&
current->signal->tty == tty) {
if (tty->pgrp <= 0)
printk("read_chan: tty->pgrp <= 0!\n");
else if (process_group(current) != tty->pgrp) {
if (!tty->pgrp)
printk("read_chan: no tty->pgrp!\n");
else if (task_pgrp(current) != tty->pgrp) {
if (is_ignored(SIGTTIN) ||
is_current_pgrp_orphaned())
return -EIO;
kill_pg(process_group(current), SIGTTIN, 1);
kill_pgrp(task_pgrp(current), SIGTTIN, 1);
return -ERESTARTSYS;
}
}
Expand Down
130 changes: 79 additions & 51 deletions trunk/drivers/char/tty_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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);
}

/**
Expand Down Expand Up @@ -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(&current->sighand->siglock);
old_pgrp = current->signal->tty_old_pgrp;
current->signal->tty_old_pgrp = 0;
current->signal->tty_old_pgrp = NULL;
spin_unlock_irq(&current->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(&current->sighand->siglock);
tty_pgrp = current->signal->tty_old_pgrp;
current->signal->tty_old_pgrp = 0;
spin_unlock_irq(&current->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]"
Expand All @@ -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();
}
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -2577,15 +2586,17 @@ static int tty_open(struct inode * inode, struct file * filp)
goto retry_open;
}

old_pgrp = NULL;
mutex_lock(&tty_mutex);
spin_lock_irq(&current->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(&current->sighand->siglock);
mutex_unlock(&tty_mutex);
put_pid(old_pgrp);
return 0;
}

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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);
Expand All @@ -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!
Expand Down Expand Up @@ -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);
}

/**
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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);
}

/**
Expand Down Expand Up @@ -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;
Expand All @@ -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.
*/
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down
Loading

0 comments on commit 3f08f08

Please sign in to comment.