mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
81 lines
1.5 KiB
81 lines
1.5 KiB
// SPDX-License-Identifier: GPL-2.0 |
|
/* |
|
* Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com) |
|
*/ |
|
|
|
#include <errno.h> |
|
#include <fcntl.h> |
|
#include <termios.h> |
|
#include "chan_user.h" |
|
#include <os.h> |
|
#include <um_malloc.h> |
|
|
|
struct tty_chan { |
|
char *dev; |
|
int raw; |
|
struct termios tt; |
|
}; |
|
|
|
static void *tty_chan_init(char *str, int device, const struct chan_opts *opts) |
|
{ |
|
struct tty_chan *data; |
|
|
|
if (*str != ':') { |
|
printk(UM_KERN_ERR "tty_init : channel type 'tty' must specify " |
|
"a device\n"); |
|
return NULL; |
|
} |
|
str++; |
|
|
|
data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL); |
|
if (data == NULL) |
|
return NULL; |
|
*data = ((struct tty_chan) { .dev = str, |
|
.raw = opts->raw }); |
|
|
|
return data; |
|
} |
|
|
|
static int tty_open(int input, int output, int primary, void *d, |
|
char **dev_out) |
|
{ |
|
struct tty_chan *data = d; |
|
int fd, err, mode = 0; |
|
|
|
if (input && output) |
|
mode = O_RDWR; |
|
else if (input) |
|
mode = O_RDONLY; |
|
else if (output) |
|
mode = O_WRONLY; |
|
|
|
fd = open(data->dev, mode); |
|
if (fd < 0) |
|
return -errno; |
|
|
|
if (data->raw) { |
|
CATCH_EINTR(err = tcgetattr(fd, &data->tt)); |
|
if (err) |
|
return err; |
|
|
|
err = raw(fd); |
|
if (err) |
|
return err; |
|
} |
|
|
|
*dev_out = data->dev; |
|
return fd; |
|
} |
|
|
|
const struct chan_ops tty_ops = { |
|
.type = "tty", |
|
.init = tty_chan_init, |
|
.open = tty_open, |
|
.close = generic_close, |
|
.read = generic_read, |
|
.write = generic_write, |
|
.console_write = generic_console_write, |
|
.window_size = generic_window_size, |
|
.free = generic_free, |
|
.winch = 0, |
|
};
|
|
|