]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/libc_be_stdin/lib/src/stdin.cc
update
[l4.git] / l4 / pkg / libc_be_stdin / lib / src / stdin.cc
1 /*
2  * (c) 2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3  *          Alexander Warg <warg@os.inf.tu-dresden.de>
4  *     economic rights: Technische Universität Dresden (Germany)
5  *
6  * This file is part of TUD:OS and distributed under the terms of the
7  * GNU General Public License 2.
8  * Please see the COPYING-GPL-2 file for details.
9  */
10
11 #include <l4/l4re_vfs/backend>
12 #include <l4/event/event>
13
14 #include <sys/ioctl.h>
15 #include <termios.h>
16 #include <unistd.h>
17 #include <cerrno>
18 #include <cstdio>
19
20 namespace {
21
22 using namespace L4Re::Vfs;
23
24 class in_ops : public Be_file_stream
25 {
26 private:
27   Event::Event  _event;
28   L4::Cap<L4::Vcon> _s;
29
30 public:
31   in_ops(L4::Cap<L4::Vcon> v)  throw()
32   : Be_file_stream(), _event(this), _s(v) {}
33   ~in_ops() throw() {}
34
35   int bind_irq(unsigned irq, L4::Cap<L4::Irq> const &irq_cap) throw()
36   { return l4_error(L4::cap_reinterpret_cast<L4::Icu>(L4Re::Env::env()->log())->bind(irq, irq_cap)); }
37
38   ssize_t readv(struct iovec const *iov, int cnt) throw()
39   {
40     if (cnt == 0)
41       return -EINVAL;
42
43     int len = iov[0].iov_len;
44     char *buf = (char *)iov[0].iov_base;
45     if (len == 0)
46       return -EINVAL;
47
48     int ret = _s->read((char *)buf, len);
49     if (ret > (int)len)
50       ret = len;
51
52     while (ret == 0)
53       {
54         // nothing read, read needs to block
55         _event.wait();
56
57         ret = _s->read((char *)buf, len);
58         if (ret > (int)len)
59           ret = len;
60       }
61
62     return ret;
63   }
64
65   int ioctl(unsigned long request, va_list args) throw()
66   {
67     switch (request) {
68       case TCGETS:
69         {
70           //vt100_tcgetattr(term, (struct termios *)argp);
71
72           struct termios *t = va_arg(args, struct termios *);
73
74           l4_vcon_attr_t l4a;
75           if (!l4_error(_s->get_attr(&l4a)))
76             {
77               t->c_iflag = l4a.i_flags;
78               t->c_oflag = l4a.o_flags; // output flags
79               t->c_cflag = 0; // control flags
80               t->c_lflag = l4a.l_flags; // local flags
81             }
82           else
83             t->c_iflag = t->c_oflag = t->c_cflag = t->c_lflag = 0;
84 #if 0
85           //t->c_lflag |= ECHO; // if term->echo
86           t->c_lflag |= ICANON; // if term->term_mode == VT100MODE_COOKED
87 #endif
88
89           t->c_cc[VEOF]   = CEOF;
90           t->c_cc[VEOL]   = _POSIX_VDISABLE;
91           t->c_cc[VEOL2]  = _POSIX_VDISABLE;
92           t->c_cc[VERASE] = CERASE;
93           t->c_cc[VWERASE]= CWERASE;
94           t->c_cc[VKILL]  = CKILL;
95           t->c_cc[VREPRINT]=CREPRINT;
96           t->c_cc[VINTR]  = CINTR;
97           t->c_cc[VQUIT]  = _POSIX_VDISABLE;
98           t->c_cc[VSUSP]  = CSUSP;
99           t->c_cc[VSTART] = CSTART;
100           t->c_cc[VSTOP] = CSTOP;
101           t->c_cc[VLNEXT] = CLNEXT;
102           t->c_cc[VDISCARD]=CDISCARD;
103           t->c_cc[VMIN] = CMIN;
104           t->c_cc[VTIME] = 0;
105
106           //printf("TCGETS: c_lflags = %08x\n", t->c_lflag);
107         }
108
109         return 0;
110
111       case TCSETS:
112       case TCSETSW:
113       case TCSETSF:
114         {
115           //vt100_tcsetattr(term, (struct termios *)argp);
116           struct termios *t = va_arg(args, struct termios *);
117
118           //XXX: probably we need to get this over to the other side!
119
120           //printf("TCSETS*: c_lflags = %08x\n", t->c_lflag);
121
122           l4_vcon_attr_t l4a;
123           l4a.i_flags = t->c_iflag;
124           l4a.o_flags = t->c_oflag; // output flags
125           l4a.l_flags = t->c_lflag; // local flags
126           _s->set_attr(&l4a);
127         }
128         return 0;
129
130       default:
131         printf("libc_be_stdin: ioctl: unknown request: %lx\n", request);
132         break;
133     };
134     return -EINVAL;
135   }
136
137   int fstat64(struct stat64 *buf) const throw()
138   {
139     (void)buf;
140     return 0;
141   }
142 };
143
144
145
146 static void get_in_ops() __attribute__((constructor));
147 static void get_in_ops()
148 {
149   static in_ops _myops(L4Re::Env::env()->log());
150   _myops.add_ref(); // prevent the static object from beeing deleted
151   L4Re::Vfs::vfs_ops->set_fd(STDIN_FILENO, cxx::ref_ptr(&_myops));
152 }
153
154 }