static int parasite_dump_tty(struct parasite_tty_args *args) { int ret; #ifndef TIOCGPKT # define TIOCGPKT _IOR('T', 0x38, int) #endif #ifndef TIOCGPTLCK # define TIOCGPTLCK _IOR('T', 0x39, int) #endif #ifndef TIOCGEXCL # define TIOCGEXCL _IOR('T', 0x40, int) #endif ret = tty_ioctl(args->fd, TIOCGSID, &args->sid); if (ret < 0) goto err; ret = tty_ioctl(args->fd, TIOCGPGRP, &args->pgrp); if (ret < 0) goto err; ret = tty_ioctl(args->fd, TIOCGPKT, &args->st_pckt); if (ret < 0) goto err; ret = tty_ioctl(args->fd, TIOCGPTLCK, &args->st_lock); if (ret < 0) goto err; ret = tty_ioctl(args->fd, TIOCGEXCL, &args->st_excl); if (ret < 0) goto err; args->hangup = false; return 0; err: if (ret != -EIO) { pr_err("TTY: Can't get sid/pgrp: %d\n", ret); return -1; } /* kernel reports EIO for get ioctls on pair-less ptys */ args->sid = 0; args->pgrp = 0; args->st_pckt = 0; args->st_lock = 0; args->st_excl = 0; args->hangup = true; return 0; }
static void setup_hs_tty(struct file *tty_fp) { struct termios hs_termios; mm_segment_t old_fs; old_fs = get_fs(); set_fs(KERNEL_DS); tty_ioctl(tty_fp, TCGETS, (unsigned long)&hs_termios); hs_termios.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); hs_termios.c_oflag &= ~OPOST; hs_termios.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); hs_termios.c_cflag &= ~(CSIZE|CBAUD|PARENB|CSTOPB); hs_termios.c_cflag |= (CREAD|CS8|CLOCAL|CRTSCTS|B38400); tty_ioctl(tty_fp, TCSETS, (unsigned long)&hs_termios); set_fs(old_fs); }
int vt_ioctl(uint8_t minor, uarg_t request, char *data) { /* FIXME: need to address the multiple vt switching case here.. probably need to switch vt */ if (minor <= MAX_VT) { switch(request) { #ifdef KEY_ROWS case KBMAPSIZE: return KEY_ROWS << 8 | KEY_COLS; case KBMAPGET: return uput(keymap, data, sizeof(keymap)); case KBSETTRANS: if (esuper()) return -1; if (uget(keyboard, data, sizeof(keyboard)) == -1) return -1; return uget(shiftkeyboard, data + sizeof(keyboard), sizeof(shiftkeyboard)); #endif case VTSIZE: return VT_HEIGHT << 8 | VT_WIDTH; case VTATTRS: return vtattr_cap; } } return tty_ioctl(minor, request, data); }
static int serial_ioctl(device_t dev, u_long cmd, void *arg) { struct serial_softc *sc = device_private(dev); return tty_ioctl(&sc->tty, cmd, arg); }
static status_t master_ioctl(void *_cookie, uint32 op, void *buffer, size_t length) { master_cookie *cookie = (master_cookie *)_cookie; TRACE(("master_ioctl: cookie %p, op %lu, buffer %p, length %lu\n", _cookie, op, buffer, length)); return tty_ioctl(cookie, op, buffer, length); }
static int dev_uart_ioctl(struct file_desc *desc, int request, ...) { va_list va; void *data; struct uart *uart_dev = desc->file_info; va_start(va, request); data = va_arg(va, void *); va_end(va); return tty_ioctl(&uart_dev->tty, request, data); }
static int ttym_ioctl(dev_cookie _cookie, int op, void *buf, size_t len) { tty_master_cookie *cookie = (tty_master_cookie *)_cookie; int err; TRACE(("ttym_ioctl: cookie %p, op %d, buf %p, len %d\n", cookie, op, buf, len)); switch(op) { case _TTY_IOCTL_GET_TTY_NUM: err = cookie->tty->index; break; default: err = tty_ioctl(cookie->tty, op, buf, len); } return err; }
static int ptsdev_ioctl(struct file *fp, u_long cmd, void *data, struct ucred *active_cred, struct thread *td) { struct tty *tp = fp->f_data; struct pts_softc *psc = tty_softc(tp); int error = 0, sig; switch (cmd) { case FIODTYPE: *(int *)data = D_TTY; return (0); case FIONBIO: /* This device supports non-blocking operation. */ return (0); case FIONREAD: tty_lock(tp); if (psc->pts_flags & PTS_FINISHED) { /* Force read() to be called. */ *(int *)data = 1; } else { *(int *)data = ttydisc_getc_poll(tp); } tty_unlock(tp); return (0); case FIODGNAME: { struct fiodgname_arg *fgn; const char *p; int i; /* Reverse device name lookups, for ptsname() and ttyname(). */ fgn = data; p = tty_devname(tp); i = strlen(p) + 1; if (i > fgn->len) return (EINVAL); return copyout(p, fgn->buf, i); } /* * We need to implement TIOCGPGRP and TIOCGSID here again. When * called on the pseudo-terminal master, it should not check if * the terminal is the foreground terminal of the calling * process. * * TIOCGETA is also implemented here. Various Linux PTY routines * often call isatty(), which is implemented by tcgetattr(). */ #ifdef PTS_LINUX case TIOCGETA: /* Obtain terminal flags through tcgetattr(). */ tty_lock(tp); *(struct termios*)data = tp->t_termios; tty_unlock(tp); return (0); #endif /* PTS_LINUX */ case TIOCSETAF: case TIOCSETAW: /* * We must make sure we turn tcsetattr() calls of TCSAFLUSH and * TCSADRAIN into something different. If an application would * call TCSAFLUSH or TCSADRAIN on the master descriptor, it may * deadlock waiting for all data to be read. */ cmd = TIOCSETA; break; #if defined(PTS_COMPAT) || defined(PTS_LINUX) case TIOCGPTN: /* * Get the device unit number. */ if (psc->pts_unit < 0) return (ENOTTY); *(unsigned int *)data = psc->pts_unit; return (0); #endif /* PTS_COMPAT || PTS_LINUX */ case TIOCGPGRP: /* Get the foreground process group ID. */ tty_lock(tp); if (tp->t_pgrp != NULL) *(int *)data = tp->t_pgrp->pg_id; else *(int *)data = NO_PID; tty_unlock(tp); return (0); case TIOCGSID: /* Get the session leader process ID. */ tty_lock(tp); if (tp->t_session == NULL) error = ENOTTY; else *(int *)data = tp->t_session->s_sid; tty_unlock(tp); return (error); case TIOCPTMASTER: /* Yes, we are a pseudo-terminal master. */ return (0); case TIOCSIG: /* Signal the foreground process group. */ sig = *(int *)data; if (sig < 1 || sig >= NSIG) return (EINVAL); tty_lock(tp); tty_signal_pgrp(tp, sig); tty_unlock(tp); return (0); case TIOCPKT: /* Enable/disable packet mode. */ tty_lock(tp); if (*(int *)data) psc->pts_flags |= PTS_PKT; else psc->pts_flags &= ~PTS_PKT; tty_unlock(tp); return (0); } /* Just redirect this ioctl to the slave device. */ tty_lock(tp); error = tty_ioctl(tp, cmd, data, fp->f_flag, td); tty_unlock(tp); if (error == ENOIOCTL) error = ENOTTY; return (error); }
static int fbcon_idesc_ioctl(struct idesc *idesc, int request, void *data) { struct fbcon *fbcon = data2fbcon(idesc); return tty_ioctl(&(fbcon->vterm.tty), request, data); }
static int vc_ioctl(struct idesc *desc, int request, void *data) { return tty_ioctl(&vc_vterm.tty, request, data); }
int pty_ioctl(uint8_t minor, uint16_t request, char *data) { return tty_ioctl(minor + PTY_OFFSET, rawflag, flag); }
/*ARGSUSED*/ int tty_ioctl_compat(struct tty *tp, u_long com, caddr_t data, int fflag, struct thread *td) { switch (com) { case TIOCSETP: case TIOCSETN: case TIOCSETC: case TIOCSLTC: case TIOCLBIS: case TIOCLBIC: case TIOCLSET: { struct termios term; int error; term = tp->t_termios; if ((error = ttsetcompat(tp, &com, data, &term)) != 0) return error; return tty_ioctl(tp, com, &term, fflag, td); } case TIOCGETP: { struct sgttyb *sg = (struct sgttyb *)data; cc_t *cc = tp->t_termios.c_cc; sg->sg_ospeed = ttcompatspeedtab(tp->t_termios.c_ospeed, compatspeeds); if (tp->t_termios.c_ispeed == 0) sg->sg_ispeed = sg->sg_ospeed; else sg->sg_ispeed = ttcompatspeedtab(tp->t_termios.c_ispeed, compatspeeds); sg->sg_erase = cc[VERASE]; sg->sg_kill = cc[VKILL]; sg->sg_flags = tp->t_compatflags = ttcompatgetflags(tp); break; } case TIOCGETC: { struct tchars *tc = (struct tchars *)data; cc_t *cc = tp->t_termios.c_cc; tc->t_intrc = cc[VINTR]; tc->t_quitc = cc[VQUIT]; tc->t_startc = cc[VSTART]; tc->t_stopc = cc[VSTOP]; tc->t_eofc = cc[VEOF]; tc->t_brkc = cc[VEOL]; break; } case TIOCGLTC: { struct ltchars *ltc = (struct ltchars *)data; cc_t *cc = tp->t_termios.c_cc; ltc->t_suspc = cc[VSUSP]; ltc->t_dsuspc = cc[VDSUSP]; ltc->t_rprntc = cc[VREPRINT]; ltc->t_flushc = cc[VDISCARD]; ltc->t_werasc = cc[VWERASE]; ltc->t_lnextc = cc[VLNEXT]; break; } case TIOCLGET: tp->t_compatflags = (ttcompatgetflags(tp) & 0xffff0000UL) | (tp->t_compatflags & 0xffff); *(int *)data = tp->t_compatflags>>16; if (ttydebug) printf("CLGET: returning %x\n", *(int *)data); break; case OTIOCGETD: *(int *)data = 2; break; case OTIOCSETD: { int ldisczero = 0; return (tty_ioctl(tp, TIOCSETD, *(int *)data == 2 ? (caddr_t)&ldisczero : data, fflag, td)); } case OTIOCCONS: *(int *)data = 1; return (tty_ioctl(tp, TIOCCONS, data, fflag, td)); default: return (ENOIOCTL); } return (0); }