int tty_ioctl(struct inode *inode, struct file *file, int cmd, register char *arg) { register struct tty *tty = determine_tty(inode->i_rdev); int ret; switch (cmd) { case TCGETS: ret = verified_memcpy_tofs(arg, &tty->termios, sizeof(struct termios)); break; case TCSETS: case TCSETSW: case TCSETSF: ret = verified_memcpy_fromfs(&tty->termios, arg, sizeof(struct termios)); /* Inform driver that things have changed */ if (tty->ops->ioctl != NULL) tty->ops->ioctl(tty, cmd, arg); break; default: ret = (tty->ops->ioctl == NULL) ? -EINVAL : tty->ops->ioctl(tty, cmd, arg); } return ret; }
int tty_open(struct inode *inode, struct file *file) { register struct tty *otty; register __ptask currentp = current; int err; if (!(otty = determine_tty(inode->i_rdev))) return -ENODEV; #if 0 memcpy(&otty->termios, &def_vals, sizeof(struct termios)); #endif err = otty->ops->open(otty); if (err) return err; if (otty->pgrp == NULL && currentp->session == currentp->pid && currentp->tty == NULL) { otty->pgrp = currentp->pgrp; currentp->tty = otty; } otty->flags |= TTY_OPEN; chq_init(&otty->inq, otty->inq_buf, INQ_SIZE); chq_init(&otty->outq, otty->outq_buf, OUTQ_SIZE); return 0; }
int tty_release(struct inode *inode, struct file *file) { register struct tty *rtty; rtty = determine_tty(inode->i_rdev); if (!rtty) return -ENODEV; if (current->pid == rtty->pgrp) { kill_pg(rtty->pgrp, SIGHUP, 1); rtty->pgrp = NULL; } rtty->flags &= ~TTY_OPEN; return rtty->ops->release(rtty); }
int tty_write(struct inode *inode, struct file *file, char *data, int len) { register struct tty *tty = determine_tty(inode->i_rdev); register char *pi; #if 0 int blocking = (file->f_flags & O_NONBLOCK) ? 0 : 1; #endif pi = (char *)len; while ((int)(pi--)) { tty_charout(tty, get_user_char((void *)(data++)) /* , blocking */ ); } return len; }
int tty_write(struct inode *inode, struct file *file, char *data, int len) { register struct tty *tty = determine_tty(inode->i_rdev); register char *pi; #if 0 int blocking = (file->f_flags & O_NONBLOCK) ? 0 : 1; #endif __u16 tmp; pi = 0; while (((int)pi) < len) { tmp = peekb(current->t_regs.ds, (__u16) (data + ((int)pi))); tty_charout(tty, (unsigned char) tmp /* , blocking */ ); ++pi; } tty->ops->write(tty); return (int)pi; }
int tty_select(struct inode *inode, /* how revolting, K&R style defs */ struct file *file, int sel_type) { register struct tty *tty = determine_tty(inode->i_rdev); register char *ret = 0; switch (sel_type) { case SEL_IN: if (chq_peekch(&tty->inq)) return 1; select_wait(&tty->inq.wq); break; case SEL_OUT: ret = (char *)(!chq_full(&tty->outq)); if (!ret) select_wait(&tty->outq.wq); /*@fallthrough@*/ /* case SEL_EX: */ /* break; */ } return (int) ret; }
int tty_read(struct inode *inode, struct file *file, char *data, int len) { #if 1 register struct tty *tty = determine_tty(inode->i_rdev); register char *pi = 0; int j, k; int rawmode = (tty->termios.c_lflag & ICANON) ? 0 : 1; int blocking = (file->f_flags & O_NONBLOCK) ? 0 : 1; unsigned char ch; if (len != 0) { do { if (tty->ops->read) { tty->ops->read(tty); blocking = 0; } j = chq_getch(&tty->inq, &ch, blocking); if (j == -1) { if (!blocking) break; return -EINTR; } if (!rawmode && (j == 04)) /* CTRL-D */ break; if (rawmode || (j != '\b')) { pokeb(current->t_regs.ds, (__u16) (data + ((int)pi)), ch); ++pi; tty_echo(tty, ch); } else if (((int)pi) > 0) { --pi; k = ((peekb(current->t_regs.ds, (__u16) (data + ((int)pi))) == '\t') ? TAB_SPACES : 1); do { tty_echo(tty, ch); } while (--k); } } while (((int)pi) < len && (rawmode || j != '\n')); } return (int) pi; #else register struct tty *tty = determine_tty(inode->i_rdev); int i = 0, j = 0, k, lch; int rawmode = (tty->termios.c_lflag & ICANON) ? 0 : 1; int blocking = (file->f_flags & O_NONBLOCK) ? 0 : 1; unsigned char ch; if (len == 0) return 0; do { if (tty->ops->read) { tty->ops->read(tty); blocking = 0; } j = chq_getch(&tty->inq, &ch, blocking); if (j == -1) if (blocking) return -EINTR; else break; if (!rawmode && (j == 04)) /* CTRL-D */ break; if (rawmode || (j != '\b')) { pokeb(current->t_regs.ds, (__u16) (data + i++), ch); tty_echo(tty, ch); } else if (i > 0) { lch = ((peekb(current->t_regs.ds, (__u16) (data + --i)) == '\t') ? TAB_SPACES : 1); for (k = 0; k < lch; k++) tty_echo(tty, ch); } } while (i < len && (rawmode || j != '\n')); return i; #endif }