linux/arch/um/drivers/tty.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
   4 */
   5
   6#include <errno.h>
   7#include <fcntl.h>
   8#include <termios.h>
   9#include "chan_user.h"
  10#include <os.h>
  11#include <um_malloc.h>
  12
  13struct tty_chan {
  14        char *dev;
  15        int raw;
  16        struct termios tt;
  17};
  18
  19static void *tty_chan_init(char *str, int device, const struct chan_opts *opts)
  20{
  21        struct tty_chan *data;
  22
  23        if (*str != ':') {
  24                printk(UM_KERN_ERR "tty_init : channel type 'tty' must specify "
  25                       "a device\n");
  26                return NULL;
  27        }
  28        str++;
  29
  30        data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
  31        if (data == NULL)
  32                return NULL;
  33        *data = ((struct tty_chan) { .dev       = str,
  34                                     .raw       = opts->raw });
  35
  36        return data;
  37}
  38
  39static int tty_open(int input, int output, int primary, void *d,
  40                    char **dev_out)
  41{
  42        struct tty_chan *data = d;
  43        int fd, err, mode = 0;
  44
  45        if (input && output)
  46                mode = O_RDWR;
  47        else if (input)
  48                mode = O_RDONLY;
  49        else if (output)
  50                mode = O_WRONLY;
  51
  52        fd = open(data->dev, mode);
  53        if (fd < 0)
  54                return -errno;
  55
  56        if (data->raw) {
  57                CATCH_EINTR(err = tcgetattr(fd, &data->tt));
  58                if (err)
  59                        return err;
  60
  61                err = raw(fd);
  62                if (err)
  63                        return err;
  64        }
  65
  66        *dev_out = data->dev;
  67        return fd;
  68}
  69
  70const struct chan_ops tty_ops = {
  71        .type           = "tty",
  72        .init           = tty_chan_init,
  73        .open           = tty_open,
  74        .close          = generic_close,
  75        .read           = generic_read,
  76        .write          = generic_write,
  77        .console_write  = generic_console_write,
  78        .window_size    = generic_window_size,
  79        .free           = generic_free,
  80        .winch          = 0,
  81};
  82