diff options
Diffstat (limited to 'drivers/char/tty_io.c')
-rw-r--r-- | drivers/char/tty_io.c | 404 |
1 files changed, 192 insertions, 212 deletions
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index b3cfc8bc613c..47a6eacb10bc 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -109,13 +109,15 @@ | |||
109 | #define TTY_PARANOIA_CHECK 1 | 109 | #define TTY_PARANOIA_CHECK 1 |
110 | #define CHECK_TTY_COUNT 1 | 110 | #define CHECK_TTY_COUNT 1 |
111 | 111 | ||
112 | struct termios tty_std_termios = { /* for the benefit of tty drivers */ | 112 | struct ktermios tty_std_termios = { /* for the benefit of tty drivers */ |
113 | .c_iflag = ICRNL | IXON, | 113 | .c_iflag = ICRNL | IXON, |
114 | .c_oflag = OPOST | ONLCR, | 114 | .c_oflag = OPOST | ONLCR, |
115 | .c_cflag = B38400 | CS8 | CREAD | HUPCL, | 115 | .c_cflag = B38400 | CS8 | CREAD | HUPCL, |
116 | .c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK | | 116 | .c_lflag = ISIG | ICANON | ECHO | ECHOE | ECHOK | |
117 | ECHOCTL | ECHOKE | IEXTEN, | 117 | ECHOCTL | ECHOKE | IEXTEN, |
118 | .c_cc = INIT_C_CC | 118 | .c_cc = INIT_C_CC, |
119 | .c_ispeed = 38400, | ||
120 | .c_ospeed = 38400 | ||
119 | }; | 121 | }; |
120 | 122 | ||
121 | EXPORT_SYMBOL(tty_std_termios); | 123 | EXPORT_SYMBOL(tty_std_termios); |
@@ -126,7 +128,7 @@ EXPORT_SYMBOL(tty_std_termios); | |||
126 | 128 | ||
127 | LIST_HEAD(tty_drivers); /* linked list of tty drivers */ | 129 | LIST_HEAD(tty_drivers); /* linked list of tty drivers */ |
128 | 130 | ||
129 | /* Semaphore to protect creating and releasing a tty. This is shared with | 131 | /* Mutex to protect creating and releasing a tty. This is shared with |
130 | vt.c for deeply disgusting hack reasons */ | 132 | vt.c for deeply disgusting hack reasons */ |
131 | DEFINE_MUTEX(tty_mutex); | 133 | DEFINE_MUTEX(tty_mutex); |
132 | EXPORT_SYMBOL(tty_mutex); | 134 | EXPORT_SYMBOL(tty_mutex); |
@@ -250,7 +252,7 @@ static int check_tty_count(struct tty_struct *tty, const char *routine) | |||
250 | "!= #fd's(%d) in %s\n", | 252 | "!= #fd's(%d) in %s\n", |
251 | tty->name, tty->count, count, routine); | 253 | tty->name, tty->count, count, routine); |
252 | return count; | 254 | return count; |
253 | } | 255 | } |
254 | #endif | 256 | #endif |
255 | return 0; | 257 | return 0; |
256 | } | 258 | } |
@@ -259,18 +261,6 @@ static int check_tty_count(struct tty_struct *tty, const char *routine) | |||
259 | * Tty buffer allocation management | 261 | * Tty buffer allocation management |
260 | */ | 262 | */ |
261 | 263 | ||
262 | |||
263 | /** | ||
264 | * tty_buffer_free_all - free buffers used by a tty | ||
265 | * @tty: tty to free from | ||
266 | * | ||
267 | * Remove all the buffers pending on a tty whether queued with data | ||
268 | * or in the free ring. Must be called when the tty is no longer in use | ||
269 | * | ||
270 | * Locking: none | ||
271 | */ | ||
272 | |||
273 | |||
274 | /** | 264 | /** |
275 | * tty_buffer_free_all - free buffers used by a tty | 265 | * tty_buffer_free_all - free buffers used by a tty |
276 | * @tty: tty to free from | 266 | * @tty: tty to free from |
@@ -614,7 +604,7 @@ EXPORT_SYMBOL_GPL(tty_prepare_flip_string_flags); | |||
614 | * they are not on hot paths so a little discipline won't do | 604 | * they are not on hot paths so a little discipline won't do |
615 | * any harm. | 605 | * any harm. |
616 | * | 606 | * |
617 | * Locking: takes termios_sem | 607 | * Locking: takes termios_mutex |
618 | */ | 608 | */ |
619 | 609 | ||
620 | static void tty_set_termios_ldisc(struct tty_struct *tty, int num) | 610 | static void tty_set_termios_ldisc(struct tty_struct *tty, int num) |
@@ -915,7 +905,7 @@ static void tty_ldisc_enable(struct tty_struct *tty) | |||
915 | * context. | 905 | * context. |
916 | * | 906 | * |
917 | * Locking: takes tty_ldisc_lock. | 907 | * Locking: takes tty_ldisc_lock. |
918 | * called functions take termios_sem | 908 | * called functions take termios_mutex |
919 | */ | 909 | */ |
920 | 910 | ||
921 | static int tty_set_ldisc(struct tty_struct *tty, int ldisc) | 911 | static int tty_set_ldisc(struct tty_struct *tty, int ldisc) |
@@ -1251,6 +1241,22 @@ void tty_ldisc_flush(struct tty_struct *tty) | |||
1251 | } | 1241 | } |
1252 | 1242 | ||
1253 | EXPORT_SYMBOL_GPL(tty_ldisc_flush); | 1243 | EXPORT_SYMBOL_GPL(tty_ldisc_flush); |
1244 | |||
1245 | /** | ||
1246 | * tty_reset_termios - reset terminal state | ||
1247 | * @tty: tty to reset | ||
1248 | * | ||
1249 | * Restore a terminal to the driver default state | ||
1250 | */ | ||
1251 | |||
1252 | static void tty_reset_termios(struct tty_struct *tty) | ||
1253 | { | ||
1254 | mutex_lock(&tty->termios_mutex); | ||
1255 | *tty->termios = tty->driver->init_termios; | ||
1256 | tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios); | ||
1257 | tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios); | ||
1258 | mutex_unlock(&tty->termios_mutex); | ||
1259 | } | ||
1254 | 1260 | ||
1255 | /** | 1261 | /** |
1256 | * do_tty_hangup - actual handler for hangup events | 1262 | * do_tty_hangup - actual handler for hangup events |
@@ -1267,12 +1273,12 @@ EXPORT_SYMBOL_GPL(tty_ldisc_flush); | |||
1267 | * | 1273 | * |
1268 | * Locking: | 1274 | * Locking: |
1269 | * BKL | 1275 | * BKL |
1270 | * redirect lock for undoing redirection | 1276 | * redirect lock for undoing redirection |
1271 | * file list lock for manipulating list of ttys | 1277 | * file list lock for manipulating list of ttys |
1272 | * tty_ldisc_lock from called functions | 1278 | * tty_ldisc_lock from called functions |
1273 | * termios_sem resetting termios data | 1279 | * termios_mutex resetting termios data |
1274 | * tasklist_lock to walk task list for hangup event | 1280 | * tasklist_lock to walk task list for hangup event |
1275 | * | 1281 | * ->siglock to protect ->signal/->sighand |
1276 | */ | 1282 | */ |
1277 | static void do_tty_hangup(struct work_struct *work) | 1283 | static void do_tty_hangup(struct work_struct *work) |
1278 | { | 1284 | { |
@@ -1339,11 +1345,7 @@ static void do_tty_hangup(struct work_struct *work) | |||
1339 | * N_TTY. | 1345 | * N_TTY. |
1340 | */ | 1346 | */ |
1341 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) | 1347 | if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) |
1342 | { | 1348 | tty_reset_termios(tty); |
1343 | mutex_lock(&tty->termios_mutex); | ||
1344 | *tty->termios = tty->driver->init_termios; | ||
1345 | mutex_unlock(&tty->termios_mutex); | ||
1346 | } | ||
1347 | 1349 | ||
1348 | /* Defer ldisc switch */ | 1350 | /* Defer ldisc switch */ |
1349 | /* tty_deferred_ldisc_switch(N_TTY); | 1351 | /* tty_deferred_ldisc_switch(N_TTY); |
@@ -1354,14 +1356,18 @@ static void do_tty_hangup(struct work_struct *work) | |||
1354 | read_lock(&tasklist_lock); | 1356 | read_lock(&tasklist_lock); |
1355 | if (tty->session > 0) { | 1357 | if (tty->session > 0) { |
1356 | do_each_task_pid(tty->session, PIDTYPE_SID, p) { | 1358 | do_each_task_pid(tty->session, PIDTYPE_SID, p) { |
1359 | spin_lock_irq(&p->sighand->siglock); | ||
1357 | if (p->signal->tty == tty) | 1360 | if (p->signal->tty == tty) |
1358 | p->signal->tty = NULL; | 1361 | p->signal->tty = NULL; |
1359 | if (!p->signal->leader) | 1362 | if (!p->signal->leader) { |
1363 | spin_unlock_irq(&p->sighand->siglock); | ||
1360 | continue; | 1364 | continue; |
1361 | group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p); | 1365 | } |
1362 | group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p); | 1366 | __group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p); |
1367 | __group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p); | ||
1363 | if (tty->pgrp > 0) | 1368 | if (tty->pgrp > 0) |
1364 | p->signal->tty_old_pgrp = tty->pgrp; | 1369 | p->signal->tty_old_pgrp = tty->pgrp; |
1370 | spin_unlock_irq(&p->sighand->siglock); | ||
1365 | } while_each_task_pid(tty->session, PIDTYPE_SID, p); | 1371 | } while_each_task_pid(tty->session, PIDTYPE_SID, p); |
1366 | } | 1372 | } |
1367 | read_unlock(&tasklist_lock); | 1373 | read_unlock(&tasklist_lock); |
@@ -1453,6 +1459,14 @@ int tty_hung_up_p(struct file * filp) | |||
1453 | 1459 | ||
1454 | EXPORT_SYMBOL(tty_hung_up_p); | 1460 | EXPORT_SYMBOL(tty_hung_up_p); |
1455 | 1461 | ||
1462 | static void session_clear_tty(pid_t session) | ||
1463 | { | ||
1464 | struct task_struct *p; | ||
1465 | do_each_task_pid(session, PIDTYPE_SID, p) { | ||
1466 | proc_clear_tty(p); | ||
1467 | } while_each_task_pid(session, PIDTYPE_SID, p); | ||
1468 | } | ||
1469 | |||
1456 | /** | 1470 | /** |
1457 | * disassociate_ctty - disconnect controlling tty | 1471 | * disassociate_ctty - disconnect controlling tty |
1458 | * @on_exit: true if exiting so need to "hang up" the session | 1472 | * @on_exit: true if exiting so need to "hang up" the session |
@@ -1469,31 +1483,35 @@ EXPORT_SYMBOL(tty_hung_up_p); | |||
1469 | * The argument on_exit is set to 1 if called when a process is | 1483 | * The argument on_exit is set to 1 if called when a process is |
1470 | * exiting; it is 0 if called by the ioctl TIOCNOTTY. | 1484 | * exiting; it is 0 if called by the ioctl TIOCNOTTY. |
1471 | * | 1485 | * |
1472 | * Locking: tty_mutex is taken to protect current->signal->tty | 1486 | * Locking: |
1473 | * BKL is taken for hysterical raisins | 1487 | * BKL is taken for hysterical raisins |
1474 | * Tasklist lock is taken (under tty_mutex) to walk process | 1488 | * tty_mutex is taken to protect tty |
1475 | * lists for the session. | 1489 | * ->siglock is taken to protect ->signal/->sighand |
1490 | * tasklist_lock is taken to walk process list for sessions | ||
1491 | * ->siglock is taken to protect ->signal/->sighand | ||
1476 | */ | 1492 | */ |
1477 | 1493 | ||
1478 | void disassociate_ctty(int on_exit) | 1494 | void disassociate_ctty(int on_exit) |
1479 | { | 1495 | { |
1480 | struct tty_struct *tty; | 1496 | struct tty_struct *tty; |
1481 | struct task_struct *p; | ||
1482 | int tty_pgrp = -1; | 1497 | int tty_pgrp = -1; |
1498 | int session; | ||
1483 | 1499 | ||
1484 | lock_kernel(); | 1500 | lock_kernel(); |
1485 | 1501 | ||
1486 | mutex_lock(&tty_mutex); | 1502 | mutex_lock(&tty_mutex); |
1487 | tty = current->signal->tty; | 1503 | tty = get_current_tty(); |
1488 | if (tty) { | 1504 | if (tty) { |
1489 | tty_pgrp = tty->pgrp; | 1505 | tty_pgrp = tty->pgrp; |
1490 | mutex_unlock(&tty_mutex); | 1506 | mutex_unlock(&tty_mutex); |
1507 | /* XXX: here we race, there is nothing protecting tty */ | ||
1491 | if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) | 1508 | if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) |
1492 | tty_vhangup(tty); | 1509 | tty_vhangup(tty); |
1493 | } else { | 1510 | } else { |
1494 | if (current->signal->tty_old_pgrp) { | 1511 | pid_t old_pgrp = current->signal->tty_old_pgrp; |
1495 | kill_pg(current->signal->tty_old_pgrp, SIGHUP, on_exit); | 1512 | if (old_pgrp) { |
1496 | kill_pg(current->signal->tty_old_pgrp, SIGCONT, on_exit); | 1513 | kill_pg(old_pgrp, SIGHUP, on_exit); |
1514 | kill_pg(old_pgrp, SIGCONT, on_exit); | ||
1497 | } | 1515 | } |
1498 | mutex_unlock(&tty_mutex); | 1516 | mutex_unlock(&tty_mutex); |
1499 | unlock_kernel(); | 1517 | unlock_kernel(); |
@@ -1505,19 +1523,29 @@ void disassociate_ctty(int on_exit) | |||
1505 | kill_pg(tty_pgrp, SIGCONT, on_exit); | 1523 | kill_pg(tty_pgrp, SIGCONT, on_exit); |
1506 | } | 1524 | } |
1507 | 1525 | ||
1508 | /* Must lock changes to tty_old_pgrp */ | 1526 | spin_lock_irq(¤t->sighand->siglock); |
1509 | mutex_lock(&tty_mutex); | ||
1510 | current->signal->tty_old_pgrp = 0; | 1527 | current->signal->tty_old_pgrp = 0; |
1511 | tty->session = 0; | 1528 | session = process_session(current); |
1512 | tty->pgrp = -1; | 1529 | spin_unlock_irq(¤t->sighand->siglock); |
1530 | |||
1531 | mutex_lock(&tty_mutex); | ||
1532 | /* It is possible that do_tty_hangup has free'd this tty */ | ||
1533 | tty = get_current_tty(); | ||
1534 | if (tty) { | ||
1535 | tty->session = 0; | ||
1536 | tty->pgrp = 0; | ||
1537 | } else { | ||
1538 | #ifdef TTY_DEBUG_HANGUP | ||
1539 | printk(KERN_DEBUG "error attempted to write to tty [0x%p]" | ||
1540 | " = NULL", tty); | ||
1541 | #endif | ||
1542 | } | ||
1543 | mutex_unlock(&tty_mutex); | ||
1513 | 1544 | ||
1514 | /* Now clear signal->tty under the lock */ | 1545 | /* Now clear signal->tty under the lock */ |
1515 | read_lock(&tasklist_lock); | 1546 | read_lock(&tasklist_lock); |
1516 | do_each_task_pid(current->signal->session, PIDTYPE_SID, p) { | 1547 | session_clear_tty(session); |
1517 | p->signal->tty = NULL; | ||
1518 | } while_each_task_pid(current->signal->session, PIDTYPE_SID, p); | ||
1519 | read_unlock(&tasklist_lock); | 1548 | read_unlock(&tasklist_lock); |
1520 | mutex_unlock(&tty_mutex); | ||
1521 | unlock_kernel(); | 1549 | unlock_kernel(); |
1522 | } | 1550 | } |
1523 | 1551 | ||
@@ -1615,7 +1643,7 @@ static ssize_t tty_read(struct file * file, char __user * buf, size_t count, | |||
1615 | struct tty_ldisc *ld; | 1643 | struct tty_ldisc *ld; |
1616 | 1644 | ||
1617 | tty = (struct tty_struct *)file->private_data; | 1645 | tty = (struct tty_struct *)file->private_data; |
1618 | inode = file->f_dentry->d_inode; | 1646 | inode = file->f_path.dentry->d_inode; |
1619 | if (tty_paranoia_check(tty, inode, "tty_read")) | 1647 | if (tty_paranoia_check(tty, inode, "tty_read")) |
1620 | return -EIO; | 1648 | return -EIO; |
1621 | if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags))) | 1649 | if (!tty || (test_bit(TTY_IO_ERROR, &tty->flags))) |
@@ -1718,7 +1746,7 @@ static inline ssize_t do_tty_write( | |||
1718 | cond_resched(); | 1746 | cond_resched(); |
1719 | } | 1747 | } |
1720 | if (written) { | 1748 | if (written) { |
1721 | struct inode *inode = file->f_dentry->d_inode; | 1749 | struct inode *inode = file->f_path.dentry->d_inode; |
1722 | inode->i_mtime = current_fs_time(inode->i_sb); | 1750 | inode->i_mtime = current_fs_time(inode->i_sb); |
1723 | ret = written; | 1751 | ret = written; |
1724 | } | 1752 | } |
@@ -1749,7 +1777,7 @@ static ssize_t tty_write(struct file * file, const char __user * buf, size_t cou | |||
1749 | loff_t *ppos) | 1777 | loff_t *ppos) |
1750 | { | 1778 | { |
1751 | struct tty_struct * tty; | 1779 | struct tty_struct * tty; |
1752 | struct inode *inode = file->f_dentry->d_inode; | 1780 | struct inode *inode = file->f_path.dentry->d_inode; |
1753 | ssize_t ret; | 1781 | ssize_t ret; |
1754 | struct tty_ldisc *ld; | 1782 | struct tty_ldisc *ld; |
1755 | 1783 | ||
@@ -1856,8 +1884,8 @@ static int init_dev(struct tty_driver *driver, int idx, | |||
1856 | struct tty_struct **ret_tty) | 1884 | struct tty_struct **ret_tty) |
1857 | { | 1885 | { |
1858 | struct tty_struct *tty, *o_tty; | 1886 | struct tty_struct *tty, *o_tty; |
1859 | struct termios *tp, **tp_loc, *o_tp, **o_tp_loc; | 1887 | struct ktermios *tp, **tp_loc, *o_tp, **o_tp_loc; |
1860 | struct termios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc; | 1888 | struct ktermios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc; |
1861 | int retval = 0; | 1889 | int retval = 0; |
1862 | 1890 | ||
1863 | /* check whether we're reopening an existing tty */ | 1891 | /* check whether we're reopening an existing tty */ |
@@ -1904,7 +1932,7 @@ static int init_dev(struct tty_driver *driver, int idx, | |||
1904 | } | 1932 | } |
1905 | 1933 | ||
1906 | if (!*tp_loc) { | 1934 | if (!*tp_loc) { |
1907 | tp = (struct termios *) kmalloc(sizeof(struct termios), | 1935 | tp = (struct ktermios *) kmalloc(sizeof(struct ktermios), |
1908 | GFP_KERNEL); | 1936 | GFP_KERNEL); |
1909 | if (!tp) | 1937 | if (!tp) |
1910 | goto free_mem_out; | 1938 | goto free_mem_out; |
@@ -1912,11 +1940,11 @@ static int init_dev(struct tty_driver *driver, int idx, | |||
1912 | } | 1940 | } |
1913 | 1941 | ||
1914 | if (!*ltp_loc) { | 1942 | if (!*ltp_loc) { |
1915 | ltp = (struct termios *) kmalloc(sizeof(struct termios), | 1943 | ltp = (struct ktermios *) kmalloc(sizeof(struct ktermios), |
1916 | GFP_KERNEL); | 1944 | GFP_KERNEL); |
1917 | if (!ltp) | 1945 | if (!ltp) |
1918 | goto free_mem_out; | 1946 | goto free_mem_out; |
1919 | memset(ltp, 0, sizeof(struct termios)); | 1947 | memset(ltp, 0, sizeof(struct ktermios)); |
1920 | } | 1948 | } |
1921 | 1949 | ||
1922 | if (driver->type == TTY_DRIVER_TYPE_PTY) { | 1950 | if (driver->type == TTY_DRIVER_TYPE_PTY) { |
@@ -1937,19 +1965,19 @@ static int init_dev(struct tty_driver *driver, int idx, | |||
1937 | } | 1965 | } |
1938 | 1966 | ||
1939 | if (!*o_tp_loc) { | 1967 | if (!*o_tp_loc) { |
1940 | o_tp = (struct termios *) | 1968 | o_tp = (struct ktermios *) |
1941 | kmalloc(sizeof(struct termios), GFP_KERNEL); | 1969 | kmalloc(sizeof(struct ktermios), GFP_KERNEL); |
1942 | if (!o_tp) | 1970 | if (!o_tp) |
1943 | goto free_mem_out; | 1971 | goto free_mem_out; |
1944 | *o_tp = driver->other->init_termios; | 1972 | *o_tp = driver->other->init_termios; |
1945 | } | 1973 | } |
1946 | 1974 | ||
1947 | if (!*o_ltp_loc) { | 1975 | if (!*o_ltp_loc) { |
1948 | o_ltp = (struct termios *) | 1976 | o_ltp = (struct ktermios *) |
1949 | kmalloc(sizeof(struct termios), GFP_KERNEL); | 1977 | kmalloc(sizeof(struct ktermios), GFP_KERNEL); |
1950 | if (!o_ltp) | 1978 | if (!o_ltp) |
1951 | goto free_mem_out; | 1979 | goto free_mem_out; |
1952 | memset(o_ltp, 0, sizeof(struct termios)); | 1980 | memset(o_ltp, 0, sizeof(struct ktermios)); |
1953 | } | 1981 | } |
1954 | 1982 | ||
1955 | /* | 1983 | /* |
@@ -1988,6 +2016,9 @@ static int init_dev(struct tty_driver *driver, int idx, | |||
1988 | *ltp_loc = ltp; | 2016 | *ltp_loc = ltp; |
1989 | tty->termios = *tp_loc; | 2017 | tty->termios = *tp_loc; |
1990 | tty->termios_locked = *ltp_loc; | 2018 | tty->termios_locked = *ltp_loc; |
2019 | /* Compatibility until drivers always set this */ | ||
2020 | tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios); | ||
2021 | tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios); | ||
1991 | driver->refcount++; | 2022 | driver->refcount++; |
1992 | tty->count++; | 2023 | tty->count++; |
1993 | 2024 | ||
@@ -2090,7 +2121,7 @@ release_mem_out: | |||
2090 | static void release_mem(struct tty_struct *tty, int idx) | 2121 | static void release_mem(struct tty_struct *tty, int idx) |
2091 | { | 2122 | { |
2092 | struct tty_struct *o_tty; | 2123 | struct tty_struct *o_tty; |
2093 | struct termios *tp; | 2124 | struct ktermios *tp; |
2094 | int devpts = tty->driver->flags & TTY_DRIVER_DEVPTS_MEM; | 2125 | int devpts = tty->driver->flags & TTY_DRIVER_DEVPTS_MEM; |
2095 | 2126 | ||
2096 | if ((o_tty = tty->link) != NULL) { | 2127 | if ((o_tty = tty->link) != NULL) { |
@@ -2156,7 +2187,7 @@ static void release_dev(struct file * filp) | |||
2156 | unsigned long flags; | 2187 | unsigned long flags; |
2157 | 2188 | ||
2158 | tty = (struct tty_struct *)filp->private_data; | 2189 | tty = (struct tty_struct *)filp->private_data; |
2159 | if (tty_paranoia_check(tty, filp->f_dentry->d_inode, "release_dev")) | 2190 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "release_dev")) |
2160 | return; | 2191 | return; |
2161 | 2192 | ||
2162 | check_tty_count(tty, "release_dev"); | 2193 | check_tty_count(tty, "release_dev"); |
@@ -2337,16 +2368,10 @@ static void release_dev(struct file * filp) | |||
2337 | * tty. | 2368 | * tty. |
2338 | */ | 2369 | */ |
2339 | if (tty_closing || o_tty_closing) { | 2370 | if (tty_closing || o_tty_closing) { |
2340 | struct task_struct *p; | ||
2341 | |||
2342 | read_lock(&tasklist_lock); | 2371 | read_lock(&tasklist_lock); |
2343 | do_each_task_pid(tty->session, PIDTYPE_SID, p) { | 2372 | session_clear_tty(tty->session); |
2344 | p->signal->tty = NULL; | ||
2345 | } while_each_task_pid(tty->session, PIDTYPE_SID, p); | ||
2346 | if (o_tty) | 2373 | if (o_tty) |
2347 | do_each_task_pid(o_tty->session, PIDTYPE_SID, p) { | 2374 | session_clear_tty(o_tty->session); |
2348 | p->signal->tty = NULL; | ||
2349 | } while_each_task_pid(o_tty->session, PIDTYPE_SID, p); | ||
2350 | read_unlock(&tasklist_lock); | 2375 | read_unlock(&tasklist_lock); |
2351 | } | 2376 | } |
2352 | 2377 | ||
@@ -2443,9 +2468,9 @@ static void release_dev(struct file * filp) | |||
2443 | * The termios state of a pty is reset on first open so that | 2468 | * The termios state of a pty is reset on first open so that |
2444 | * settings don't persist across reuse. | 2469 | * settings don't persist across reuse. |
2445 | * | 2470 | * |
2446 | * Locking: tty_mutex protects current->signal->tty, get_tty_driver and | 2471 | * Locking: tty_mutex protects tty, get_tty_driver and init_dev work. |
2447 | * init_dev work. tty->count should protect the rest. | 2472 | * tty->count should protect the rest. |
2448 | * task_lock is held to update task details for sessions | 2473 | * ->siglock protects ->signal/->sighand |
2449 | */ | 2474 | */ |
2450 | 2475 | ||
2451 | static int tty_open(struct inode * inode, struct file * filp) | 2476 | static int tty_open(struct inode * inode, struct file * filp) |
@@ -2467,12 +2492,13 @@ retry_open: | |||
2467 | mutex_lock(&tty_mutex); | 2492 | mutex_lock(&tty_mutex); |
2468 | 2493 | ||
2469 | if (device == MKDEV(TTYAUX_MAJOR,0)) { | 2494 | if (device == MKDEV(TTYAUX_MAJOR,0)) { |
2470 | if (!current->signal->tty) { | 2495 | tty = get_current_tty(); |
2496 | if (!tty) { | ||
2471 | mutex_unlock(&tty_mutex); | 2497 | mutex_unlock(&tty_mutex); |
2472 | return -ENXIO; | 2498 | return -ENXIO; |
2473 | } | 2499 | } |
2474 | driver = current->signal->tty->driver; | 2500 | driver = tty->driver; |
2475 | index = current->signal->tty->index; | 2501 | index = tty->index; |
2476 | filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ | 2502 | filp->f_flags |= O_NONBLOCK; /* Don't let /dev/tty block */ |
2477 | /* noctty = 1; */ | 2503 | /* noctty = 1; */ |
2478 | goto got_driver; | 2504 | goto got_driver; |
@@ -2547,17 +2573,16 @@ got_driver: | |||
2547 | filp->f_op = &tty_fops; | 2573 | filp->f_op = &tty_fops; |
2548 | goto retry_open; | 2574 | goto retry_open; |
2549 | } | 2575 | } |
2576 | |||
2577 | mutex_lock(&tty_mutex); | ||
2578 | spin_lock_irq(¤t->sighand->siglock); | ||
2550 | if (!noctty && | 2579 | if (!noctty && |
2551 | current->signal->leader && | 2580 | current->signal->leader && |
2552 | !current->signal->tty && | 2581 | !current->signal->tty && |
2553 | tty->session == 0) { | 2582 | tty->session == 0) |
2554 | task_lock(current); | 2583 | __proc_set_tty(current, tty); |
2555 | current->signal->tty = tty; | 2584 | spin_unlock_irq(¤t->sighand->siglock); |
2556 | task_unlock(current); | 2585 | mutex_unlock(&tty_mutex); |
2557 | current->signal->tty_old_pgrp = 0; | ||
2558 | tty->session = current->signal->session; | ||
2559 | tty->pgrp = process_group(current); | ||
2560 | } | ||
2561 | return 0; | 2586 | return 0; |
2562 | } | 2587 | } |
2563 | 2588 | ||
@@ -2672,7 +2697,7 @@ static unsigned int tty_poll(struct file * filp, poll_table * wait) | |||
2672 | int ret = 0; | 2697 | int ret = 0; |
2673 | 2698 | ||
2674 | tty = (struct tty_struct *)filp->private_data; | 2699 | tty = (struct tty_struct *)filp->private_data; |
2675 | if (tty_paranoia_check(tty, filp->f_dentry->d_inode, "tty_poll")) | 2700 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_poll")) |
2676 | return 0; | 2701 | return 0; |
2677 | 2702 | ||
2678 | ld = tty_ldisc_ref_wait(tty); | 2703 | ld = tty_ldisc_ref_wait(tty); |
@@ -2688,7 +2713,7 @@ static int tty_fasync(int fd, struct file * filp, int on) | |||
2688 | int retval; | 2713 | int retval; |
2689 | 2714 | ||
2690 | tty = (struct tty_struct *)filp->private_data; | 2715 | tty = (struct tty_struct *)filp->private_data; |
2691 | if (tty_paranoia_check(tty, filp->f_dentry->d_inode, "tty_fasync")) | 2716 | if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync")) |
2692 | return 0; | 2717 | return 0; |
2693 | 2718 | ||
2694 | retval = fasync_helper(fd, filp, on, &tty->fasync); | 2719 | retval = fasync_helper(fd, filp, on, &tty->fasync); |
@@ -2747,7 +2772,7 @@ static int tiocsti(struct tty_struct *tty, char __user *p) | |||
2747 | * | 2772 | * |
2748 | * Copies the kernel idea of the window size into the user buffer. | 2773 | * Copies the kernel idea of the window size into the user buffer. |
2749 | * | 2774 | * |
2750 | * Locking: tty->termios_sem is taken to ensure the winsize data | 2775 | * Locking: tty->termios_mutex is taken to ensure the winsize data |
2751 | * is consistent. | 2776 | * is consistent. |
2752 | */ | 2777 | */ |
2753 | 2778 | ||
@@ -2774,8 +2799,8 @@ static int tiocgwinsz(struct tty_struct *tty, struct winsize __user * arg) | |||
2774 | * Locking: | 2799 | * Locking: |
2775 | * Called function use the console_sem is used to ensure we do | 2800 | * Called function use the console_sem is used to ensure we do |
2776 | * not try and resize the console twice at once. | 2801 | * not try and resize the console twice at once. |
2777 | * The tty->termios_sem is used to ensure we don't double | 2802 | * The tty->termios_mutex is used to ensure we don't double |
2778 | * resize and get confused. Lock order - tty->termios.sem before | 2803 | * resize and get confused. Lock order - tty->termios_mutex before |
2779 | * console sem | 2804 | * console sem |
2780 | */ | 2805 | */ |
2781 | 2806 | ||
@@ -2880,25 +2905,28 @@ static int fionbio(struct file *file, int __user *p) | |||
2880 | * leader to set this tty as the controlling tty for the session. | 2905 | * leader to set this tty as the controlling tty for the session. |
2881 | * | 2906 | * |
2882 | * Locking: | 2907 | * Locking: |
2883 | * Takes tasklist lock internally to walk sessions | ||
2884 | * Takes task_lock() when updating signal->tty | ||
2885 | * Takes tty_mutex() to protect tty instance | 2908 | * Takes tty_mutex() to protect tty instance |
2886 | * | 2909 | * Takes tasklist_lock internally to walk sessions |
2910 | * Takes ->siglock() when updating signal->tty | ||
2887 | */ | 2911 | */ |
2888 | 2912 | ||
2889 | static int tiocsctty(struct tty_struct *tty, int arg) | 2913 | static int tiocsctty(struct tty_struct *tty, int arg) |
2890 | { | 2914 | { |
2891 | struct task_struct *p; | 2915 | int ret = 0; |
2892 | |||
2893 | if (current->signal->leader && | 2916 | if (current->signal->leader && |
2894 | (current->signal->session == tty->session)) | 2917 | (process_session(current) == tty->session)) |
2895 | return 0; | 2918 | return ret; |
2919 | |||
2920 | mutex_lock(&tty_mutex); | ||
2896 | /* | 2921 | /* |
2897 | * The process must be a session leader and | 2922 | * The process must be a session leader and |
2898 | * not have a controlling tty already. | 2923 | * not have a controlling tty already. |
2899 | */ | 2924 | */ |
2900 | if (!current->signal->leader || current->signal->tty) | 2925 | if (!current->signal->leader || current->signal->tty) { |
2901 | return -EPERM; | 2926 | ret = -EPERM; |
2927 | goto unlock; | ||
2928 | } | ||
2929 | |||
2902 | if (tty->session > 0) { | 2930 | if (tty->session > 0) { |
2903 | /* | 2931 | /* |
2904 | * This tty is already the controlling | 2932 | * This tty is already the controlling |
@@ -2908,24 +2936,18 @@ static int tiocsctty(struct tty_struct *tty, int arg) | |||
2908 | /* | 2936 | /* |
2909 | * Steal it away | 2937 | * Steal it away |
2910 | */ | 2938 | */ |
2911 | |||
2912 | read_lock(&tasklist_lock); | 2939 | read_lock(&tasklist_lock); |
2913 | do_each_task_pid(tty->session, PIDTYPE_SID, p) { | 2940 | session_clear_tty(tty->session); |
2914 | p->signal->tty = NULL; | ||
2915 | } while_each_task_pid(tty->session, PIDTYPE_SID, p); | ||
2916 | read_unlock(&tasklist_lock); | 2941 | read_unlock(&tasklist_lock); |
2917 | } else | 2942 | } else { |
2918 | return -EPERM; | 2943 | ret = -EPERM; |
2944 | goto unlock; | ||
2945 | } | ||
2919 | } | 2946 | } |
2920 | mutex_lock(&tty_mutex); | 2947 | proc_set_tty(current, tty); |
2921 | task_lock(current); | 2948 | unlock: |
2922 | current->signal->tty = tty; | ||
2923 | task_unlock(current); | ||
2924 | mutex_unlock(&tty_mutex); | 2949 | mutex_unlock(&tty_mutex); |
2925 | current->signal->tty_old_pgrp = 0; | 2950 | return ret; |
2926 | tty->session = current->signal->session; | ||
2927 | tty->pgrp = process_group(current); | ||
2928 | return 0; | ||
2929 | } | 2951 | } |
2930 | 2952 | ||
2931 | /** | 2953 | /** |
@@ -2937,7 +2959,7 @@ static int tiocsctty(struct tty_struct *tty, int arg) | |||
2937 | * Obtain the process group of the tty. If there is no process group | 2959 | * Obtain the process group of the tty. If there is no process group |
2938 | * return an error. | 2960 | * return an error. |
2939 | * | 2961 | * |
2940 | * Locking: none. Reference to ->signal->tty is safe. | 2962 | * Locking: none. Reference to current->signal->tty is safe. |
2941 | */ | 2963 | */ |
2942 | 2964 | ||
2943 | static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) | 2965 | static int tiocgpgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) |
@@ -2974,13 +2996,13 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t | |||
2974 | return retval; | 2996 | return retval; |
2975 | if (!current->signal->tty || | 2997 | if (!current->signal->tty || |
2976 | (current->signal->tty != real_tty) || | 2998 | (current->signal->tty != real_tty) || |
2977 | (real_tty->session != current->signal->session)) | 2999 | (real_tty->session != process_session(current))) |
2978 | return -ENOTTY; | 3000 | return -ENOTTY; |
2979 | if (get_user(pgrp, p)) | 3001 | if (get_user(pgrp, p)) |
2980 | return -EFAULT; | 3002 | return -EFAULT; |
2981 | if (pgrp < 0) | 3003 | if (pgrp < 0) |
2982 | return -EINVAL; | 3004 | return -EINVAL; |
2983 | if (session_of_pgrp(pgrp) != current->signal->session) | 3005 | if (session_of_pgrp(pgrp) != process_session(current)) |
2984 | return -EPERM; | 3006 | return -EPERM; |
2985 | real_tty->pgrp = pgrp; | 3007 | real_tty->pgrp = pgrp; |
2986 | return 0; | 3008 | return 0; |
@@ -2995,7 +3017,7 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t | |||
2995 | * Obtain the session id of the tty. If there is no session | 3017 | * Obtain the session id of the tty. If there is no session |
2996 | * return an error. | 3018 | * return an error. |
2997 | * | 3019 | * |
2998 | * Locking: none. Reference to ->signal->tty is safe. | 3020 | * Locking: none. Reference to current->signal->tty is safe. |
2999 | */ | 3021 | */ |
3000 | 3022 | ||
3001 | static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) | 3023 | static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) |
@@ -3214,14 +3236,11 @@ int tty_ioctl(struct inode * inode, struct file * file, | |||
3214 | clear_bit(TTY_EXCLUSIVE, &tty->flags); | 3236 | clear_bit(TTY_EXCLUSIVE, &tty->flags); |
3215 | return 0; | 3237 | return 0; |
3216 | case TIOCNOTTY: | 3238 | case TIOCNOTTY: |
3217 | /* FIXME: taks lock or tty_mutex ? */ | ||
3218 | if (current->signal->tty != tty) | 3239 | if (current->signal->tty != tty) |
3219 | return -ENOTTY; | 3240 | return -ENOTTY; |
3220 | if (current->signal->leader) | 3241 | if (current->signal->leader) |
3221 | disassociate_ctty(0); | 3242 | disassociate_ctty(0); |
3222 | task_lock(current); | 3243 | proc_clear_tty(current); |
3223 | current->signal->tty = NULL; | ||
3224 | task_unlock(current); | ||
3225 | return 0; | 3244 | return 0; |
3226 | case TIOCSCTTY: | 3245 | case TIOCSCTTY: |
3227 | return tiocsctty(tty, arg); | 3246 | return tiocsctty(tty, arg); |
@@ -3316,18 +3335,13 @@ static void __do_SAK(struct work_struct *work) | |||
3316 | int session; | 3335 | int session; |
3317 | int i; | 3336 | int i; |
3318 | struct file *filp; | 3337 | struct file *filp; |
3319 | struct tty_ldisc *disc; | ||
3320 | struct fdtable *fdt; | 3338 | struct fdtable *fdt; |
3321 | 3339 | ||
3322 | if (!tty) | 3340 | if (!tty) |
3323 | return; | 3341 | return; |
3324 | session = tty->session; | 3342 | session = tty->session; |
3325 | 3343 | ||
3326 | /* We don't want an ldisc switch during this */ | 3344 | tty_ldisc_flush(tty); |
3327 | disc = tty_ldisc_ref(tty); | ||
3328 | if (disc && disc->flush_buffer) | ||
3329 | disc->flush_buffer(tty); | ||
3330 | tty_ldisc_deref(disc); | ||
3331 | 3345 | ||
3332 | if (tty->driver->flush_buffer) | 3346 | if (tty->driver->flush_buffer) |
3333 | tty->driver->flush_buffer(tty); | 3347 | tty->driver->flush_buffer(tty); |
@@ -3336,7 +3350,7 @@ static void __do_SAK(struct work_struct *work) | |||
3336 | /* Kill the entire session */ | 3350 | /* Kill the entire session */ |
3337 | do_each_task_pid(session, PIDTYPE_SID, p) { | 3351 | do_each_task_pid(session, PIDTYPE_SID, p) { |
3338 | printk(KERN_NOTICE "SAK: killed process %d" | 3352 | printk(KERN_NOTICE "SAK: killed process %d" |
3339 | " (%s): p->signal->session==tty->session\n", | 3353 | " (%s): process_session(p)==tty->session\n", |
3340 | p->pid, p->comm); | 3354 | p->pid, p->comm); |
3341 | send_sig(SIGKILL, p, 1); | 3355 | send_sig(SIGKILL, p, 1); |
3342 | } while_each_task_pid(session, PIDTYPE_SID, p); | 3356 | } while_each_task_pid(session, PIDTYPE_SID, p); |
@@ -3346,7 +3360,7 @@ static void __do_SAK(struct work_struct *work) | |||
3346 | do_each_thread(g, p) { | 3360 | do_each_thread(g, p) { |
3347 | if (p->signal->tty == tty) { | 3361 | if (p->signal->tty == tty) { |
3348 | printk(KERN_NOTICE "SAK: killed process %d" | 3362 | printk(KERN_NOTICE "SAK: killed process %d" |
3349 | " (%s): p->signal->session==tty->session\n", | 3363 | " (%s): process_session(p)==tty->session\n", |
3350 | p->pid, p->comm); | 3364 | p->pid, p->comm); |
3351 | send_sig(SIGKILL, p, 1); | 3365 | send_sig(SIGKILL, p, 1); |
3352 | continue; | 3366 | continue; |
@@ -3456,84 +3470,6 @@ static void flush_to_ldisc(struct work_struct *work) | |||
3456 | tty_ldisc_deref(disc); | 3470 | tty_ldisc_deref(disc); |
3457 | } | 3471 | } |
3458 | 3472 | ||
3459 | /* | ||
3460 | * Routine which returns the baud rate of the tty | ||
3461 | * | ||
3462 | * Note that the baud_table needs to be kept in sync with the | ||
3463 | * include/asm/termbits.h file. | ||
3464 | */ | ||
3465 | static int baud_table[] = { | ||
3466 | 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, | ||
3467 | 9600, 19200, 38400, 57600, 115200, 230400, 460800, | ||
3468 | #ifdef __sparc__ | ||
3469 | 76800, 153600, 307200, 614400, 921600 | ||
3470 | #else | ||
3471 | 500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000, | ||
3472 | 2500000, 3000000, 3500000, 4000000 | ||
3473 | #endif | ||
3474 | }; | ||
3475 | |||
3476 | static int n_baud_table = ARRAY_SIZE(baud_table); | ||
3477 | |||
3478 | /** | ||
3479 | * tty_termios_baud_rate | ||
3480 | * @termios: termios structure | ||
3481 | * | ||
3482 | * Convert termios baud rate data into a speed. This should be called | ||
3483 | * with the termios lock held if this termios is a terminal termios | ||
3484 | * structure. May change the termios data. | ||
3485 | * | ||
3486 | * Locking: none | ||
3487 | */ | ||
3488 | |||
3489 | int tty_termios_baud_rate(struct termios *termios) | ||
3490 | { | ||
3491 | unsigned int cbaud; | ||
3492 | |||
3493 | cbaud = termios->c_cflag & CBAUD; | ||
3494 | |||
3495 | if (cbaud & CBAUDEX) { | ||
3496 | cbaud &= ~CBAUDEX; | ||
3497 | |||
3498 | if (cbaud < 1 || cbaud + 15 > n_baud_table) | ||
3499 | termios->c_cflag &= ~CBAUDEX; | ||
3500 | else | ||
3501 | cbaud += 15; | ||
3502 | } | ||
3503 | return baud_table[cbaud]; | ||
3504 | } | ||
3505 | |||
3506 | EXPORT_SYMBOL(tty_termios_baud_rate); | ||
3507 | |||
3508 | /** | ||
3509 | * tty_get_baud_rate - get tty bit rates | ||
3510 | * @tty: tty to query | ||
3511 | * | ||
3512 | * Returns the baud rate as an integer for this terminal. The | ||
3513 | * termios lock must be held by the caller and the terminal bit | ||
3514 | * flags may be updated. | ||
3515 | * | ||
3516 | * Locking: none | ||
3517 | */ | ||
3518 | |||
3519 | int tty_get_baud_rate(struct tty_struct *tty) | ||
3520 | { | ||
3521 | int baud = tty_termios_baud_rate(tty->termios); | ||
3522 | |||
3523 | if (baud == 38400 && tty->alt_speed) { | ||
3524 | if (!tty->warned) { | ||
3525 | printk(KERN_WARNING "Use of setserial/setrocket to " | ||
3526 | "set SPD_* flags is deprecated\n"); | ||
3527 | tty->warned = 1; | ||
3528 | } | ||
3529 | baud = tty->alt_speed; | ||
3530 | } | ||
3531 | |||
3532 | return baud; | ||
3533 | } | ||
3534 | |||
3535 | EXPORT_SYMBOL(tty_get_baud_rate); | ||
3536 | |||
3537 | /** | 3473 | /** |
3538 | * tty_flip_buffer_push - terminal | 3474 | * tty_flip_buffer_push - terminal |
3539 | * @tty: tty to push | 3475 | * @tty: tty to push |
@@ -3756,8 +3692,8 @@ int tty_register_driver(struct tty_driver *driver) | |||
3756 | 3692 | ||
3757 | if (p) { | 3693 | if (p) { |
3758 | driver->ttys = (struct tty_struct **)p; | 3694 | driver->ttys = (struct tty_struct **)p; |
3759 | driver->termios = (struct termios **)(p + driver->num); | 3695 | driver->termios = (struct ktermios **)(p + driver->num); |
3760 | driver->termios_locked = (struct termios **)(p + driver->num * 2); | 3696 | driver->termios_locked = (struct ktermios **)(p + driver->num * 2); |
3761 | } else { | 3697 | } else { |
3762 | driver->ttys = NULL; | 3698 | driver->ttys = NULL; |
3763 | driver->termios = NULL; | 3699 | driver->termios = NULL; |
@@ -3796,7 +3732,7 @@ EXPORT_SYMBOL(tty_register_driver); | |||
3796 | int tty_unregister_driver(struct tty_driver *driver) | 3732 | int tty_unregister_driver(struct tty_driver *driver) |
3797 | { | 3733 | { |
3798 | int i; | 3734 | int i; |
3799 | struct termios *tp; | 3735 | struct ktermios *tp; |
3800 | void *p; | 3736 | void *p; |
3801 | 3737 | ||
3802 | if (driver->refcount) | 3738 | if (driver->refcount) |
@@ -3834,9 +3770,53 @@ int tty_unregister_driver(struct tty_driver *driver) | |||
3834 | cdev_del(&driver->cdev); | 3770 | cdev_del(&driver->cdev); |
3835 | return 0; | 3771 | return 0; |
3836 | } | 3772 | } |
3837 | |||
3838 | EXPORT_SYMBOL(tty_unregister_driver); | 3773 | EXPORT_SYMBOL(tty_unregister_driver); |
3839 | 3774 | ||
3775 | dev_t tty_devnum(struct tty_struct *tty) | ||
3776 | { | ||
3777 | return MKDEV(tty->driver->major, tty->driver->minor_start) + tty->index; | ||
3778 | } | ||
3779 | EXPORT_SYMBOL(tty_devnum); | ||
3780 | |||
3781 | void proc_clear_tty(struct task_struct *p) | ||
3782 | { | ||
3783 | spin_lock_irq(&p->sighand->siglock); | ||
3784 | p->signal->tty = NULL; | ||
3785 | spin_unlock_irq(&p->sighand->siglock); | ||
3786 | } | ||
3787 | EXPORT_SYMBOL(proc_clear_tty); | ||
3788 | |||
3789 | void __proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) | ||
3790 | { | ||
3791 | if (tty) { | ||
3792 | tty->session = process_session(tsk); | ||
3793 | tty->pgrp = process_group(tsk); | ||
3794 | } | ||
3795 | tsk->signal->tty = tty; | ||
3796 | tsk->signal->tty_old_pgrp = 0; | ||
3797 | } | ||
3798 | |||
3799 | void proc_set_tty(struct task_struct *tsk, struct tty_struct *tty) | ||
3800 | { | ||
3801 | spin_lock_irq(&tsk->sighand->siglock); | ||
3802 | __proc_set_tty(tsk, tty); | ||
3803 | spin_unlock_irq(&tsk->sighand->siglock); | ||
3804 | } | ||
3805 | |||
3806 | struct tty_struct *get_current_tty(void) | ||
3807 | { | ||
3808 | struct tty_struct *tty; | ||
3809 | WARN_ON_ONCE(!mutex_is_locked(&tty_mutex)); | ||
3810 | tty = current->signal->tty; | ||
3811 | /* | ||
3812 | * session->tty can be changed/cleared from under us, make sure we | ||
3813 | * issue the load. The obtained pointer, when not NULL, is valid as | ||
3814 | * long as we hold tty_mutex. | ||
3815 | */ | ||
3816 | barrier(); | ||
3817 | return tty; | ||
3818 | } | ||
3819 | EXPORT_SYMBOL_GPL(get_current_tty); | ||
3840 | 3820 | ||
3841 | /* | 3821 | /* |
3842 | * Initialize the console device. This is called *early*, so | 3822 | * Initialize the console device. This is called *early*, so |