PageRenderTime 19ms CodeModel.GetById 12ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 1ms

/arch/um/drivers/fd.c

https://bitbucket.org/evzijst/gittest
C | 108 lines | 81 code | 13 blank | 14 comment | 15 complexity | b668914341ef29e49b31e3b2fa1d9e62 MD5 | raw file
  1/* 
  2 * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
  3 * Licensed under the GPL
  4 */
  5
  6#include <stdio.h>
  7#include <stdlib.h>
  8#include <unistd.h>
  9#include <termios.h>
 10#include <errno.h>
 11#include "user.h"
 12#include "user_util.h"
 13#include "chan_user.h"
 14
 15struct fd_chan {
 16	int fd;
 17	int raw;
 18	struct termios tt;
 19	char str[sizeof("1234567890\0")];
 20};
 21
 22static void *fd_init(char *str, int device, struct chan_opts *opts)
 23{
 24	struct fd_chan *data;
 25	char *end;
 26	int n;
 27
 28	if(*str != ':'){
 29		printk("fd_init : channel type 'fd' must specify a file "
 30		       "descriptor\n");
 31		return(NULL);
 32	}
 33	str++;
 34	n = strtoul(str, &end, 0);
 35	if((*end != '\0') || (end == str)){
 36		printk("fd_init : couldn't parse file descriptor '%s'\n", str);
 37		return(NULL);
 38	}
 39	data = um_kmalloc(sizeof(*data));
 40	if(data == NULL) return(NULL);
 41	*data = ((struct fd_chan) { .fd  	= n,
 42				    .raw  	= opts->raw });
 43	return(data);
 44}
 45
 46static int fd_open(int input, int output, int primary, void *d, char **dev_out)
 47{
 48	struct fd_chan *data = d;
 49	int err;
 50
 51	if(data->raw && isatty(data->fd)){
 52		CATCH_EINTR(err = tcgetattr(data->fd, &data->tt));
 53		if(err)
 54			return(err);
 55
 56		err = raw(data->fd);
 57		if(err)
 58			return(err);
 59	}
 60	sprintf(data->str, "%d", data->fd);
 61	*dev_out = data->str;
 62	return(data->fd);
 63}
 64
 65static void fd_close(int fd, void *d)
 66{
 67	struct fd_chan *data = d;
 68	int err;
 69
 70	if(data->raw && isatty(fd)){
 71		CATCH_EINTR(err = tcsetattr(fd, TCSAFLUSH, &data->tt));
 72		if(err)
 73			printk("Failed to restore terminal state - "
 74			       "errno = %d\n", -err);
 75		data->raw = 0;
 76	}
 77}
 78
 79static int fd_console_write(int fd, const char *buf, int n, void *d)
 80{
 81	struct fd_chan *data = d;
 82
 83	return(generic_console_write(fd, buf, n, &data->tt));
 84}
 85
 86struct 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	= fd_console_write,
 94	.window_size	= generic_window_size,
 95	.free		= generic_free,
 96	.winch		= 1,
 97};
 98
 99/*
100 * Overrides for Emacs so that we follow Linus's tabbing style.
101 * Emacs will notice this stuff at the end of the file and automatically
102 * adjust the settings for this buffer only.  This must remain at the end
103 * of the file.
104 * ---------------------------------------------------------------------------
105 * Local variables:
106 * c-file-style: "linux"
107 * End:
108 */