aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/um/drivers/line.c2
-rw-r--r--drivers/char/ip2/ip2main.c4
-rw-r--r--drivers/char/n_tty.c12
-rw-r--r--drivers/char/tty_io.c130
-rw-r--r--drivers/char/vt.c4
-rw-r--r--fs/proc/array.c2
-rw-r--r--include/linux/init_task.h2
-rw-r--r--include/linux/sched.h2
-rw-r--r--include/linux/tty.h4
-rw-r--r--kernel/fork.c2
-rw-r--r--kernel/sys.c1
11 files changed, 96 insertions, 69 deletions
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 0e1e9a20a4d6..01d4ab6b0ef1 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -774,7 +774,7 @@ static irqreturn_t winch_interrupt(int irq, void *data)
774 line = tty->driver_data; 774 line = tty->driver_data;
775 chan_window_size(&line->chan_list, &tty->winsize.ws_row, 775 chan_window_size(&line->chan_list, &tty->winsize.ws_row,
776 &tty->winsize.ws_col); 776 &tty->winsize.ws_col);
777 kill_pg(tty->pgrp, SIGWINCH, 1); 777 kill_pgrp(tty->pgrp, SIGWINCH, 1);
778 } 778 }
779 out: 779 out:
780 if(winch->fd != -1) 780 if(winch->fd != -1)
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index 7c70310a49b5..83c7258d3580 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -1271,8 +1271,8 @@ static void do_input(struct work_struct *work)
1271// code duplicated from n_tty (ldisc) 1271// code duplicated from n_tty (ldisc)
1272static inline void isig(int sig, struct tty_struct *tty, int flush) 1272static inline void isig(int sig, struct tty_struct *tty, int flush)
1273{ 1273{
1274 if (tty->pgrp > 0) 1274 if (tty->pgrp)
1275 kill_pg(tty->pgrp, sig, 1); 1275 kill_pgrp(tty->pgrp, sig, 1);
1276 if (flush || !L_NOFLSH(tty)) { 1276 if (flush || !L_NOFLSH(tty)) {
1277 if ( tty->ldisc.flush_buffer ) 1277 if ( tty->ldisc.flush_buffer )
1278 tty->ldisc.flush_buffer(tty); 1278 tty->ldisc.flush_buffer(tty);
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index c035c2f1f462..6ac3ca4c723c 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -579,8 +579,8 @@ static void eraser(unsigned char c, struct tty_struct *tty)
579 579
580static inline void isig(int sig, struct tty_struct *tty, int flush) 580static inline void isig(int sig, struct tty_struct *tty, int flush)
581{ 581{
582 if (tty->pgrp > 0) 582 if (tty->pgrp)
583 kill_pg(tty->pgrp, sig, 1); 583 kill_pgrp(tty->pgrp, sig, 1);
584 if (flush || !L_NOFLSH(tty)) { 584 if (flush || !L_NOFLSH(tty)) {
585 n_tty_flush_buffer(tty); 585 n_tty_flush_buffer(tty);
586 if (tty->driver->flush_buffer) 586 if (tty->driver->flush_buffer)
@@ -1184,13 +1184,13 @@ static int job_control(struct tty_struct *tty, struct file *file)
1184 /* don't stop on /dev/console */ 1184 /* don't stop on /dev/console */
1185 if (file->f_op->write != redirected_tty_write && 1185 if (file->f_op->write != redirected_tty_write &&
1186 current->signal->tty == tty) { 1186 current->signal->tty == tty) {
1187 if (tty->pgrp <= 0) 1187 if (!tty->pgrp)
1188 printk("read_chan: tty->pgrp <= 0!\n"); 1188 printk("read_chan: no tty->pgrp!\n");
1189 else if (process_group(current) != tty->pgrp) { 1189 else if (task_pgrp(current) != tty->pgrp) {
1190 if (is_ignored(SIGTTIN) || 1190 if (is_ignored(SIGTTIN) ||
1191 is_current_pgrp_orphaned()) 1191 is_current_pgrp_orphaned())
1192 return -EIO; 1192 return -EIO;
1193 kill_pg(process_group(current), SIGTTIN, 1); 1193 kill_pgrp(task_pgrp(current), SIGTTIN, 1);
1194 return -ERESTARTSYS; 1194 return -ERESTARTSYS;
1195 } 1195 }
1196 } 1196 }
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 94070f7bf389..65672c57470b 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -155,7 +155,8 @@ int tty_ioctl(struct inode * inode, struct file * file,
155 unsigned int cmd, unsigned long arg); 155 unsigned int cmd, unsigned long arg);
156static int tty_fasync(int fd, struct file * filp, int on); 156static int tty_fasync(int fd, struct file * filp, int on);
157static void release_tty(struct tty_struct *tty, int idx); 157static void release_tty(struct tty_struct *tty, int idx);
158static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty); 158static struct pid *__proc_set_tty(struct task_struct *tsk,
159 struct tty_struct *tty);
159 160
160/** 161/**
161 * alloc_tty_struct - allocate a tty object 162 * alloc_tty_struct - allocate a tty object
@@ -1110,17 +1111,17 @@ int tty_check_change(struct tty_struct * tty)
1110{ 1111{
1111 if (current->signal->tty != tty) 1112 if (current->signal->tty != tty)
1112 return 0; 1113 return 0;
1113 if (tty->pgrp <= 0) { 1114 if (!tty->pgrp) {
1114 printk(KERN_WARNING "tty_check_change: tty->pgrp <= 0!\n"); 1115 printk(KERN_WARNING "tty_check_change: tty->pgrp == NULL!\n");
1115 return 0; 1116 return 0;
1116 } 1117 }
1117 if (process_group(current) == tty->pgrp) 1118 if (task_pgrp(current) == tty->pgrp)
1118 return 0; 1119 return 0;
1119 if (is_ignored(SIGTTOU)) 1120 if (is_ignored(SIGTTOU))
1120 return 0; 1121 return 0;
1121 if (is_current_pgrp_orphaned()) 1122 if (is_current_pgrp_orphaned())
1122 return -EIO; 1123 return -EIO;
1123 (void) kill_pg(process_group(current), SIGTTOU, 1); 1124 (void) kill_pgrp(task_pgrp(current), SIGTTOU, 1);
1124 return -ERESTARTSYS; 1125 return -ERESTARTSYS;
1125} 1126}
1126 1127
@@ -1355,8 +1356,8 @@ static void do_tty_hangup(struct work_struct *work)
1355 tty_release is called */ 1356 tty_release is called */
1356 1357
1357 read_lock(&tasklist_lock); 1358 read_lock(&tasklist_lock);
1358 if (tty->session > 0) { 1359 if (tty->session) {
1359 do_each_task_pid(tty->session, PIDTYPE_SID, p) { 1360 do_each_pid_task(tty->session, PIDTYPE_SID, p) {
1360 spin_lock_irq(&p->sighand->siglock); 1361 spin_lock_irq(&p->sighand->siglock);
1361 if (p->signal->tty == tty) 1362 if (p->signal->tty == tty)
1362 p->signal->tty = NULL; 1363 p->signal->tty = NULL;
@@ -1366,16 +1367,17 @@ static void do_tty_hangup(struct work_struct *work)
1366 } 1367 }
1367 __group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p); 1368 __group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p);
1368 __group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p); 1369 __group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p);
1369 if (tty->pgrp > 0) 1370 put_pid(p->signal->tty_old_pgrp); /* A noop */
1370 p->signal->tty_old_pgrp = tty->pgrp; 1371 if (tty->pgrp)
1372 p->signal->tty_old_pgrp = get_pid(tty->pgrp);
1371 spin_unlock_irq(&p->sighand->siglock); 1373 spin_unlock_irq(&p->sighand->siglock);
1372 } while_each_task_pid(tty->session, PIDTYPE_SID, p); 1374 } while_each_pid_task(tty->session, PIDTYPE_SID, p);
1373 } 1375 }
1374 read_unlock(&tasklist_lock); 1376 read_unlock(&tasklist_lock);
1375 1377
1376 tty->flags = 0; 1378 tty->flags = 0;
1377 tty->session = 0; 1379 tty->session = NULL;
1378 tty->pgrp = -1; 1380 tty->pgrp = NULL;
1379 tty->ctrl_status = 0; 1381 tty->ctrl_status = 0;
1380 /* 1382 /*
1381 * If one of the devices matches a console pointer, we 1383 * If one of the devices matches a console pointer, we
@@ -1460,12 +1462,12 @@ int tty_hung_up_p(struct file * filp)
1460 1462
1461EXPORT_SYMBOL(tty_hung_up_p); 1463EXPORT_SYMBOL(tty_hung_up_p);
1462 1464
1463static void session_clear_tty(pid_t session) 1465static void session_clear_tty(struct pid *session)
1464{ 1466{
1465 struct task_struct *p; 1467 struct task_struct *p;
1466 do_each_task_pid(session, PIDTYPE_SID, p) { 1468 do_each_pid_task(session, PIDTYPE_SID, p) {
1467 proc_clear_tty(p); 1469 proc_clear_tty(p);
1468 } while_each_task_pid(session, PIDTYPE_SID, p); 1470 } while_each_pid_task(session, PIDTYPE_SID, p);
1469} 1471}
1470 1472
1471/** 1473/**
@@ -1495,48 +1497,54 @@ static void session_clear_tty(pid_t session)
1495void disassociate_ctty(int on_exit) 1497void disassociate_ctty(int on_exit)
1496{ 1498{
1497 struct tty_struct *tty; 1499 struct tty_struct *tty;
1498 int tty_pgrp = -1; 1500 struct pid *tty_pgrp = NULL;
1499 1501
1500 lock_kernel(); 1502 lock_kernel();
1501 1503
1502 mutex_lock(&tty_mutex); 1504 mutex_lock(&tty_mutex);
1503 tty = get_current_tty(); 1505 tty = get_current_tty();
1504 if (tty) { 1506 if (tty) {
1505 tty_pgrp = tty->pgrp; 1507 tty_pgrp = get_pid(tty->pgrp);
1506 mutex_unlock(&tty_mutex); 1508 mutex_unlock(&tty_mutex);
1507 /* XXX: here we race, there is nothing protecting tty */ 1509 /* XXX: here we race, there is nothing protecting tty */
1508 if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) 1510 if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY)
1509 tty_vhangup(tty); 1511 tty_vhangup(tty);
1510 } else if (on_exit) { 1512 } else if (on_exit) {
1511 pid_t old_pgrp; 1513 struct pid *old_pgrp;
1512 spin_lock_irq(&current->sighand->siglock); 1514 spin_lock_irq(&current->sighand->siglock);
1513 old_pgrp = current->signal->tty_old_pgrp; 1515 old_pgrp = current->signal->tty_old_pgrp;
1514 current->signal->tty_old_pgrp = 0; 1516 current->signal->tty_old_pgrp = NULL;
1515 spin_unlock_irq(&current->sighand->siglock); 1517 spin_unlock_irq(&current->sighand->siglock);
1516 if (old_pgrp) { 1518 if (old_pgrp) {
1517 kill_pg(old_pgrp, SIGHUP, on_exit); 1519 kill_pgrp(old_pgrp, SIGHUP, on_exit);
1518 kill_pg(old_pgrp, SIGCONT, on_exit); 1520 kill_pgrp(old_pgrp, SIGCONT, on_exit);
1521 put_pid(old_pgrp);
1519 } 1522 }
1520 mutex_unlock(&tty_mutex); 1523 mutex_unlock(&tty_mutex);
1521 unlock_kernel(); 1524 unlock_kernel();
1522 return; 1525 return;
1523 } 1526 }
1524 if (tty_pgrp > 0) { 1527 if (tty_pgrp) {
1525 kill_pg(tty_pgrp, SIGHUP, on_exit); 1528 kill_pgrp(tty_pgrp, SIGHUP, on_exit);
1526 if (!on_exit) 1529 if (!on_exit)
1527 kill_pg(tty_pgrp, SIGCONT, on_exit); 1530 kill_pgrp(tty_pgrp, SIGCONT, on_exit);
1531 put_pid(tty_pgrp);
1528 } 1532 }
1529 1533
1530 spin_lock_irq(&current->sighand->siglock); 1534 spin_lock_irq(&current->sighand->siglock);
1535 tty_pgrp = current->signal->tty_old_pgrp;
1531 current->signal->tty_old_pgrp = 0; 1536 current->signal->tty_old_pgrp = 0;
1532 spin_unlock_irq(&current->sighand->siglock); 1537 spin_unlock_irq(&current->sighand->siglock);
1538 put_pid(tty_pgrp);
1533 1539
1534 mutex_lock(&tty_mutex); 1540 mutex_lock(&tty_mutex);
1535 /* It is possible that do_tty_hangup has free'd this tty */ 1541 /* It is possible that do_tty_hangup has free'd this tty */
1536 tty = get_current_tty(); 1542 tty = get_current_tty();
1537 if (tty) { 1543 if (tty) {
1538 tty->session = 0; 1544 put_pid(tty->session);
1539 tty->pgrp = 0; 1545 put_pid(tty->pgrp);
1546 tty->session = NULL;
1547 tty->pgrp = NULL;
1540 } else { 1548 } else {
1541#ifdef TTY_DEBUG_HANGUP 1549#ifdef TTY_DEBUG_HANGUP
1542 printk(KERN_DEBUG "error attempted to write to tty [0x%p]" 1550 printk(KERN_DEBUG "error attempted to write to tty [0x%p]"
@@ -1547,7 +1555,7 @@ void disassociate_ctty(int on_exit)
1547 1555
1548 /* Now clear signal->tty under the lock */ 1556 /* Now clear signal->tty under the lock */
1549 read_lock(&tasklist_lock); 1557 read_lock(&tasklist_lock);
1550 session_clear_tty(process_session(current)); 1558 session_clear_tty(task_session(current));
1551 read_unlock(&tasklist_lock); 1559 read_unlock(&tasklist_lock);
1552 unlock_kernel(); 1560 unlock_kernel();
1553} 1561}
@@ -2484,6 +2492,7 @@ static int tty_open(struct inode * inode, struct file * filp)
2484 int index; 2492 int index;
2485 dev_t device = inode->i_rdev; 2493 dev_t device = inode->i_rdev;
2486 unsigned short saved_flags = filp->f_flags; 2494 unsigned short saved_flags = filp->f_flags;
2495 struct pid *old_pgrp;
2487 2496
2488 nonseekable_open(inode, filp); 2497 nonseekable_open(inode, filp);
2489 2498
@@ -2577,15 +2586,17 @@ got_driver:
2577 goto retry_open; 2586 goto retry_open;
2578 } 2587 }
2579 2588
2589 old_pgrp = NULL;
2580 mutex_lock(&tty_mutex); 2590 mutex_lock(&tty_mutex);
2581 spin_lock_irq(&current->sighand->siglock); 2591 spin_lock_irq(&current->sighand->siglock);
2582 if (!noctty && 2592 if (!noctty &&
2583 current->signal->leader && 2593 current->signal->leader &&
2584 !current->signal->tty && 2594 !current->signal->tty &&
2585 tty->session == 0) 2595 tty->session == NULL)
2586 __proc_set_tty(current, tty); 2596 old_pgrp = __proc_set_tty(current, tty);
2587 spin_unlock_irq(&current->sighand->siglock); 2597 spin_unlock_irq(&current->sighand->siglock);
2588 mutex_unlock(&tty_mutex); 2598 mutex_unlock(&tty_mutex);
2599 put_pid(old_pgrp);
2589 return 0; 2600 return 0;
2590} 2601}
2591 2602
@@ -2724,9 +2735,18 @@ static int tty_fasync(int fd, struct file * filp, int on)
2724 return retval; 2735 return retval;
2725 2736
2726 if (on) { 2737 if (on) {
2738 enum pid_type type;
2739 struct pid *pid;
2727 if (!waitqueue_active(&tty->read_wait)) 2740 if (!waitqueue_active(&tty->read_wait))
2728 tty->minimum_to_wake = 1; 2741 tty->minimum_to_wake = 1;
2729 retval = f_setown(filp, (-tty->pgrp) ? : current->pid, 0); 2742 if (tty->pgrp) {
2743 pid = tty->pgrp;
2744 type = PIDTYPE_PGID;
2745 } else {
2746 pid = task_pid(current);
2747 type = PIDTYPE_PID;
2748 }
2749 retval = __f_setown(filp, pid, type, 0);
2730 if (retval) 2750 if (retval)
2731 return retval; 2751 return retval;
2732 } else { 2752 } else {
@@ -2828,10 +2848,10 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty,
2828 } 2848 }
2829 } 2849 }
2830#endif 2850#endif
2831 if (tty->pgrp > 0) 2851 if (tty->pgrp)
2832 kill_pg(tty->pgrp, SIGWINCH, 1); 2852 kill_pgrp(tty->pgrp, SIGWINCH, 1);
2833 if ((real_tty->pgrp != tty->pgrp) && (real_tty->pgrp > 0)) 2853 if ((real_tty->pgrp != tty->pgrp) && real_tty->pgrp)
2834 kill_pg(real_tty->pgrp, SIGWINCH, 1); 2854 kill_pgrp(real_tty->pgrp, SIGWINCH, 1);
2835 tty->winsize = tmp_ws; 2855 tty->winsize = tmp_ws;
2836 real_tty->winsize = tmp_ws; 2856 real_tty->winsize = tmp_ws;
2837done: 2857done:
@@ -2916,8 +2936,7 @@ static int fionbio(struct file *file, int __user *p)
2916static int tiocsctty(struct tty_struct *tty, int arg) 2936static int tiocsctty(struct tty_struct *tty, int arg)
2917{ 2937{
2918 int ret = 0; 2938 int ret = 0;
2919 if (current->signal->leader && 2939 if (current->signal->leader && (task_session(current) == tty->session))
2920 (process_session(current) == tty->session))
2921 return ret; 2940 return ret;
2922 2941
2923 mutex_lock(&tty_mutex); 2942 mutex_lock(&tty_mutex);
@@ -2930,7 +2949,7 @@ static int tiocsctty(struct tty_struct *tty, int arg)
2930 goto unlock; 2949 goto unlock;
2931 } 2950 }
2932 2951
2933 if (tty->session > 0) { 2952 if (tty->session) {
2934 /* 2953 /*
2935 * This tty is already the controlling 2954 * This tty is already the controlling
2936 * tty for another session group! 2955 * tty for another session group!
@@ -2973,7 +2992,7 @@ static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
2973 */ 2992 */
2974 if (tty == real_tty && current->signal->tty != real_tty) 2993 if (tty == real_tty && current->signal->tty != real_tty)
2975 return -ENOTTY; 2994 return -ENOTTY;
2976 return put_user(real_tty->pgrp, p); 2995 return put_user(pid_nr(real_tty->pgrp), p);
2977} 2996}
2978 2997
2979/** 2998/**
@@ -3000,7 +3019,7 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
3000 return retval; 3019 return retval;
3001 if (!current->signal->tty || 3020 if (!current->signal->tty ||
3002 (current->signal->tty != real_tty) || 3021 (current->signal->tty != real_tty) ||
3003 (real_tty->session != process_session(current))) 3022 (real_tty->session != task_session(current)))
3004 return -ENOTTY; 3023 return -ENOTTY;
3005 if (get_user(pgrp_nr, p)) 3024 if (get_user(pgrp_nr, p))
3006 return -EFAULT; 3025 return -EFAULT;
@@ -3015,7 +3034,8 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t
3015 if (session_of_pgrp(pgrp) != task_session(current)) 3034 if (session_of_pgrp(pgrp) != task_session(current))
3016 goto out_unlock; 3035 goto out_unlock;
3017 retval = 0; 3036 retval = 0;
3018 real_tty->pgrp = pgrp_nr; 3037 put_pid(real_tty->pgrp);
3038 real_tty->pgrp = get_pid(pgrp);
3019out_unlock: 3039out_unlock:
3020 rcu_read_unlock(); 3040 rcu_read_unlock();
3021 return retval; 3041 return retval;
@@ -3041,9 +3061,9 @@ static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t _
3041 */ 3061 */
3042 if (tty == real_tty && current->signal->tty != real_tty) 3062 if (tty == real_tty && current->signal->tty != real_tty)
3043 return -ENOTTY; 3063 return -ENOTTY;
3044 if (real_tty->session <= 0) 3064 if (!real_tty->session)
3045 return -ENOTTY; 3065 return -ENOTTY;
3046 return put_user(real_tty->session, p); 3066 return put_user(pid_nr(real_tty->session), p);
3047} 3067}
3048 3068
3049/** 3069/**
@@ -3343,7 +3363,7 @@ void __do_SAK(struct tty_struct *tty)
3343 tty_hangup(tty); 3363 tty_hangup(tty);
3344#else 3364#else
3345 struct task_struct *g, *p; 3365 struct task_struct *g, *p;
3346 int session; 3366 struct pid *session;
3347 int i; 3367 int i;
3348 struct file *filp; 3368 struct file *filp;
3349 struct fdtable *fdt; 3369 struct fdtable *fdt;
@@ -3359,12 +3379,12 @@ void __do_SAK(struct tty_struct *tty)
3359 3379
3360 read_lock(&tasklist_lock); 3380 read_lock(&tasklist_lock);
3361 /* Kill the entire session */ 3381 /* Kill the entire session */
3362 do_each_task_pid(session, PIDTYPE_SID, p) { 3382 do_each_pid_task(session, PIDTYPE_SID, p) {
3363 printk(KERN_NOTICE "SAK: killed process %d" 3383 printk(KERN_NOTICE "SAK: killed process %d"
3364 " (%s): process_session(p)==tty->session\n", 3384 " (%s): process_session(p)==tty->session\n",
3365 p->pid, p->comm); 3385 p->pid, p->comm);
3366 send_sig(SIGKILL, p, 1); 3386 send_sig(SIGKILL, p, 1);
3367 } while_each_task_pid(session, PIDTYPE_SID, p); 3387 } while_each_pid_task(session, PIDTYPE_SID, p);
3368 /* Now kill any processes that happen to have the 3388 /* Now kill any processes that happen to have the
3369 * tty open. 3389 * tty open.
3370 */ 3390 */
@@ -3533,7 +3553,8 @@ static void initialize_tty_struct(struct tty_struct *tty)
3533 memset(tty, 0, sizeof(struct tty_struct)); 3553 memset(tty, 0, sizeof(struct tty_struct));
3534 tty->magic = TTY_MAGIC; 3554 tty->magic = TTY_MAGIC;
3535 tty_ldisc_assign(tty, tty_ldisc_get(N_TTY)); 3555 tty_ldisc_assign(tty, tty_ldisc_get(N_TTY));
3536 tty->pgrp = -1; 3556 tty->session = NULL;
3557 tty->pgrp = NULL;
3537 tty->overrun_time = jiffies; 3558 tty->overrun_time = jiffies;
3538 tty->buf.head = tty->buf.tail = NULL; 3559 tty->buf.head = tty->buf.tail = NULL;
3539 tty_buffer_init(tty); 3560 tty_buffer_init(tty);
@@ -3804,21 +3825,28 @@ void proc_clear_tty(struct task_struct *p)
3804} 3825}
3805EXPORT_SYMBOL(proc_clear_tty); 3826EXPORT_SYMBOL(proc_clear_tty);
3806 3827
3807static void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) 3828static struct pid *__proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
3808{ 3829{
3830 struct pid *old_pgrp;
3809 if (tty) { 3831 if (tty) {
3810 tty->session = process_session(tsk); 3832 tty->session = get_pid(task_session(tsk));
3811 tty->pgrp = process_group(tsk); 3833 tty->pgrp = get_pid(task_pgrp(tsk));
3812 } 3834 }
3835 old_pgrp = tsk->signal->tty_old_pgrp;
3813 tsk->signal->tty = tty; 3836 tsk->signal->tty = tty;
3814 tsk->signal->tty_old_pgrp = 0; 3837 tsk->signal->tty_old_pgrp = NULL;
3838 return old_pgrp;
3815} 3839}
3816 3840
3817void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) 3841void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty)
3818{ 3842{
3843 struct pid *old_pgrp;
3844
3819 spin_lock_irq(&tsk->sighand->siglock); 3845 spin_lock_irq(&tsk->sighand->siglock);
3820 __proc_set_tty(tsk, tty); 3846 old_pgrp = __proc_set_tty(tsk, tty);
3821 spin_unlock_irq(&tsk->sighand->siglock); 3847 spin_unlock_irq(&tsk->sighand->siglock);
3848
3849 put_pid(old_pgrp);
3822} 3850}
3823 3851
3824struct tty_struct *get_current_tty(void) 3852struct tty_struct *get_current_tty(void)
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index d6694163b6f1..94ce3e7fc9e4 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -866,8 +866,8 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
866 ws.ws_col = vc->vc_cols; 866 ws.ws_col = vc->vc_cols;
867 ws.ws_ypixel = vc->vc_scan_lines; 867 ws.ws_ypixel = vc->vc_scan_lines;
868 if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col) && 868 if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col) &&
869 vc->vc_tty->pgrp > 0) 869 vc->vc_tty->pgrp)
870 kill_pg(vc->vc_tty->pgrp, SIGWINCH, 1); 870 kill_pgrp(vc->vc_tty->pgrp, SIGWINCH, 1);
871 *cws = ws; 871 *cws = ws;
872 } 872 }
873 873
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 70e4fab117b1..07c9cdbcdcac 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -351,7 +351,7 @@ static int do_task_stat(struct task_struct *task, char * buffer, int whole)
351 struct signal_struct *sig = task->signal; 351 struct signal_struct *sig = task->signal;
352 352
353 if (sig->tty) { 353 if (sig->tty) {
354 tty_pgrp = sig->tty->pgrp; 354 tty_pgrp = pid_nr(sig->tty->pgrp);
355 tty_nr = new_encode_dev(tty_devnum(sig->tty)); 355 tty_nr = new_encode_dev(tty_devnum(sig->tty));
356 } 356 }
357 357
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 6383d2d83bb0..a2d95ff50e9b 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -66,7 +66,7 @@
66 .cpu_timers = INIT_CPU_TIMERS(sig.cpu_timers), \ 66 .cpu_timers = INIT_CPU_TIMERS(sig.cpu_timers), \
67 .rlim = INIT_RLIMITS, \ 67 .rlim = INIT_RLIMITS, \
68 .pgrp = 1, \ 68 .pgrp = 1, \
69 .tty_old_pgrp = 0, \ 69 .tty_old_pgrp = NULL, \
70 { .__session = 1}, \ 70 { .__session = 1}, \
71} 71}
72 72
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 76c8e2dc48dd..39d40c518531 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -436,7 +436,7 @@ struct signal_struct {
436 436
437 /* job control IDs */ 437 /* job control IDs */
438 pid_t pgrp; 438 pid_t pgrp;
439 pid_t tty_old_pgrp; 439 struct pid *tty_old_pgrp;
440 440
441 union { 441 union {
442 pid_t session __deprecated; 442 pid_t session __deprecated;
diff --git a/include/linux/tty.h b/include/linux/tty.h
index d0e03c4a71b1..dee72b9a20fb 100644
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -197,8 +197,8 @@ struct tty_struct {
197 struct mutex termios_mutex; 197 struct mutex termios_mutex;
198 struct ktermios *termios, *termios_locked; 198 struct ktermios *termios, *termios_locked;
199 char name[64]; 199 char name[64];
200 int pgrp; 200 struct pid *pgrp;
201 int session; 201 struct pid *session;
202 unsigned long flags; 202 unsigned long flags;
203 int count; 203 int count;
204 struct winsize winsize; 204 struct winsize winsize;
diff --git a/kernel/fork.c b/kernel/fork.c
index 80284eb488ce..0b6293d94d96 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -869,7 +869,7 @@ static inline int copy_signal(unsigned long clone_flags, struct task_struct * ts
869 sig->it_prof_incr = cputime_zero; 869 sig->it_prof_incr = cputime_zero;
870 870
871 sig->leader = 0; /* session leadership doesn't inherit */ 871 sig->leader = 0; /* session leadership doesn't inherit */
872 sig->tty_old_pgrp = 0; 872 sig->tty_old_pgrp = NULL;
873 873
874 sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero; 874 sig->utime = sig->stime = sig->cutime = sig->cstime = cputime_zero;
875 sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0; 875 sig->nvcsw = sig->nivcsw = sig->cnvcsw = sig->cnivcsw = 0;
diff --git a/kernel/sys.c b/kernel/sys.c
index e1024383314d..efcf76e0dada 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1510,7 +1510,6 @@ asmlinkage long sys_setsid(void)
1510 1510
1511 spin_lock(&group_leader->sighand->siglock); 1511 spin_lock(&group_leader->sighand->siglock);
1512 group_leader->signal->tty = NULL; 1512 group_leader->signal->tty = NULL;
1513 group_leader->signal->tty_old_pgrp = 0;
1514 spin_unlock(&group_leader->sighand->siglock); 1513 spin_unlock(&group_leader->sighand->siglock);
1515 1514
1516 err = process_group(group_leader); 1515 err = process_group(group_leader);