Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/um/drivers/fd.c
10817 views
1
/*
2
* Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
3
* Licensed under the GPL
4
*/
5
6
#include <stdio.h>
7
#include <stdlib.h>
8
#include <unistd.h>
9
#include <errno.h>
10
#include <termios.h>
11
#include "chan_user.h"
12
#include "kern_constants.h"
13
#include "os.h"
14
#include "um_malloc.h"
15
#include "user.h"
16
17
struct fd_chan {
18
int fd;
19
int raw;
20
struct termios tt;
21
char str[sizeof("1234567890\0")];
22
};
23
24
static void *fd_init(char *str, int device, const struct chan_opts *opts)
25
{
26
struct fd_chan *data;
27
char *end;
28
int n;
29
30
if (*str != ':') {
31
printk(UM_KERN_ERR "fd_init : channel type 'fd' must specify a "
32
"file descriptor\n");
33
return NULL;
34
}
35
str++;
36
n = strtoul(str, &end, 0);
37
if ((*end != '\0') || (end == str)) {
38
printk(UM_KERN_ERR "fd_init : couldn't parse file descriptor "
39
"'%s'\n", str);
40
return NULL;
41
}
42
43
data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
44
if (data == NULL)
45
return NULL;
46
47
*data = ((struct fd_chan) { .fd = n,
48
.raw = opts->raw });
49
return data;
50
}
51
52
static int fd_open(int input, int output, int primary, void *d, char **dev_out)
53
{
54
struct fd_chan *data = d;
55
int err;
56
57
if (data->raw && isatty(data->fd)) {
58
CATCH_EINTR(err = tcgetattr(data->fd, &data->tt));
59
if (err)
60
return err;
61
62
err = raw(data->fd);
63
if (err)
64
return err;
65
}
66
sprintf(data->str, "%d", data->fd);
67
*dev_out = data->str;
68
return data->fd;
69
}
70
71
static void fd_close(int fd, void *d)
72
{
73
struct fd_chan *data = d;
74
int err;
75
76
if (!data->raw || !isatty(fd))
77
return;
78
79
CATCH_EINTR(err = tcsetattr(fd, TCSAFLUSH, &data->tt));
80
if (err)
81
printk(UM_KERN_ERR "Failed to restore terminal state - "
82
"errno = %d\n", -err);
83
data->raw = 0;
84
}
85
86
const struct chan_ops fd_ops = {
87
.type = "fd",
88
.init = fd_init,
89
.open = fd_open,
90
.close = fd_close,
91
.read = generic_read,
92
.write = generic_write,
93
.console_write = generic_console_write,
94
.window_size = generic_window_size,
95
.free = generic_free,
96
.winch = 1,
97
};
98
99