blob: 218aa0e9b792b6f0351e084f8640e472ecdf5c9f [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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"
Gennady Sharapov4fef0c12006-01-18 17:42:41 -080014#include "os.h"
Paolo 'Blaisorblade' Giarrussoc13e5692006-10-19 23:28:20 -070015#include "um_malloc.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070016
17struct fd_chan {
18 int fd;
19 int raw;
20 struct termios tt;
21 char str[sizeof("1234567890\0")];
22};
23
Jeff Dike5e7672e2006-09-27 01:50:33 -070024static void *fd_init(char *str, int device, const struct chan_opts *opts)
Linus Torvalds1da177e2005-04-16 15:20:36 -070025{
26 struct fd_chan *data;
27 char *end;
28 int n;
29
30 if(*str != ':'){
31 printk("fd_init : channel type 'fd' must specify a file "
32 "descriptor\n");
33 return(NULL);
34 }
35 str++;
36 n = strtoul(str, &end, 0);
37 if((*end != '\0') || (end == str)){
38 printk("fd_init : couldn't parse file descriptor '%s'\n", str);
39 return(NULL);
40 }
41 data = um_kmalloc(sizeof(*data));
42 if(data == NULL) return(NULL);
43 *data = ((struct fd_chan) { .fd = n,
44 .raw = opts->raw });
45 return(data);
46}
47
48static int fd_open(int input, int output, int primary, void *d, char **dev_out)
49{
50 struct fd_chan *data = d;
51 int err;
52
53 if(data->raw && isatty(data->fd)){
54 CATCH_EINTR(err = tcgetattr(data->fd, &data->tt));
55 if(err)
56 return(err);
57
58 err = raw(data->fd);
59 if(err)
60 return(err);
61 }
62 sprintf(data->str, "%d", data->fd);
63 *dev_out = data->str;
64 return(data->fd);
65}
66
67static void fd_close(int fd, void *d)
68{
69 struct fd_chan *data = d;
70 int err;
71
72 if(data->raw && isatty(fd)){
73 CATCH_EINTR(err = tcsetattr(fd, TCSAFLUSH, &data->tt));
74 if(err)
75 printk("Failed to restore terminal state - "
76 "errno = %d\n", -err);
77 data->raw = 0;
78 }
79}
80
Jeff Dike5e7672e2006-09-27 01:50:33 -070081const struct chan_ops fd_ops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -070082 .type = "fd",
83 .init = fd_init,
84 .open = fd_open,
85 .close = fd_close,
86 .read = generic_read,
87 .write = generic_write,
Paolo 'Blaisorblade' Giarrussofd9bc532005-11-13 16:07:10 -080088 .console_write = generic_console_write,
Linus Torvalds1da177e2005-04-16 15:20:36 -070089 .window_size = generic_window_size,
90 .free = generic_free,
91 .winch = 1,
92};
93
94/*
95 * Overrides for Emacs so that we follow Linus's tabbing style.
96 * Emacs will notice this stuff at the end of the file and automatically
97 * adjust the settings for this buffer only. This must remain at the end
98 * of the file.
99 * ---------------------------------------------------------------------------
100 * Local variables:
101 * c-file-style: "linux"
102 * End:
103 */