3 #include "icu_helper.h"
7 class Vlog : public Icu_h<Vlog>, public Kobject
13 F_ONLCR = 000004, ///< Map NL to CR-NL on output
14 F_OCRNL = 000010, ///< Map CR to NL on output
15 F_ONLRET = 000040, ///< Do not ouput CR
39 #include "entry_frame.h"
41 #include "mem_space.h"
42 #include "l4_buf_iter.h"
46 #include "irq_controller.h"
48 class Vlog_irq_pin : public Sw_irq_pin
52 PUBLIC inline explicit
53 Vlog_irq_pin::Vlog_irq_pin(Vlog *i)
54 { payload()[0] = Mword(i); }
58 Vlog_irq_pin::vlog() const
59 { return (Vlog*)payload()[0]; }
64 Vlog_irq_pin::unbind_irq()
70 replace<Sw_irq_pin>();
74 FIASCO_DEFINE_KOBJ(Vlog);
79 _i_flags(F_ICRNL), _o_flags(F_ONLRET | F_OCRNL), _l_flags(F_ECHO)
81 Vkey::set_echo(Vkey::Echo_crnl);
92 PRIVATE inline NOEXPORT
94 Vlog::log_string(Syscall_frame *f, Utcb const *u)
96 L4_snd_item_iter snd_items(u, f->tag().words());
98 unsigned len = u->values[1];
99 char const *str = (char const *)&u->values[2];
101 if (len > sizeof(u->values) - sizeof(u->values[0]) * 2)
108 if (_o_flags & F_ONLCR && c == '\n')
111 if (_o_flags & F_OCRNL && c == '\r')
114 if (_o_flags & F_ONLRET && c == '\r')
121 PRIVATE inline NOEXPORT
123 Vlog::get_input(Mword rights, Syscall_frame *f, Utcb *u)
127 if (!have_receive(u))
128 return commit_result(0);
130 if (!(rights & L4_fpage::X))
131 return commit_result(-L4_err::EPerm);
133 char *buffer = reinterpret_cast<char *>(&u->values[1]);
134 long cnt_down = u->values[0] >> 16;
136 while (cnt_down && (i = Vkey::get()) != -1)
140 if (_i_flags & F_INLCR && i == '\n')
143 if (_i_flags & F_IGNCR && i == '\r')
146 if (_i_flags & F_ICRNL && i == '\r')
154 u->values[0] = buffer - reinterpret_cast<char *>(&u->values[1]);
156 u->values[0] |= 1UL<<31;
157 return commit_result(0);
162 Vlog::icu_bind_irq(Irq *irq_o, unsigned irqnum)
165 return commit_result(-L4_err::EInval);
168 _irq->pin()->unbind_irq();
170 irq_o->pin()->unbind_irq();
171 irq_o->pin()->replace<Vlog_irq_pin>(this);
174 return commit_result(0);
178 PRIVATE inline NOEXPORT
180 Vlog::set_attr(Mword, Syscall_frame const *, Utcb const *u)
182 _i_flags = u->values[1];
183 _o_flags = u->values[2];
184 _l_flags = u->values[3];
185 Vkey::set_echo((!(_l_flags & F_ECHO))
187 : (_o_flags & F_OCRNL
191 return commit_result(0);
194 PRIVATE inline NOEXPORT
196 Vlog::get_attr(Mword, Syscall_frame *, Utcb *u)
198 if (!have_receive(u))
199 return commit_result(0);
201 u->values[1] = _i_flags;
202 u->values[2] = _o_flags;
203 u->values[3] = _l_flags;
204 return commit_result(0, 4);
209 Vlog::icu_get_irq(unsigned irqnum)
220 Vlog::icu_get_info(Mword *features, Mword *num_irqs, Mword *num_msis)
222 *features = 0; // supported features (only normal irqs)
230 Vlog::kinvoke(L4_obj_ref ref, Mword rights, Syscall_frame *f,
231 Utcb const *r_msg, Utcb *s_msg)
233 L4_msg_tag const t = f->tag();
235 if (t.proto() == L4_msg_tag::Label_irq)
236 return Icu_h<Vlog>::icu_invoke(ref, rights, f, r_msg, s_msg);
237 else if (t.proto() != L4_msg_tag::Label_log)
238 return commit_result(-L4_err::EBadproto);
240 switch (r_msg->values[0])
243 log_string(f, r_msg);
247 return set_attr(rights, f, r_msg);
250 return get_attr(rights, f, s_msg);
253 return get_input(rights, f, s_msg);