diff options
author | Jeff Garzik <jeff@garzik.org> | 2007-02-17 15:09:59 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-02-17 15:09:59 -0500 |
commit | 48c871c1f6a7c7044dd76774fb469e65c7e2e4e8 (patch) | |
tree | da3aa535c98cc0957851354ceb0fbff7482d7a9d /drivers/char/tty_io.c | |
parent | 1a1689344add3333d28d1b5495d8043a3877d01c (diff) | |
parent | 4409d28140d9a6e6e3f4f1fdaf7234c4b965d954 (diff) |
Merge branch 'gfar' of master.kernel.org:/pub/scm/linux/kernel/git/galak/powerpc into upstream
Diffstat (limited to 'drivers/char/tty_io.c')
-rw-r--r-- | drivers/char/tty_io.c | 246 |
1 files changed, 146 insertions, 100 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 47a6eacb10bc..65672c57470b 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -154,7 +154,9 @@ static int tty_release(struct inode *, struct file *); | |||
154 | int tty_ioctl(struct inode * inode, struct file * file, | 154 | int tty_ioctl(struct inode * inode, struct file * file, |
155 | unsigned int cmd, unsigned long arg); | 155 | unsigned int cmd, unsigned long arg); |
156 | static int tty_fasync(int fd, struct file * filp, int on); | 156 | static int tty_fasync(int fd, struct file * filp, int on); |
157 | static void release_mem(struct tty_struct *tty, int idx); | 157 | static void release_tty(struct tty_struct *tty, int idx); |
158 | static struct pid *__proc_set_tty(struct task_struct *tsk, | ||
159 | struct tty_struct *tty); | ||
158 | 160 | ||
159 | /** | 161 | /** |
160 | * alloc_tty_struct - allocate a tty object | 162 | * alloc_tty_struct - allocate a tty object |
@@ -1109,17 +1111,17 @@ int tty_check_change(struct tty_struct * tty) | |||
1109 | { | 1111 | { |
1110 | if (current->signal->tty != tty) | 1112 | if (current->signal->tty != tty) |
1111 | return 0; | 1113 | return 0; |
1112 | if (tty->pgrp <= 0) { | 1114 | if (!tty->pgrp) { |
1113 | printk(KERN_WARNING "tty_check_change: tty->pgrp <= 0!\n"); | 1115 | printk(KERN_WARNING "tty_check_change: tty->pgrp == NULL!\n"); |
1114 | return 0; | 1116 | return 0; |
1115 | } | 1117 | } |
1116 | if (process_group(current) == tty->pgrp) | 1118 | if (task_pgrp(current) == tty->pgrp) |
1117 | return 0; | 1119 | return 0; |
1118 | if (is_ignored(SIGTTOU)) | 1120 | if (is_ignored(SIGTTOU)) |
1119 | return 0; | 1121 | return 0; |
1120 | if (is_orphaned_pgrp(process_group(current))) | 1122 | if (is_current_pgrp_orphaned()) |
1121 | return -EIO; | 1123 | return -EIO; |
1122 | (void) kill_pg(process_group(current), SIGTTOU, 1); | 1124 | (void) kill_pgrp(task_pgrp(current), SIGTTOU, 1); |
1123 | return -ERESTARTSYS; | 1125 | return -ERESTARTSYS; |
1124 | } | 1126 | } |
1125 | 1127 | ||
@@ -1354,8 +1356,8 @@ static void do_tty_hangup(struct work_struct *work) | |||
1354 | tty_release is called */ | 1356 | tty_release is called */ |
1355 | 1357 | ||
1356 | read_lock(&tasklist_lock); | 1358 | read_lock(&tasklist_lock); |
1357 | if (tty->session > 0) { | 1359 | if (tty->session) { |
1358 | do_each_task_pid(tty->session, PIDTYPE_SID, p) { | 1360 | do_each_pid_task(tty->session, PIDTYPE_SID, p) { |
1359 | spin_lock_irq(&p->sighand->siglock); | 1361 | spin_lock_irq(&p->sighand->siglock); |
1360 | if (p->signal->tty == tty) | 1362 | if (p->signal->tty == tty) |
1361 | p->signal->tty = NULL; | 1363 | p->signal->tty = NULL; |
@@ -1365,16 +1367,17 @@ static void do_tty_hangup(struct work_struct *work) | |||
1365 | } | 1367 | } |
1366 | __group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p); | 1368 | __group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p); |
1367 | __group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p); | 1369 | __group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p); |
1368 | if (tty->pgrp > 0) | 1370 | put_pid(p->signal->tty_old_pgrp); /* A noop */ |
1369 | p->signal->tty_old_pgrp = tty->pgrp; | 1371 | if (tty->pgrp) |
1372 | p->signal->tty_old_pgrp = get_pid(tty->pgrp); | ||
1370 | spin_unlock_irq(&p->sighand->siglock); | 1373 | spin_unlock_irq(&p->sighand->siglock); |
1371 | } while_each_task_pid(tty->session, PIDTYPE_SID, p); | 1374 | } while_each_pid_task(tty->session, PIDTYPE_SID, p); |
1372 | } | 1375 | } |
1373 | read_unlock(&tasklist_lock); | 1376 | read_unlock(&tasklist_lock); |
1374 | 1377 | ||
1375 | tty->flags = 0; | 1378 | tty->flags = 0; |
1376 | tty->session = 0; | 1379 | tty->session = NULL; |
1377 | tty->pgrp = -1; | 1380 | tty->pgrp = NULL; |
1378 | tty->ctrl_status = 0; | 1381 | tty->ctrl_status = 0; |
1379 | /* | 1382 | /* |
1380 | * If one of the devices matches a console pointer, we | 1383 | * If one of the devices matches a console pointer, we |
@@ -1459,12 +1462,12 @@ int tty_hung_up_p(struct file * filp) | |||
1459 | 1462 | ||
1460 | EXPORT_SYMBOL(tty_hung_up_p); | 1463 | EXPORT_SYMBOL(tty_hung_up_p); |
1461 | 1464 | ||
1462 | static void session_clear_tty(pid_t session) | 1465 | static void session_clear_tty(struct pid *session) |
1463 | { | 1466 | { |
1464 | struct task_struct *p; | 1467 | struct task_struct *p; |
1465 | do_each_task_pid(session, PIDTYPE_SID, p) { | 1468 | do_each_pid_task(session, PIDTYPE_SID, p) { |
1466 | proc_clear_tty(p); | 1469 | proc_clear_tty(p); |
1467 | } while_each_task_pid(session, PIDTYPE_SID, p); | 1470 | } while_each_pid_task(session, PIDTYPE_SID, p); |
1468 | } | 1471 | } |
1469 | 1472 | ||
1470 | /** | 1473 | /** |
@@ -1494,46 +1497,54 @@ static void session_clear_tty(pid_t session) | |||
1494 | void disassociate_ctty(int on_exit) | 1497 | void disassociate_ctty(int on_exit) |
1495 | { | 1498 | { |
1496 | struct tty_struct *tty; | 1499 | struct tty_struct *tty; |
1497 | int tty_pgrp = -1; | 1500 | struct pid *tty_pgrp = NULL; |
1498 | int session; | ||
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 { | 1512 | } else if (on_exit) { |
1511 | pid_t old_pgrp = current->signal->tty_old_pgrp; | 1513 | struct pid *old_pgrp; |
1514 | spin_lock_irq(¤t->sighand->siglock); | ||
1515 | old_pgrp = current->signal->tty_old_pgrp; | ||
1516 | current->signal->tty_old_pgrp = NULL; | ||
1517 | spin_unlock_irq(¤t->sighand->siglock); | ||
1512 | if (old_pgrp) { | 1518 | if (old_pgrp) { |
1513 | kill_pg(old_pgrp, SIGHUP, on_exit); | 1519 | kill_pgrp(old_pgrp, SIGHUP, on_exit); |
1514 | kill_pg(old_pgrp, SIGCONT, on_exit); | 1520 | kill_pgrp(old_pgrp, SIGCONT, on_exit); |
1521 | put_pid(old_pgrp); | ||
1515 | } | 1522 | } |
1516 | mutex_unlock(&tty_mutex); | 1523 | mutex_unlock(&tty_mutex); |
1517 | unlock_kernel(); | 1524 | unlock_kernel(); |
1518 | return; | 1525 | return; |
1519 | } | 1526 | } |
1520 | if (tty_pgrp > 0) { | 1527 | if (tty_pgrp) { |
1521 | kill_pg(tty_pgrp, SIGHUP, on_exit); | 1528 | kill_pgrp(tty_pgrp, SIGHUP, on_exit); |
1522 | if (!on_exit) | 1529 | if (!on_exit) |
1523 | kill_pg(tty_pgrp, SIGCONT, on_exit); | 1530 | kill_pgrp(tty_pgrp, SIGCONT, on_exit); |
1531 | put_pid(tty_pgrp); | ||
1524 | } | 1532 | } |
1525 | 1533 | ||
1526 | spin_lock_irq(¤t->sighand->siglock); | 1534 | spin_lock_irq(¤t->sighand->siglock); |
1535 | tty_pgrp = current->signal->tty_old_pgrp; | ||
1527 | current->signal->tty_old_pgrp = 0; | 1536 | current->signal->tty_old_pgrp = 0; |
1528 | session = process_session(current); | ||
1529 | spin_unlock_irq(¤t->sighand->siglock); | 1537 | spin_unlock_irq(¤t->sighand->siglock); |
1538 | put_pid(tty_pgrp); | ||
1530 | 1539 | ||
1531 | mutex_lock(&tty_mutex); | 1540 | mutex_lock(&tty_mutex); |
1532 | /* 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 */ |
1533 | tty = get_current_tty(); | 1542 | tty = get_current_tty(); |
1534 | if (tty) { | 1543 | if (tty) { |
1535 | tty->session = 0; | 1544 | put_pid(tty->session); |
1536 | tty->pgrp = 0; | 1545 | put_pid(tty->pgrp); |
1546 | tty->session = NULL; | ||
1547 | tty->pgrp = NULL; | ||
1537 | } else { | 1548 | } else { |
1538 | #ifdef TTY_DEBUG_HANGUP | 1549 | #ifdef TTY_DEBUG_HANGUP |
1539 | printk(KERN_DEBUG "error attempted to write to tty [0x%p]" | 1550 | printk(KERN_DEBUG "error attempted to write to tty [0x%p]" |
@@ -1544,7 +1555,7 @@ void disassociate_ctty(int on_exit) | |||
1544 | 1555 | ||
1545 | /* Now clear signal->tty under the lock */ | 1556 | /* Now clear signal->tty under the lock */ |
1546 | read_lock(&tasklist_lock); | 1557 | read_lock(&tasklist_lock); |
1547 | session_clear_tty(session); | 1558 | session_clear_tty(task_session(current)); |
1548 | read_unlock(&tasklist_lock); | 1559 | read_unlock(&tasklist_lock); |
1549 | unlock_kernel(); | 1560 | unlock_kernel(); |
1550 | } | 1561 | } |
@@ -1612,7 +1623,6 @@ void start_tty(struct tty_struct *tty) | |||
1612 | 1623 | ||
1613 | /* If we have a running line discipline it may need kicking */ | 1624 | /* If we have a running line discipline it may need kicking */ |
1614 | tty_wakeup(tty); | 1625 | tty_wakeup(tty); |
1615 | wake_up_interruptible(&tty->write_wait); | ||
1616 | } | 1626 | } |
1617 | 1627 | ||
1618 | EXPORT_SYMBOL(start_tty); | 1628 | EXPORT_SYMBOL(start_tty); |
@@ -2003,7 +2013,7 @@ static int init_dev(struct tty_driver *driver, int idx, | |||
2003 | 2013 | ||
2004 | /* | 2014 | /* |
2005 | * All structures have been allocated, so now we install them. | 2015 | * All structures have been allocated, so now we install them. |
2006 | * Failures after this point use release_mem to clean up, so | 2016 | * Failures after this point use release_tty to clean up, so |
2007 | * there's no need to null out the local pointers. | 2017 | * there's no need to null out the local pointers. |
2008 | */ | 2018 | */ |
2009 | if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM)) { | 2019 | if (!(driver->flags & TTY_DRIVER_DEVPTS_MEM)) { |
@@ -2024,8 +2034,8 @@ static int init_dev(struct tty_driver *driver, int idx, | |||
2024 | 2034 | ||
2025 | /* | 2035 | /* |
2026 | * Structures all installed ... call the ldisc open routines. | 2036 | * Structures all installed ... call the ldisc open routines. |
2027 | * If we fail here just call release_mem to clean up. No need | 2037 | * If we fail here just call release_tty to clean up. No need |
2028 | * to decrement the use counts, as release_mem doesn't care. | 2038 | * to decrement the use counts, as release_tty doesn't care. |
2029 | */ | 2039 | */ |
2030 | 2040 | ||
2031 | if (tty->ldisc.open) { | 2041 | if (tty->ldisc.open) { |
@@ -2095,17 +2105,17 @@ fail_no_mem: | |||
2095 | retval = -ENOMEM; | 2105 | retval = -ENOMEM; |
2096 | goto end_init; | 2106 | goto end_init; |
2097 | 2107 | ||
2098 | /* call the tty release_mem routine to clean out this slot */ | 2108 | /* call the tty release_tty routine to clean out this slot */ |
2099 | release_mem_out: | 2109 | release_mem_out: |
2100 | if (printk_ratelimit()) | 2110 | if (printk_ratelimit()) |
2101 | printk(KERN_INFO "init_dev: ldisc open failed, " | 2111 | printk(KERN_INFO "init_dev: ldisc open failed, " |
2102 | "clearing slot %d\n", idx); | 2112 | "clearing slot %d\n", idx); |
2103 | release_mem(tty, idx); | 2113 | release_tty(tty, idx); |
2104 | goto end_init; | 2114 | goto end_init; |
2105 | } | 2115 | } |
2106 | 2116 | ||
2107 | /** | 2117 | /** |
2108 | * release_mem - release tty structure memory | 2118 | * release_one_tty - release tty structure memory |
2109 | * | 2119 | * |
2110 | * Releases memory associated with a tty structure, and clears out the | 2120 | * Releases memory associated with a tty structure, and clears out the |
2111 | * driver table slots. This function is called when a device is no longer | 2121 | * driver table slots. This function is called when a device is no longer |
@@ -2117,37 +2127,14 @@ release_mem_out: | |||
2117 | * of ttys that the driver keeps. | 2127 | * of ttys that the driver keeps. |
2118 | * FIXME: should we require tty_mutex is held here ?? | 2128 | * FIXME: should we require tty_mutex is held here ?? |
2119 | */ | 2129 | */ |
2120 | 2130 | static void release_one_tty(struct tty_struct *tty, int idx) | |
2121 | static void release_mem(struct tty_struct *tty, int idx) | ||
2122 | { | 2131 | { |
2123 | struct tty_struct *o_tty; | ||
2124 | struct ktermios *tp; | ||
2125 | int devpts = tty->driver->flags & TTY_DRIVER_DEVPTS_MEM; | 2132 | int devpts = tty->driver->flags & TTY_DRIVER_DEVPTS_MEM; |
2126 | 2133 | struct ktermios *tp; | |
2127 | if ((o_tty = tty->link) != NULL) { | ||
2128 | if (!devpts) | ||
2129 | o_tty->driver->ttys[idx] = NULL; | ||
2130 | if (o_tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { | ||
2131 | tp = o_tty->termios; | ||
2132 | if (!devpts) | ||
2133 | o_tty->driver->termios[idx] = NULL; | ||
2134 | kfree(tp); | ||
2135 | |||
2136 | tp = o_tty->termios_locked; | ||
2137 | if (!devpts) | ||
2138 | o_tty->driver->termios_locked[idx] = NULL; | ||
2139 | kfree(tp); | ||
2140 | } | ||
2141 | o_tty->magic = 0; | ||
2142 | o_tty->driver->refcount--; | ||
2143 | file_list_lock(); | ||
2144 | list_del_init(&o_tty->tty_files); | ||
2145 | file_list_unlock(); | ||
2146 | free_tty_struct(o_tty); | ||
2147 | } | ||
2148 | 2134 | ||
2149 | if (!devpts) | 2135 | if (!devpts) |
2150 | tty->driver->ttys[idx] = NULL; | 2136 | tty->driver->ttys[idx] = NULL; |
2137 | |||
2151 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { | 2138 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) { |
2152 | tp = tty->termios; | 2139 | tp = tty->termios; |
2153 | if (!devpts) | 2140 | if (!devpts) |
@@ -2160,15 +2147,39 @@ static void release_mem(struct tty_struct *tty, int idx) | |||
2160 | kfree(tp); | 2147 | kfree(tp); |
2161 | } | 2148 | } |
2162 | 2149 | ||
2150 | |||
2163 | tty->magic = 0; | 2151 | tty->magic = 0; |
2164 | tty->driver->refcount--; | 2152 | tty->driver->refcount--; |
2153 | |||
2165 | file_list_lock(); | 2154 | file_list_lock(); |
2166 | list_del_init(&tty->tty_files); | 2155 | list_del_init(&tty->tty_files); |
2167 | file_list_unlock(); | 2156 | file_list_unlock(); |
2168 | module_put(tty->driver->owner); | 2157 | |
2169 | free_tty_struct(tty); | 2158 | free_tty_struct(tty); |
2170 | } | 2159 | } |
2171 | 2160 | ||
2161 | /** | ||
2162 | * release_tty - release tty structure memory | ||
2163 | * | ||
2164 | * Release both @tty and a possible linked partner (think pty pair), | ||
2165 | * and decrement the refcount of the backing module. | ||
2166 | * | ||
2167 | * Locking: | ||
2168 | * tty_mutex - sometimes only | ||
2169 | * takes the file list lock internally when working on the list | ||
2170 | * of ttys that the driver keeps. | ||
2171 | * FIXME: should we require tty_mutex is held here ?? | ||
2172 | */ | ||
2173 | static void release_tty(struct tty_struct *tty, int idx) | ||
2174 | { | ||
2175 | struct tty_driver *driver = tty->driver; | ||
2176 | |||
2177 | if (tty->link) | ||
2178 | release_one_tty(tty->link, idx); | ||
2179 | release_one_tty(tty, idx); | ||
2180 | module_put(driver->owner); | ||
2181 | } | ||
2182 | |||
2172 | /* | 2183 | /* |
2173 | * Even releasing the tty structures is a tricky business.. We have | 2184 | * Even releasing the tty structures is a tricky business.. We have |
2174 | * to be very careful that the structures are all released at the | 2185 | * to be very careful that the structures are all released at the |
@@ -2436,10 +2447,10 @@ static void release_dev(struct file * filp) | |||
2436 | tty_set_termios_ldisc(o_tty,N_TTY); | 2447 | tty_set_termios_ldisc(o_tty,N_TTY); |
2437 | } | 2448 | } |
2438 | /* | 2449 | /* |
2439 | * The release_mem function takes care of the details of clearing | 2450 | * The release_tty function takes care of the details of clearing |
2440 | * the slots and preserving the termios structure. | 2451 | * the slots and preserving the termios structure. |
2441 | */ | 2452 | */ |
2442 | release_mem(tty, idx); | 2453 | release_tty(tty, idx); |
2443 | 2454 | ||
2444 | #ifdef CONFIG_UNIX98_PTYS | 2455 | #ifdef CONFIG_UNIX98_PTYS |
2445 | /* Make this pty number available for reallocation */ | 2456 | /* Make this pty number available for reallocation */ |
@@ -2481,6 +2492,7 @@ static int tty_open(struct inode * inode, struct file * filp) | |||
2481 | int index; | 2492 | int index; |
2482 | dev_t device = inode->i_rdev; | 2493 | dev_t device = inode->i_rdev; |
2483 | unsigned short saved_flags = filp->f_flags; | 2494 | unsigned short saved_flags = filp->f_flags; |
2495 | struct pid *old_pgrp; | ||
2484 | 2496 | ||
2485 | nonseekable_open(inode, filp); | 2497 | nonseekable_open(inode, filp); |
2486 | 2498 | ||
@@ -2574,15 +2586,17 @@ got_driver: | |||
2574 | goto retry_open; | 2586 | goto retry_open; |
2575 | } | 2587 | } |
2576 | 2588 | ||
2589 | old_pgrp = NULL; | ||
2577 | mutex_lock(&tty_mutex); | 2590 | mutex_lock(&tty_mutex); |
2578 | spin_lock_irq(¤t->sighand->siglock); | 2591 | spin_lock_irq(¤t->sighand->siglock); |
2579 | if (!noctty && | 2592 | if (!noctty && |
2580 | current->signal->leader && | 2593 | current->signal->leader && |
2581 | !current->signal->tty && | 2594 | !current->signal->tty && |
2582 | tty->session == 0) | 2595 | tty->session == NULL) |
2583 | __proc_set_tty(current, tty); | 2596 | old_pgrp = __proc_set_tty(current, tty); |
2584 | spin_unlock_irq(¤t->sighand->siglock); | 2597 | spin_unlock_irq(¤t->sighand->siglock); |
2585 | mutex_unlock(&tty_mutex); | 2598 | mutex_unlock(&tty_mutex); |
2599 | put_pid(old_pgrp); | ||
2586 | return 0; | 2600 | return 0; |
2587 | } | 2601 | } |
2588 | 2602 | ||
@@ -2721,9 +2735,18 @@ static int tty_fasync(int fd, struct file * filp, int on) | |||
2721 | return retval; | 2735 | return retval; |
2722 | 2736 | ||
2723 | if (on) { | 2737 | if (on) { |
2738 | enum pid_type type; | ||
2739 | struct pid *pid; | ||
2724 | if (!waitqueue_active(&tty->read_wait)) | 2740 | if (!waitqueue_active(&tty->read_wait)) |
2725 | tty->minimum_to_wake = 1; | 2741 | tty->minimum_to_wake = 1; |
2726 | 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); | ||
2727 | if (retval) | 2750 | if (retval) |
2728 | return retval; | 2751 | return retval; |
2729 | } else { | 2752 | } else { |
@@ -2825,10 +2848,10 @@ static int tiocswinsz(struct tty_struct *tty, struct tty_struct *real_tty, | |||
2825 | } | 2848 | } |
2826 | } | 2849 | } |
2827 | #endif | 2850 | #endif |
2828 | if (tty->pgrp > 0) | 2851 | if (tty->pgrp) |
2829 | kill_pg(tty->pgrp, SIGWINCH, 1); | 2852 | kill_pgrp(tty->pgrp, SIGWINCH, 1); |
2830 | if ((real_tty->pgrp != tty->pgrp) && (real_tty->pgrp > 0)) | 2853 | if ((real_tty->pgrp != tty->pgrp) && real_tty->pgrp) |
2831 | kill_pg(real_tty->pgrp, SIGWINCH, 1); | 2854 | kill_pgrp(real_tty->pgrp, SIGWINCH, 1); |
2832 | tty->winsize = tmp_ws; | 2855 | tty->winsize = tmp_ws; |
2833 | real_tty->winsize = tmp_ws; | 2856 | real_tty->winsize = tmp_ws; |
2834 | done: | 2857 | done: |
@@ -2913,8 +2936,7 @@ static int fionbio(struct file *file, int __user *p) | |||
2913 | static int tiocsctty(struct tty_struct *tty, int arg) | 2936 | static int tiocsctty(struct tty_struct *tty, int arg) |
2914 | { | 2937 | { |
2915 | int ret = 0; | 2938 | int ret = 0; |
2916 | if (current->signal->leader && | 2939 | if (current->signal->leader && (task_session(current) == tty->session)) |
2917 | (process_session(current) == tty->session)) | ||
2918 | return ret; | 2940 | return ret; |
2919 | 2941 | ||
2920 | mutex_lock(&tty_mutex); | 2942 | mutex_lock(&tty_mutex); |
@@ -2927,7 +2949,7 @@ static int tiocsctty(struct tty_struct *tty, int arg) | |||
2927 | goto unlock; | 2949 | goto unlock; |
2928 | } | 2950 | } |
2929 | 2951 | ||
2930 | if (tty->session > 0) { | 2952 | if (tty->session) { |
2931 | /* | 2953 | /* |
2932 | * This tty is already the controlling | 2954 | * This tty is already the controlling |
2933 | * tty for another session group! | 2955 | * tty for another session group! |
@@ -2970,7 +2992,7 @@ static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t | |||
2970 | */ | 2992 | */ |
2971 | if (tty == real_tty && current->signal->tty != real_tty) | 2993 | if (tty == real_tty && current->signal->tty != real_tty) |
2972 | return -ENOTTY; | 2994 | return -ENOTTY; |
2973 | return put_user(real_tty->pgrp, p); | 2995 | return put_user(pid_nr(real_tty->pgrp), p); |
2974 | } | 2996 | } |
2975 | 2997 | ||
2976 | /** | 2998 | /** |
@@ -2987,7 +3009,8 @@ static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t | |||
2987 | 3009 | ||
2988 | static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) | 3010 | static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) |
2989 | { | 3011 | { |
2990 | pid_t pgrp; | 3012 | struct pid *pgrp; |
3013 | pid_t pgrp_nr; | ||
2991 | int retval = tty_check_change(real_tty); | 3014 | int retval = tty_check_change(real_tty); |
2992 | 3015 | ||
2993 | if (retval == -EIO) | 3016 | if (retval == -EIO) |
@@ -2996,16 +3019,26 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t | |||
2996 | return retval; | 3019 | return retval; |
2997 | if (!current->signal->tty || | 3020 | if (!current->signal->tty || |
2998 | (current->signal->tty != real_tty) || | 3021 | (current->signal->tty != real_tty) || |
2999 | (real_tty->session != process_session(current))) | 3022 | (real_tty->session != task_session(current))) |
3000 | return -ENOTTY; | 3023 | return -ENOTTY; |
3001 | if (get_user(pgrp, p)) | 3024 | if (get_user(pgrp_nr, p)) |
3002 | return -EFAULT; | 3025 | return -EFAULT; |
3003 | if (pgrp < 0) | 3026 | if (pgrp_nr < 0) |
3004 | return -EINVAL; | 3027 | return -EINVAL; |
3005 | if (session_of_pgrp(pgrp) != process_session(current)) | 3028 | rcu_read_lock(); |
3006 | return -EPERM; | 3029 | pgrp = find_pid(pgrp_nr); |
3007 | real_tty->pgrp = pgrp; | 3030 | retval = -ESRCH; |
3008 | return 0; | 3031 | if (!pgrp) |
3032 | goto out_unlock; | ||
3033 | retval = -EPERM; | ||
3034 | if (session_of_pgrp(pgrp) != task_session(current)) | ||
3035 | goto out_unlock; | ||
3036 | retval = 0; | ||
3037 | put_pid(real_tty->pgrp); | ||
3038 | real_tty->pgrp = get_pid(pgrp); | ||
3039 | out_unlock: | ||
3040 | rcu_read_unlock(); | ||
3041 | return retval; | ||
3009 | } | 3042 | } |
3010 | 3043 | ||
3011 | /** | 3044 | /** |
@@ -3028,9 +3061,9 @@ static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t _ | |||
3028 | */ | 3061 | */ |
3029 | if (tty == real_tty && current->signal->tty != real_tty) | 3062 | if (tty == real_tty && current->signal->tty != real_tty) |
3030 | return -ENOTTY; | 3063 | return -ENOTTY; |
3031 | if (real_tty->session <= 0) | 3064 | if (!real_tty->session) |
3032 | return -ENOTTY; | 3065 | return -ENOTTY; |
3033 | return put_user(real_tty->session, p); | 3066 | return put_user(pid_nr(real_tty->session), p); |
3034 | } | 3067 | } |
3035 | 3068 | ||
3036 | /** | 3069 | /** |
@@ -3324,15 +3357,13 @@ int tty_ioctl(struct inode * inode, struct file * file, | |||
3324 | * Nasty bug: do_SAK is being called in interrupt context. This can | 3357 | * Nasty bug: do_SAK is being called in interrupt context. This can |
3325 | * deadlock. We punt it up to process context. AKPM - 16Mar2001 | 3358 | * deadlock. We punt it up to process context. AKPM - 16Mar2001 |
3326 | */ | 3359 | */ |
3327 | static void __do_SAK(struct work_struct *work) | 3360 | void __do_SAK(struct tty_struct *tty) |
3328 | { | 3361 | { |
3329 | struct tty_struct *tty = | ||
3330 | container_of(work, struct tty_struct, SAK_work); | ||
3331 | #ifdef TTY_SOFT_SAK | 3362 | #ifdef TTY_SOFT_SAK |
3332 | tty_hangup(tty); | 3363 | tty_hangup(tty); |
3333 | #else | 3364 | #else |
3334 | struct task_struct *g, *p; | 3365 | struct task_struct *g, *p; |
3335 | int session; | 3366 | struct pid *session; |
3336 | int i; | 3367 | int i; |
3337 | struct file *filp; | 3368 | struct file *filp; |
3338 | struct fdtable *fdt; | 3369 | struct fdtable *fdt; |
@@ -3348,12 +3379,12 @@ static void __do_SAK(struct work_struct *work) | |||
3348 | 3379 | ||
3349 | read_lock(&tasklist_lock); | 3380 | read_lock(&tasklist_lock); |
3350 | /* Kill the entire session */ | 3381 | /* Kill the entire session */ |
3351 | do_each_task_pid(session, PIDTYPE_SID, p) { | 3382 | do_each_pid_task(session, PIDTYPE_SID, p) { |
3352 | printk(KERN_NOTICE "SAK: killed process %d" | 3383 | printk(KERN_NOTICE "SAK: killed process %d" |
3353 | " (%s): process_session(p)==tty->session\n", | 3384 | " (%s): process_session(p)==tty->session\n", |
3354 | p->pid, p->comm); | 3385 | p->pid, p->comm); |
3355 | send_sig(SIGKILL, p, 1); | 3386 | send_sig(SIGKILL, p, 1); |
3356 | } while_each_task_pid(session, PIDTYPE_SID, p); | 3387 | } while_each_pid_task(session, PIDTYPE_SID, p); |
3357 | /* Now kill any processes that happen to have the | 3388 | /* Now kill any processes that happen to have the |
3358 | * tty open. | 3389 | * tty open. |
3359 | */ | 3390 | */ |
@@ -3394,6 +3425,13 @@ static void __do_SAK(struct work_struct *work) | |||
3394 | #endif | 3425 | #endif |
3395 | } | 3426 | } |
3396 | 3427 | ||
3428 | static void do_SAK_work(struct work_struct *work) | ||
3429 | { | ||
3430 | struct tty_struct *tty = | ||
3431 | container_of(work, struct tty_struct, SAK_work); | ||
3432 | __do_SAK(tty); | ||
3433 | } | ||
3434 | |||
3397 | /* | 3435 | /* |
3398 | * The tq handling here is a little racy - tty->SAK_work may already be queued. | 3436 | * The tq handling here is a little racy - tty->SAK_work may already be queued. |
3399 | * Fortunately we don't need to worry, because if ->SAK_work is already queued, | 3437 | * Fortunately we don't need to worry, because if ->SAK_work is already queued, |
@@ -3404,7 +3442,7 @@ void do_SAK(struct tty_struct *tty) | |||
3404 | { | 3442 | { |
3405 | if (!tty) | 3443 | if (!tty) |
3406 | return; | 3444 | return; |
3407 | PREPARE_WORK(&tty->SAK_work, __do_SAK); | 3445 | PREPARE_WORK(&tty->SAK_work, do_SAK_work); |
3408 | schedule_work(&tty->SAK_work); | 3446 | schedule_work(&tty->SAK_work); |
3409 | } | 3447 | } |
3410 | 3448 | ||
@@ -3515,7 +3553,8 @@ static void initialize_tty_struct(struct tty_struct *tty) | |||
3515 | memset(tty, 0, sizeof(struct tty_struct)); | 3553 | memset(tty, 0, sizeof(struct tty_struct)); |
3516 | tty->magic = TTY_MAGIC; | 3554 | tty->magic = TTY_MAGIC; |
3517 | tty_ldisc_assign(tty, tty_ldisc_get(N_TTY)); | 3555 | tty_ldisc_assign(tty, tty_ldisc_get(N_TTY)); |
3518 | tty->pgrp = -1; | 3556 | tty->session = NULL; |
3557 | tty->pgrp = NULL; | ||
3519 | tty->overrun_time = jiffies; | 3558 | tty->overrun_time = jiffies; |
3520 | tty->buf.head = tty->buf.tail = NULL; | 3559 | tty->buf.head = tty->buf.tail = NULL; |
3521 | tty_buffer_init(tty); | 3560 | tty_buffer_init(tty); |
@@ -3786,21 +3825,28 @@ void proc_clear_tty(struct task_struct *p) | |||
3786 | } | 3825 | } |
3787 | EXPORT_SYMBOL(proc_clear_tty); | 3826 | EXPORT_SYMBOL(proc_clear_tty); |
3788 | 3827 | ||
3789 | void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) | 3828 | static struct pid *__proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) |
3790 | { | 3829 | { |
3830 | struct pid *old_pgrp; | ||
3791 | if (tty) { | 3831 | if (tty) { |
3792 | tty->session = process_session(tsk); | 3832 | tty->session = get_pid(task_session(tsk)); |
3793 | tty->pgrp = process_group(tsk); | 3833 | tty->pgrp = get_pid(task_pgrp(tsk)); |
3794 | } | 3834 | } |
3835 | old_pgrp = tsk->signal->tty_old_pgrp; | ||
3795 | tsk->signal->tty = tty; | 3836 | tsk->signal->tty = tty; |
3796 | tsk->signal->tty_old_pgrp = 0; | 3837 | tsk->signal->tty_old_pgrp = NULL; |
3838 | return old_pgrp; | ||
3797 | } | 3839 | } |
3798 | 3840 | ||
3799 | void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) | 3841 | void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) |
3800 | { | 3842 | { |
3843 | struct pid *old_pgrp; | ||
3844 | |||
3801 | spin_lock_irq(&tsk->sighand->siglock); | 3845 | spin_lock_irq(&tsk->sighand->siglock); |
3802 | __proc_set_tty(tsk, tty); | 3846 | old_pgrp = __proc_set_tty(tsk, tty); |
3803 | spin_unlock_irq(&tsk->sighand->siglock); | 3847 | spin_unlock_irq(&tsk->sighand->siglock); |
3848 | |||
3849 | put_pid(old_pgrp); | ||
3804 | } | 3850 | } |
3805 | 3851 | ||
3806 | struct tty_struct *get_current_tty(void) | 3852 | struct tty_struct *get_current_tty(void) |