Commit ab521dc0 authored by Eric W. Biederman's avatar Eric W. Biederman Committed by Linus Torvalds
Browse files

[PATCH] tty: update the tty layer to work with struct pid



Of kernel subsystems that work with pids the tty layer is probably the largest
consumer.  But it has the nice virtue that the assiation with a session only
lasts until the session leader exits.  Which means that no reference counting
is required.  So using struct pid winds up being a simple optimization to
avoid hash table lookups.

In the long term the use of pid_nr also ensures that when we have multiple pid
spaces mixed everything will work correctly.
Signed-off-by: default avatarEric W. Biederman <eric@maxwell.lnxi.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Oleg Nesterov <oleg@tv-sign.ru>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 3e7cd6c4
...@@ -774,7 +774,7 @@ static irqreturn_t winch_interrupt(int irq, void *data) ...@@ -774,7 +774,7 @@ static irqreturn_t winch_interrupt(int irq, void *data)
line = tty->driver_data; line = tty->driver_data;
chan_window_size(&line->chan_list, &tty->winsize.ws_row, chan_window_size(&line->chan_list, &tty->winsize.ws_row,
&tty->winsize.ws_col); &tty->winsize.ws_col);
kill_pg(tty->pgrp, SIGWINCH, 1); kill_pgrp(tty->pgrp, SIGWINCH, 1);
} }
out: out:
if(winch->fd != -1) if(winch->fd != -1)
......
...@@ -1271,8 +1271,8 @@ static void do_input(struct work_struct *work) ...@@ -1271,8 +1271,8 @@ static void do_input(struct work_struct *work)
// code duplicated from n_tty (ldisc) // code duplicated from n_tty (ldisc)
static inline void isig(int sig, struct tty_struct *tty, int flush) static inline void isig(int sig, struct tty_struct *tty, int flush)
{ {
if (tty->pgrp > 0) if (tty->pgrp)
kill_pg(tty->pgrp, sig, 1); kill_pgrp(tty->pgrp, sig, 1);
if (flush || !L_NOFLSH(tty)) { if (flush || !L_NOFLSH(tty)) {
if ( tty->ldisc.flush_buffer ) if ( tty->ldisc.flush_buffer )
tty->ldisc.flush_buffer(tty); tty->ldisc.flush_buffer(tty);
......
...@@ -579,8 +579,8 @@ static void eraser(unsigned char c, struct tty_struct *tty) ...@@ -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) static inline void isig(int sig, struct tty_struct *tty, int flush)
{ {
if (tty->pgrp > 0) if (tty->pgrp)
kill_pg(tty->pgrp, sig, 1); kill_pgrp(tty->pgrp, sig, 1);
if (flush || !L_NOFLSH(tty)) { if (flush || !L_NOFLSH(tty)) {
n_tty_flush_buffer(tty); n_tty_flush_buffer(tty);
if (tty->driver->flush_buffer) if (tty->driver->flush_buffer)
...@@ -1184,13 +1184,13 @@ static int job_control(struct tty_struct *tty, struct file *file) ...@@ -1184,13 +1184,13 @@ static int job_control(struct tty_struct *tty, struct file *file)
/* don't stop on /dev/console */ /* don't stop on /dev/console */
if (file->f_op->write != redirected_tty_write && if (file->f_op->write != redirected_tty_write &&
current->signal->tty == tty) { current->signal->tty == tty) {
if (tty->pgrp <= 0) if (!tty->pgrp)
printk("read_chan: tty->pgrp <= 0!\n"); printk("read_chan: no tty->pgrp!\n");
else if (process_group(current) != tty->pgrp) { else if (task_pgrp(current) != tty->pgrp) {
if (is_ignored(SIGTTIN) || if (is_ignored(SIGTTIN) ||
is_current_pgrp_orphaned()) is_current_pgrp_orphaned())
return -EIO; return -EIO;
kill_pg(process_group(current), SIGTTIN, 1); kill_pgrp(task_pgrp(current), SIGTTIN, 1);
return -ERESTARTSYS; return -ERESTARTSYS;
} }
} }
......
...@@ -155,7 +155,8 @@ int tty_ioctl(struct inode * inode, struct file * file, ...@@ -155,7 +155,8 @@ int tty_ioctl(struct inode * inode, struct file * file,
unsigned int cmd, unsigned long arg); unsigned int cmd, unsigned long arg);
static int tty_fasync(int fd, struct file * filp, int on); static int tty_fasync(int fd, struct file * filp, int on);
static void release_tty(struct tty_struct *tty, int idx); 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 * alloc_tty_struct - allocate a tty object
...@@ -1110,17 +1111,17 @@ int tty_check_change(struct tty_struct * tty) ...@@ -1110,17 +1111,17 @@ int tty_check_change(struct tty_struct * tty)
{ {
if (current->signal->tty != tty) if (current->signal->tty != tty)
return 0; return 0;
if (tty->pgrp <= 0) { if (!tty->pgrp) {
printk(KERN_WARNING "tty_check_change: tty->pgrp <= 0!\n"); printk(KERN_WARNING "tty_check_change: tty->pgrp == NULL!\n");
return 0; return 0;
} }
if (process_group(current) == tty->pgrp) if (task_pgrp(current) == tty->pgrp)
return 0; return 0;
if (is_ignored(SIGTTOU)) if (is_ignored(SIGTTOU))
return 0; return 0;
if (is_current_pgrp_orphaned()) if (is_current_pgrp_orphaned())
return -EIO; return -EIO;
(void) kill_pg(process_group(current), SIGTTOU, 1); (void) kill_pgrp(task_pgrp(current), SIGTTOU, 1);
return -ERESTARTSYS; return -ERESTARTSYS;
} }
...@@ -1355,8 +1356,8 @@ static void do_tty_hangup(struct work_struct *work) ...@@ -1355,8 +1356,8 @@ static void do_tty_hangup(struct work_struct *work)
tty_release is called */ tty_release is called */
read_lock(&tasklist_lock); read_lock(&tasklist_lock);
if (tty->session > 0) { if (tty->session) {
do_each_task_pid(tty->session, PIDTYPE_SID, p) { do_each_pid_task(tty->session, PIDTYPE_SID, p) {
spin_lock_irq(&p->sighand->siglock); spin_lock_irq(&p->sighand->siglock);
if (p->signal->tty == tty) if (p->signal->tty == tty)
p->signal->tty = NULL; p->signal->tty = NULL;
...@@ -1366,16 +1367,17 @@ static void do_tty_hangup(struct work_struct *work) ...@@ -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(SIGHUP, SEND_SIG_PRIV, p);
__group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p); __group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p);
if (tty->pgrp > 0) put_pid(p->signal->tty_old_pgrp); /* A noop */
p->signal->tty_old_pgrp = tty->pgrp; if (tty->pgrp)
p->signal->tty_old_pgrp = get_pid(tty->pgrp);
spin_unlock_irq(&p->sighand->siglock); 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); read_unlock(&tasklist_lock);
tty->flags = 0; tty->flags = 0;
tty->session = 0; tty->session = NULL;
tty->pgrp = -1; tty->pgrp = NULL;
tty->ctrl_status = 0; tty->ctrl_status = 0;
/* /*
* If one of the devices matches a console pointer, we * If one of the devices matches a console pointer, we
...@@ -1460,12 +1462,12 @@ int tty_hung_up_p(struct file * filp) ...@@ -1460,12 +1462,12 @@ int tty_hung_up_p(struct file * filp)
EXPORT_SYMBOL(tty_hung_up_p); 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; struct task_struct *p;
do_each_task_pid(session, PIDTYPE_SID, p) { do_each_pid_task(session, PIDTYPE_SID, p) {
proc_clear_tty(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) ...@@ -1495,48 +1497,54 @@ static void session_clear_tty(pid_t session)
void disassociate_ctty(int on_exit) void disassociate_ctty(int on_exit)
{ {
struct tty_struct *tty; struct tty_struct *tty;
int tty_pgrp = -1; struct pid *tty_pgrp = NULL;
lock_kernel(); lock_kernel();
mutex_lock(&tty_mutex); mutex_lock(&tty_mutex);
tty = get_current_tty(); tty = get_current_tty();
if (tty) { if (tty) {
tty_pgrp = tty->pgrp; tty_pgrp = get_pid(tty->pgrp);
mutex_unlock(&tty_mutex); mutex_unlock(&tty_mutex);
/* XXX: here we race, there is nothing protecting tty */ /* XXX: here we race, there is nothing protecting tty */
if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY)
tty_vhangup(tty); tty_vhangup(tty);
} else if (on_exit) { } else if (on_exit) {
pid_t old_pgrp; struct pid *old_pgrp;
spin_lock_irq(&current->sighand->siglock); spin_lock_irq(&current->sighand->siglock);
old_pgrp = current->signal->tty_old_pgrp; 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); spin_unlock_irq(&current->sighand->siglock);
if (old_pgrp) { if (old_pgrp) {
kill_pg(old_pgrp, SIGHUP, on_exit); kill_pgrp(old_pgrp, SIGHUP, on_exit);
kill_pg(old_pgrp, SIGCONT, on_exit); kill_pgrp(old_pgrp, SIGCONT, on_exit);
put_pid(old_pgrp);
} }
mutex_unlock(&tty_mutex); mutex_unlock(&tty_mutex);
unlock_kernel(); unlock_kernel();
return; return;
} }
if (tty_pgrp > 0) { if (tty_pgrp) {
kill_pg(tty_pgrp, SIGHUP, on_exit); kill_pgrp(tty_pgrp, SIGHUP, on_exit);
if (!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); spin_lock_irq(&current->sighand->siglock);
tty_pgrp = current->signal->tty_old_pgrp;
current->signal->tty_old_pgrp = 0; current->signal->tty_old_pgrp = 0;
spin_unlock_irq(&current->sighand->siglock); spin_unlock_irq(&current->sighand->siglock);
put_pid(tty_pgrp);
mutex_lock(&tty_mutex); mutex_lock(&tty_mutex);
/* It is possible that do_tty_hangup has free'd this tty */ /* It is possible that do_tty_hangup has free'd this tty */
tty = get_current_tty(); tty = get_current_tty();
if (tty) { if (tty) {
tty->session = 0; put_pid(tty->session);
tty->pgrp = 0; put_pid(tty->pgrp);
tty->session = NULL;
tty->pgrp = NULL;
} else { } else {
#ifdef TTY_DEBUG_HANGUP #ifdef TTY_DEBUG_HANGUP
printk(KERN_DEBUG "error attempted to write to tty [0x%p]" printk(KERN_DEBUG "error attempted to write to tty [0x%p]"
...@@ -1547,7 +1555,7 @@ void disassociate_ctty(int on_exit) ...@@ -1547,7 +1555,7 @@ void disassociate_ctty(int on_exit)
/* Now clear signal->tty under the lock */ /* Now clear signal->tty under the lock */
read_lock(&tasklist_lock); read_lock(&tasklist_lock);
session_clear_tty(process_session(current)); session_clear_tty(task_session(current));
read_unlock(&tasklist_lock); read_unlock(&tasklist_lock);
unlock_kernel(); unlock_kernel();
} }
...@@ -2484,6 +2492,7 @@ static int tty_open(struct inode * inode, struct file * filp) ...@@ -2484,6 +2492,7 @@ static int tty_open(struct inode * inode, struct file * filp)
int index; int index;
dev_t device = inode->i_rdev; dev_t device = inode->i_rdev;
unsigned short saved_flags = filp->f_flags; unsigned short saved_flags = filp->f_flags;
struct pid *old_pgrp;
nonseekable_open(inode, filp); nonseekable_open(inode, filp);
...@@ -2577,15 +2586,17 @@ static int tty_open(struct inode * inode, struct file * filp) ...@@ -2577,15 +2586,17 @@ static int tty_open(struct inode * inode, struct file * filp)
goto retry_open; goto retry_open;
} }
old_pgrp = NULL;
mutex_lock(&tty_mutex); mutex_lock(&tty_mutex);
spin_lock_irq(&current->sighand->siglock); spin_lock_irq(&current->sighand->siglock);
if (!noctty && if (!noctty &&
current->signal->leader && current->signal->leader &&
!current->signal->tty && !current->signal->tty &&
tty->session == 0) tty->session == NULL)
__proc_set_tty(current, tty); old_pgrp = __proc_set_tty(current, tty);
spin_unlock_irq(&current->sighand->siglock); spin_unlock_irq(&current->sighand->siglock);
mutex_unlock(&tty_mutex); mutex_unlock(&tty_mutex);
put_pid(old_pgrp);
return 0; return 0;
} }
...@@ -2724,9 +2735,18 @@ static int tty_fasync(int fd, struct file * filp, int on) ...@@ -2724,9 +2735,18 @@ static int tty_fasync(int fd, struct file * filp, int on)
return retval; return retval;
if (on) { if (on) {
enum pid_type type;
struct pid *pid;
if (!waitqueue_active(&tty->read_wait)) if (!waitqueue_active(&tty->read_wait))
tty->minimum_to_wake = 1; 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) if (retval)
return retval; return retval;
} else { } else {
...@@ -2828,10 +2848,10 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty, ...@@ -2828,10 +2848,10 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty,
} }
} }
#endif #endif
if (tty->pgrp > 0) if (tty->pgrp)
kill_pg(tty->pgrp, SIGWINCH, 1); kill_pgrp(tty->pgrp, SIGWINCH, 1);
if ((real_tty->pgrp != tty->pgrp) && (real_tty->pgrp > 0)) if ((real_tty->pgrp != tty->pgrp) && real_tty->pgrp)
kill_pg(real_tty->pgrp, SIGWINCH, 1); kill_pgrp(real_tty->pgrp, SIGWINCH, 1);
tty->winsize = tmp_ws; tty->winsize = tmp_ws;
real_tty->winsize = tmp_ws; real_tty->winsize = tmp_ws;
done: done:
...@@ -2916,8 +2936,7 @@ static int fionbio(struct file *file, int __user *p) ...@@ -2916,8 +2936,7 @@ static int fionbio(struct file *file, int __user *p)
static int tiocsctty(struct tty_struct *tty, int arg) static int tiocsctty(struct tty_struct *tty, int arg)
{ {
int ret = 0; int ret = 0;
if (current->signal->leader && if (current->signal->leader && (task_session(current) == tty->session))
(process_session(current) == tty->session))
return ret; return ret;
mutex_lock(&tty_mutex); mutex_lock(&tty_mutex);
...@@ -2930,7 +2949,7 @@ static int tiocsctty(struct tty_struct *tty, int arg) ...@@ -2930,7 +2949,7 @@ static int tiocsctty(struct tty_struct *tty, int arg)
goto unlock; goto unlock;
} }
if (tty->session > 0) { if (tty->session) {
/* /*
* This tty is already the controlling * This tty is already the controlling
* tty for another session group! * tty for another session group!
...@@ -2973,7 +2992,7 @@ static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t ...@@ -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) if (tty == real_tty && current->signal->tty != real_tty)
return -ENOTTY; 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 ...@@ -3000,7 +3019,7 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
return retval; return retval;
if (!current->signal->tty || if (!current->signal->tty ||
(current->signal->tty != real_tty) || (current->signal->tty != real_tty) ||
(real_tty->session != process_session(current))) (real_tty->session != task_session(current)))
return -ENOTTY; return -ENOTTY;
if (get_user(pgrp_nr, p)) if (get_user(pgrp_nr, p))
return -EFAULT; return -EFAULT;
...@@ -3015,7 +3034,8 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t ...@@ -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)) if (session_of_pgrp(pgrp) != task_session(current))
goto out_unlock; goto out_unlock;
retval = 0; retval = 0;
real_tty->pgrp = pgrp_nr; put_pid(real_tty->pgrp);
real_tty->pgrp = get_pid(pgrp);
out_unlock: out_unlock:
rcu_read_unlock(); rcu_read_unlock();
return retval; return retval;
...@@ -3041,9 +3061,9 @@ static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t _ ...@@ -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) if (tty == real_tty && current->signal->tty != real_tty)
return -ENOTTY; return -ENOTTY;
if (real_tty->session <= 0) if (!real_tty->session)
return -ENOTTY; 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) ...@@ -3343,7 +3363,7 @@ void __do_SAK(struct tty_struct *tty)
tty_hangup(tty); tty_hangup(tty);
#else #else
struct task_struct *g, *p; struct task_struct *g, *p;
int session; struct pid *session;
int i; int i;
struct file *filp; struct file *filp;
struct fdtable *fdt; struct fdtable *fdt;
...@@ -3359,12 +3379,12 @@ void __do_SAK(struct tty_struct *tty) ...@@ -3359,12 +3379,12 @@ void __do_SAK(struct tty_struct *tty)
read_lock(&tasklist_lock); read_lock(&tasklist_lock);
/* Kill the entire session */ /* 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" printk(KERN_NOTICE "SAK: killed process %d"
" (%s): process_session(p)==tty->session\n", " (%s): process_session(p)==tty->session\n",
p->pid, p->comm); p->pid, p->comm);
send_sig(SIGKILL, p, 1); 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 /* Now kill any processes that happen to have the
* tty open. * tty open.
*/ */
...@@ -3533,7 +3553,8 @@ static void initialize_tty_struct(struct tty_struct *tty) ...@@ -3533,7 +3553,8 @@ static void initialize_tty_struct(struct tty_struct *tty)
memset(tty, 0, sizeof(struct tty_struct)); memset(tty, 0, sizeof(struct tty_struct));
tty->magic = TTY_MAGIC; tty->magic = TTY_MAGIC;
tty_ldisc_assign(tty, tty_ldisc_get(N_TTY)); tty_ldisc_assign(tty, tty_ldisc_get(N_TTY));
tty->pgrp = -1; tty->session = NULL;
tty->pgrp = NULL;
tty->overrun_time = jiffies; tty->overrun_time = jiffies;
tty->buf.head = tty->buf.tail = NULL; tty->buf.head = tty->buf.tail = NULL;
tty_buffer_init(tty); tty_buffer_init(tty);
...@@ -3804,21 +3825,28 @@ void proc_clear_tty(struct task_struct *p) ...@@ -3804,21 +3825,28 @@ void proc_clear_tty(struct task_struct *p)
} }
EXPORT_SYMBOL(proc_clear_tty); 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) { if (tty) {
tty->session = process_session(tsk); tty->session = get_pid(task_session(tsk));
tty->pgrp = process_group(tsk); tty->pgrp = get_pid(task_pgrp(tsk));
} }
old_pgrp = tsk->signal->tty_old_pgrp;
tsk->signal->tty = tty; 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) void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
{ {
struct pid *old_pgrp;
spin_lock_irq(&tsk->sighand->siglock); spin_lock_irq(&tsk->sighand->siglock);
__proc_set_tty(tsk, tty); old_pgrp = __proc_set_tty(tsk, tty);
spin_unlock_irq(&tsk->sighand->siglock); spin_unlock_irq(&tsk->sighand->siglock);
put_pid(old_pgrp);
} }
struct tty_struct *get_current_tty(void) struct tty_struct *get_current_tty(void)
......
...@@ -866,8 +866,8 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines) ...@@ -866,8 +866,8 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
ws.ws_col = vc->vc_cols; ws.ws_col = vc->vc_cols;
ws.ws_ypixel = vc->vc_scan_lines; ws.ws_ypixel = vc->vc_scan_lines;
if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col) && if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col) &&
vc->vc_tty->pgrp > 0) vc->vc_tty->pgrp)
kill_pg(vc->vc_tty->pgrp, SIGWINCH, 1); kill_pgrp(vc->vc_tty->pgrp, SIGWINCH, 1);
*cws = ws; *cws = ws;
} }
......
...@@ -351,7 +351,7 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole) ...@@ -351,7 +351,7 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
struct signal_struct *sig = task->signal; struct signal_struct *sig = task->signal;
if (sig->tty) { if (sig->tty) {
tty_pgrp = sig->tty->pgrp; tty_pgrp = pid_nr(sig->tty->pgrp);
tty_nr = new_encode_dev(tty_devnum(sig->tty)); tty_nr = new_encode_dev(tty_devnum(sig->tty));
} }
......
...@@ -66,7 +66,7 @@ ...@@ -66,7 +66,7 @@
.cpu_timers = INIT_CPU_TIMERS(sig.cpu_timers), \ .cpu_timers = INIT_CPU_TIMERS(sig.cpu_timers), \
.rlim = INIT_RLIMITS, \ .rlim = INIT_RLIMITS, \
.pgrp = 1, \ .pgrp = 1, \
.tty_old_pgrp = 0, \ .tty_old_pgrp = NULL, \
{ .__session = 1}, \ { .__session = 1}, \
} }
......
...@@ -436,7 +436,7 @@ struct signal_struct { ...@@ -436,7 +436,7 @@ struct signal_struct {