X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fchar%2Ftty_io.c;h=6ba0b9a1e12df7802d75a7f51d1b9eeea527b11f;hb=987b0145d94eecf292d8b301228356f44611ab7c;hp=12c15826afeeaf381bcfab5b2efead1ccd27de95;hpb=f7ed79d23a47594e7834d66a8f14449796d4f3e6;p=linux-2.6.git diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 12c15826a..6ba0b9a1e 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -131,9 +131,7 @@ LIST_HEAD(tty_drivers); /* linked list of tty drivers */ /* Semaphore to protect creating and releasing a tty. This is shared with vt.c for deeply disgusting hack reasons */ -DEFINE_MUTEX(tty_mutex); - -int console_use_vt = 1; +DECLARE_MUTEX(tty_sem); #ifdef CONFIG_UNIX98_PTYS extern struct tty_driver *ptm_driver; /* Unix98 pty masters; for /dev/ptmx */ @@ -354,10 +352,10 @@ int tty_buffer_request_room(struct tty_struct *tty, size_t size) spin_unlock_irqrestore(&tty->buf.lock, flags); return size; } + EXPORT_SYMBOL_GPL(tty_buffer_request_room); -int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, - size_t size) +int tty_insert_flip_string(struct tty_struct *tty, unsigned char *chars, size_t size) { int copied = 0; do { @@ -371,16 +369,17 @@ int tty_insert_flip_string(struct tty_struct *tty, const unsigned char *chars, tb->used += space; copied += space; chars += space; +/* printk("Flip insert %d.\n", space); */ } /* There is a small chance that we need to split the data over several buffers. If this is the case we must loop */ while (unlikely(size > copied)); return copied; } -EXPORT_SYMBOL(tty_insert_flip_string); -int tty_insert_flip_string_flags(struct tty_struct *tty, - const unsigned char *chars, const char *flags, size_t size) +EXPORT_SYMBOL_GPL(tty_insert_flip_string); + +int tty_insert_flip_string_flags(struct tty_struct *tty, unsigned char *chars, char *flags, size_t size) { int copied = 0; do { @@ -401,20 +400,9 @@ int tty_insert_flip_string_flags(struct tty_struct *tty, while (unlikely(size > copied)); return copied; } -EXPORT_SYMBOL(tty_insert_flip_string_flags); -void tty_schedule_flip(struct tty_struct *tty) -{ - unsigned long flags; - spin_lock_irqsave(&tty->buf.lock, flags); - if (tty->buf.tail != NULL) { - tty->buf.tail->active = 0; - tty->buf.tail->commit = tty->buf.tail->used; - } - spin_unlock_irqrestore(&tty->buf.lock, flags); - schedule_delayed_work(&tty->buf.work, 1); -} -EXPORT_SYMBOL(tty_schedule_flip); +EXPORT_SYMBOL_GPL(tty_insert_flip_string_flags); + /* * Prepare a block of space in the buffer for data. Returns the length @@ -556,12 +544,14 @@ void tty_ldisc_put(int disc) struct tty_ldisc *ld; unsigned long flags; - BUG_ON(disc < N_TTY || disc >= NR_LDISCS); + if (disc < N_TTY || disc >= NR_LDISCS) + BUG(); spin_lock_irqsave(&tty_ldisc_lock, flags); ld = &tty_ldiscs[disc]; - BUG_ON(ld->refcount == 0); - ld->refcount--; + if(ld->refcount == 0) + BUG(); + ld->refcount --; module_put(ld->owner); spin_unlock_irqrestore(&tty_ldisc_lock, flags); } @@ -656,7 +646,8 @@ void tty_ldisc_deref(struct tty_ldisc *ld) { unsigned long flags; - BUG_ON(ld == NULL); + if(ld == NULL) + BUG(); spin_lock_irqsave(&tty_ldisc_lock, flags); if(ld->refcount == 0) @@ -1107,8 +1098,8 @@ static void do_tty_hangup(void *data) p->signal->tty = NULL; if (!p->signal->leader) continue; - group_send_sig_info(SIGHUP, SEND_SIG_PRIV, p); - group_send_sig_info(SIGCONT, SEND_SIG_PRIV, p); + send_group_sig_info(SIGHUP, SEND_SIG_PRIV, p); + send_group_sig_info(SIGCONT, SEND_SIG_PRIV, p); if (tty->pgrp > 0) p->signal->tty_old_pgrp = tty->pgrp; } while_each_task_pid(tty->session, PIDTYPE_SID, p); @@ -1198,11 +1189,11 @@ void disassociate_ctty(int on_exit) lock_kernel(); - mutex_lock(&tty_mutex); + down(&tty_sem); tty = current->signal->tty; if (tty) { tty_pgrp = tty->pgrp; - mutex_unlock(&tty_mutex); + up(&tty_sem); if (on_exit && tty->driver->type != TTY_DRIVER_TYPE_PTY) tty_vhangup(tty); } else { @@ -1210,7 +1201,7 @@ void disassociate_ctty(int on_exit) kill_pg(current->signal->tty_old_pgrp, SIGHUP, on_exit); kill_pg(current->signal->tty_old_pgrp, SIGCONT, on_exit); } - mutex_unlock(&tty_mutex); + up(&tty_sem); unlock_kernel(); return; } @@ -1221,7 +1212,7 @@ void disassociate_ctty(int on_exit) } /* Must lock changes to tty_old_pgrp */ - mutex_lock(&tty_mutex); + down(&tty_sem); current->signal->tty_old_pgrp = 0; tty->session = 0; tty->pgrp = -1; @@ -1232,7 +1223,7 @@ void disassociate_ctty(int on_exit) p->signal->tty = NULL; } while_each_task_pid(current->signal->session, PIDTYPE_SID, p); read_unlock(&tasklist_lock); - mutex_unlock(&tty_mutex); + up(&tty_sem); unlock_kernel(); } @@ -1316,7 +1307,7 @@ static inline ssize_t do_tty_write( ssize_t ret = 0, written = 0; unsigned int chunk; - if (mutex_lock_interruptible(&tty->atomic_write_lock)) { + if (down_interruptible(&tty->atomic_write)) { return -ERESTARTSYS; } @@ -1339,7 +1330,7 @@ static inline ssize_t do_tty_write( if (count < chunk) chunk = count; - /* write_buf/write_cnt is protected by the atomic_write_lock mutex */ + /* write_buf/write_cnt is protected by the atomic_write semaphore */ if (tty->write_cnt < chunk) { unsigned char *buf; @@ -1348,7 +1339,7 @@ static inline ssize_t do_tty_write( buf = kmalloc(chunk, GFP_KERNEL); if (!buf) { - mutex_unlock(&tty->atomic_write_lock); + up(&tty->atomic_write); return -ENOMEM; } kfree(tty->write_buf); @@ -1384,7 +1375,7 @@ static inline ssize_t do_tty_write( inode->i_mtime = current_fs_time(inode->i_sb); ret = written; } - mutex_unlock(&tty->atomic_write_lock); + up(&tty->atomic_write); return ret; } @@ -1452,8 +1443,8 @@ static inline void tty_line_name(struct tty_driver *driver, int index, char *p) /* * WSH 06/09/97: Rewritten to remove races and properly clean up after a - * failed open. The new code protects the open with a mutex, so it's - * really quite straightforward. The mutex locking can probably be + * failed open. The new code protects the open with a semaphore, so it's + * really quite straightforward. The semaphore locking can probably be * relaxed for the (most common) case of reopening a tty. */ static int init_dev(struct tty_driver *driver, int idx, @@ -1650,7 +1641,7 @@ fast_track: success: *ret_tty = tty; - /* All paths come through here to release the mutex */ + /* All paths come through here to release the semaphore */ end_init: return retval; @@ -1743,7 +1734,7 @@ static void release_dev(struct file * filp) { struct tty_struct *tty, *o_tty; int pty_master, tty_closing, o_tty_closing, do_sleep; - int devpts; + int devpts_master, devpts; int idx; char buf[64]; unsigned long flags; @@ -1760,6 +1751,7 @@ static void release_dev(struct file * filp) pty_master = (tty->driver->type == TTY_DRIVER_TYPE_PTY && tty->driver->subtype == PTY_TYPE_MASTER); devpts = (tty->driver->flags & TTY_DRIVER_DEVPTS_MEM) != 0; + devpts_master = pty_master && devpts; o_tty = tty->link; #ifdef TTY_PARANOIA_CHECK @@ -1846,7 +1838,7 @@ static void release_dev(struct file * filp) /* Guard against races with tty->count changes elsewhere and opens on /dev/tty */ - mutex_lock(&tty_mutex); + down(&tty_sem); tty_closing = tty->count <= 1; o_tty_closing = o_tty && (o_tty->count <= (pty_master ? 1 : 0)); @@ -1877,7 +1869,7 @@ static void release_dev(struct file * filp) printk(KERN_WARNING "release_dev: %s: read/write wait queue " "active!\n", tty_name(tty, buf)); - mutex_unlock(&tty_mutex); + up(&tty_sem); schedule(); } @@ -1943,7 +1935,7 @@ static void release_dev(struct file * filp) read_unlock(&tasklist_lock); } - mutex_unlock(&tty_mutex); + up(&tty_sem); /* check whether both sides are closing ... */ if (!tty_closing || (o_tty && !o_tty_closing)) @@ -2049,11 +2041,11 @@ retry_open: index = -1; retval = 0; - mutex_lock(&tty_mutex); + down(&tty_sem); if (device == MKDEV(TTYAUX_MAJOR,0)) { if (!current->signal->tty) { - mutex_unlock(&tty_mutex); + up(&tty_sem); return -ENXIO; } driver = current->signal->tty->driver; @@ -2063,7 +2055,7 @@ retry_open: goto got_driver; } #ifdef CONFIG_VT - if (console_use_vt && (device == MKDEV(TTY_MAJOR,0))) { + if (device == MKDEV(TTY_MAJOR,0)) { extern struct tty_driver *console_driver; driver = console_driver; index = fg_console; @@ -2079,18 +2071,18 @@ retry_open: noctty = 1; goto got_driver; } - mutex_unlock(&tty_mutex); + up(&tty_sem); return -ENODEV; } driver = get_tty_driver(device, &index); if (!driver) { - mutex_unlock(&tty_mutex); + up(&tty_sem); return -ENODEV; } got_driver: retval = init_dev(driver, index, &tty); - mutex_unlock(&tty_mutex); + up(&tty_sem); if (retval) return retval; @@ -2176,9 +2168,9 @@ static int ptmx_open(struct inode * inode, struct file * filp) } up(&allocated_ptys_lock); - mutex_lock(&tty_mutex); + down(&tty_sem); retval = init_dev(ptm_driver, index, &tty); - mutex_unlock(&tty_mutex); + up(&tty_sem); if (retval) goto out; @@ -2197,7 +2189,6 @@ static int ptmx_open(struct inode * inode, struct file * filp) return 0; out1: release_dev(filp); - return retval; out: down(&allocated_ptys_lock); idr_remove(&allocated_ptys, index); @@ -2690,7 +2681,7 @@ static void __do_SAK(void *arg) tty_hangup(tty); #else struct tty_struct *tty = arg; - struct task_struct *g, *p; + struct task_struct *p; int session; int i; struct file *filp; @@ -2711,18 +2702,8 @@ static void __do_SAK(void *arg) tty->driver->flush_buffer(tty); read_lock(&tasklist_lock); - /* Kill the entire session */ do_each_task_pid(session, PIDTYPE_SID, p) { - printk(KERN_NOTICE "SAK: killed process %d" - " (%s): p->signal->session==tty->session\n", - p->pid, p->comm); - send_sig(SIGKILL, p, 1); - } while_each_task_pid(session, PIDTYPE_SID, p); - /* Now kill any processes that happen to have the - * tty open. - */ - do_each_thread(g, p) { - if (p->signal->tty == tty) { + if (p->signal->tty == tty || session > 0) { printk(KERN_NOTICE "SAK: killed process %d" " (%s): p->signal->session==tty->session\n", p->pid, p->comm); @@ -2746,14 +2727,14 @@ static void __do_SAK(void *arg) printk(KERN_NOTICE "SAK: killed process %d" " (%s): fd#%d opened to the tty\n", p->pid, p->comm, i); - force_sig(SIGKILL, p); + send_sig(SIGKILL, p, 1); break; } } spin_unlock(&p->files->file_lock); } task_unlock(p); - } while_each_thread(g, p); + } while_each_task_pid(session, PIDTYPE_SID, p); read_unlock(&tasklist_lock); #endif } @@ -2948,8 +2929,8 @@ static void initialize_tty_struct(struct tty_struct *tty) init_waitqueue_head(&tty->write_wait); init_waitqueue_head(&tty->read_wait); INIT_WORK(&tty->hangup_work, do_tty_hangup, tty); - mutex_init(&tty->atomic_read_lock); - mutex_init(&tty->atomic_write_lock); + sema_init(&tty->atomic_read, 1); + sema_init(&tty->atomic_write, 1); spin_lock_init(&tty->read_lock); INIT_LIST_HEAD(&tty->tty_files); INIT_WORK(&tty->SAK_work, NULL, NULL); @@ -3270,8 +3251,6 @@ static int __init tty_init(void) #endif #ifdef CONFIG_VT - if (!console_use_vt) - goto out_vt; cdev_init(&vc0_cdev, &console_fops); if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) || register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0) @@ -3280,7 +3259,6 @@ static int __init tty_init(void) class_device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0"); vty_init(); - out_vt: #endif return 0; }