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         int skip_readq;
  59 
  60         if (from->stopped || EMPTY(&from->write_q))
  61                 return;
  62         fq = &from->write_q;
  63         /* Bypass the read_q if this is a pty master. */
  64         skip_readq = IS_A_PTY_MASTER(to->line) && to->disc == N_TTY;
  65         tq = skip_readq ? &to->secondary : &to->read_q;
  66         count = MIN(CHARS(fq), LEFT(tq));
  67         while (count) {
  68                 n = MIN(MIN(TTY_BUF_SIZE - fq->tail, TTY_BUF_SIZE - tq->head),
  69                         count);
  70                 memcpy(&tq->buf[tq->head], &fq->buf[fq->tail], n);
  71                 count -= n;
  72                 fq->tail = (fq->tail + n) & (TTY_BUF_SIZE - 1);
  73                 tq->head = (tq->head + n) & (TTY_BUF_SIZE - 1);
  74         }
  75         if (skip_readq)
  76                 wake_up_interruptible(&to->secondary.proc_list);
  77         else
  78                 TTY_READ_FLUSH(to);
  79         if (LEFT(fq) > WAKEUP_CHARS)
  80                 wake_up_interruptible(&fq->proc_list);
  81         if (from->write_data_cnt) {
  82                 set_bit(from->line, &tty_check_write);
  83                 mark_bh(TTY_BH);
  84         }
  85 }
  86 
  87 /*
  88  * This routine gets called when tty_write has put something into
  89  * the write_queue. It copies the input to the output-queue of its
  90  * slave.
  91  */
  92 static void pty_write(struct tty_struct * tty)
     /* [previous][next][first][last][top][bottom][index][help] */
  93 {
  94         if (tty->link)
  95                 pty_copy(tty,tty->link);
  96 }
  97 
  98 int pty_open(struct tty_struct *tty, struct file * filp)
     /* [previous][next][first][last][top][bottom][index][help] */
  99 {
 100         if (!tty || !tty->link)
 101                 return -ENODEV;
 102         if (IS_A_PTY_SLAVE(tty->line))
 103                 clear_bit(TTY_SLAVE_CLOSED, &tty->link->flags);
 104         tty->write = tty->link->write = pty_write;
 105         tty->close = tty->link->close = pty_close;
 106         wake_up_interruptible(&tty->read_q.proc_list);
 107         if (filp->f_flags & O_NDELAY)
 108                 return 0;
 109         while (!tty->link->count && !(current->signal & ~current->blocked))
 110                 interruptible_sleep_on(&tty->link->read_q.proc_list);
 111         if (!tty->link->count)
 112                 return -ERESTARTSYS;
 113         return 0;
 114 }

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