root/drivers/char/pty.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. pty_close
  2. pty_copy
  3. pty_write
  4. pty_open

   1 /*
   2  *  linux/kernel/chr_drv/pty.c
   3  *
   4  *  Copyright (C) 1991, 1992  Linus Torvalds
   5  */
   6 
   7 /*
   8  *      pty.c
   9  *
  10  * This module exports the following pty function:
  11  * 
  12  *      int  pty_open(struct tty_struct * tty, struct file * filp);
  13  */
  14 
  15 #include <linux/errno.h>
  16 #include <linux/sched.h>
  17 #include <linux/tty.h>
  18 #include <linux/fcntl.h>
  19 #include <linux/interrupt.h>
  20 #include <linux/string.h>
  21 
  22 #include <asm/system.h>
  23 #include <asm/bitops.h>
  24 
  25 #define MIN(a,b)        ((a) < (b) ? (a) : (b))
  26 
  27 static void pty_close(struct tty_struct * tty, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
  28 {
  29         if (!tty)
  30                 return;
  31         if (IS_A_PTY_MASTER(tty->line)) {
  32                 if (tty->count > 1)
  33                         printk("master pty_close: count = %d!!\n", tty->count);
  34         } else {
  35                 if (tty->count > 2)
  36                         return;
  37         }
  38         wake_up_interruptible(&tty->secondary.proc_list);
  39         wake_up_interruptible(&tty->read_q.proc_list);
  40         wake_up_interruptible(&tty->write_q.proc_list);
  41         if (!tty->link)
  42                 return;
  43         wake_up_interruptible(&tty->link->secondary.proc_list);
  44         wake_up_interruptible(&tty->link->read_q.proc_list);
  45         wake_up_interruptible(&tty->link->write_q.proc_list);
  46         if (IS_A_PTY_MASTER(tty->line))
  47                 tty_hangup(tty->link);
  48         else {
  49                 start_tty(tty);
  50                 set_bit(TTY_SLAVE_CLOSED, &tty->link->flags);
  51         }
  52 }
  53 
  54 static inline void pty_copy(struct tty_struct * from, struct tty_struct * to)
     /* [previous][next][first][last][top][bottom][index][help] */
  55 {
  56         unsigned long count, n;
  57         struct tty_queue *fq, *tq;
  58 
  59         if (from->stopped || EMPTY(&from->write_q))
  60                 return;
  61         fq = &from->write_q;
  62         tq = &to->read_q;
  63         count = MIN(CHARS(fq), LEFT(tq));
  64         while (count) {
  65                 n = MIN(MIN(TTY_BUF_SIZE - fq->tail, TTY_BUF_SIZE - tq->head),
  66                         count);
  67                 memcpy(&tq->buf[tq->head], &fq->buf[fq->tail], n);
  68                 count -= n;
  69                 fq->tail = (fq->tail + n) & (TTY_BUF_SIZE - 1);
  70                 tq->head = (tq->head + n) & (TTY_BUF_SIZE - 1);
  71         }
  72         TTY_READ_FLUSH(to);
  73         if (LEFT(fq) > WAKEUP_CHARS)
  74                 wake_up_interruptible(&fq->proc_list);
  75         if (from->write_data_cnt) {
  76                 set_bit(from->line, &tty_check_write);
  77                 mark_bh(TTY_BH);
  78         }
  79 }
  80 
  81 /*
  82  * This routine gets called when tty_write has put something into
  83  * the write_queue. It copies the input to the output-queue of its
  84  * slave.
  85  */
  86 static void pty_write(struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
  87 {
  88         if (tty->link)
  89                 pty_copy(tty,tty->link);
  90 }
  91 
  92 int pty_open(struct tty_struct *tty, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
  93 {
  94         if (!tty || !tty->link)
  95                 return -ENODEV;
  96         if (IS_A_PTY_SLAVE(tty->line))
  97                 clear_bit(TTY_SLAVE_CLOSED, &tty->link->flags);
  98         tty->write = tty->link->write = pty_write;
  99         tty->close = tty->link->close = pty_close;
 100         wake_up_interruptible(&tty->read_q.proc_list);
 101         if (filp->f_flags & O_NDELAY)
 102                 return 0;
 103         while (!tty->link->count && !(current->signal & ~current->blocked))
 104                 interruptible_sleep_on(&tty->link->read_q.proc_list);
 105         if (!tty->link->count)
 106                 return -ERESTARTSYS;
 107         return 0;
 108 }

/* [previous][next][first][last][top][bottom][index][help] */