Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
tty.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
3  * Licensed under the GPL
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 
13 struct tty_chan {
14  char *dev;
15  int raw;
16  struct termios tt;
17 };
18 
19 static 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 
39 static 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 
70 const 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 };