android_kernel_xiaomi_sm8350/arch/um/drivers/fd.c
Jeff Dike 43f5b3085f uml: fix build when SLOB is enabled
Reintroduce uml_kmalloc for the benefit of UML libc code.  The
previous tactic of declaring __kmalloc so it could be called directly
from the libc side of the house turned out to be getting too intimate
with slab, and it doesn't work with slob.

So, the uml_kmalloc wrapper is back.  It calls kmalloc or whatever
that translates into, and libc code calls it.

kfree is left alone since that still works, leaving a somewhat
inconsistent API.

Signed-off-by: Jeff Dike <jdike@linux.intel.com>
Cc: WANG Cong <xiyou.wangcong@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2008-05-13 08:02:22 -07:00

98 lines
1.9 KiB
C

/*
* Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
* Licensed under the GPL
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <termios.h>
#include "chan_user.h"
#include "kern_constants.h"
#include "os.h"
#include "um_malloc.h"
#include "user.h"
struct fd_chan {
int fd;
int raw;
struct termios tt;
char str[sizeof("1234567890\0")];
};
static void *fd_init(char *str, int device, const struct chan_opts *opts)
{
struct fd_chan *data;
char *end;
int n;
if (*str != ':') {
printk(UM_KERN_ERR "fd_init : channel type 'fd' must specify a "
"file descriptor\n");
return NULL;
}
str++;
n = strtoul(str, &end, 0);
if ((*end != '\0') || (end == str)) {
printk(UM_KERN_ERR "fd_init : couldn't parse file descriptor "
"'%s'\n", str);
return NULL;
}
data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
if (data == NULL)
return NULL;
*data = ((struct fd_chan) { .fd = n,
.raw = opts->raw });
return data;
}
static int fd_open(int input, int output, int primary, void *d, char **dev_out)
{
struct fd_chan *data = d;
int err;
if (data->raw && isatty(data->fd)) {
CATCH_EINTR(err = tcgetattr(data->fd, &data->tt));
if (err)
return err;
err = raw(data->fd);
if (err)
return err;
}
sprintf(data->str, "%d", data->fd);
*dev_out = data->str;
return data->fd;
}
static void fd_close(int fd, void *d)
{
struct fd_chan *data = d;
int err;
if (!data->raw || !isatty(fd))
return;
CATCH_EINTR(err = tcsetattr(fd, TCSAFLUSH, &data->tt));
if (err)
printk(UM_KERN_ERR "Failed to restore terminal state - "
"errno = %d\n", -err);
data->raw = 0;
}
const struct chan_ops fd_ops = {
.type = "fd",
.init = fd_init,
.open = fd_open,
.close = fd_close,
.read = generic_read,
.write = generic_write,
.console_write = generic_console_write,
.window_size = generic_window_size,
.free = generic_free,
.winch = 1,
};