3 #include <lunaix/clock.h>
4 #include <lunaix/kpreempt.h>
6 #include <usr/lunaix/term.h>
8 #define ONBREAK (LEVT_EOF | LEVT_SIGRAISE)
9 #define ONSTOP (LEVT_SIGRAISE | LEVT_EOL | LEVT_EOF)
12 do_read_raw(struct term* tdev)
14 struct linebuffer* line_in;
15 lbuf_ref_t current_buf;
17 time_t t, expr, dt = 0;
19 line_in = &tdev->line_in;
20 current_buf = ref_current(line_in);
22 min = tdev->cc[_VMIN] - 1;
24 expr = (tdev->cc[_VTIME] * 100) - 1;
26 min = MIN(min, (size_t)line_in->sz_hlf);
27 while (sz <= min && dt <= expr) {
28 // XXX should we held the device lock while we are waiting?
30 dt = clock_systime() - t;
33 sz = deref(current_buf)->len;
40 term_read_cano(struct term* tdev)
42 struct linebuffer* line_in;
44 line_in = &tdev->line_in;
45 while (!(line_in->sflags & ONSTOP)) {
46 pwait(&tdev->line_in_event);
53 term_read(struct term* tdev)
55 if ((tdev->lflags & _ICANON)) {
56 return term_read_cano(tdev);
59 return do_read_raw(tdev);
63 term_flush(struct term* tdev)
65 struct device* chardev;
66 struct linebuffer* line_out = &tdev->line_out;
67 char* xmit_buf = tdev->scratch_pad;
68 lbuf_ref_t current_ref = ref_current(line_out);
72 chardev = tdev->chdev;
74 while (!rbuffer_empty(deref(current_ref))) {
75 if ((tdev->oflags & _OPOST)) {
76 lcntl_transform_outseq(tdev);
79 size_t xmit_len = line_out->current->len;
81 rbuffer_gets(line_out->current, xmit_buf, xmit_len);
85 while (xmit_len && ret >= 0) {
86 ret = chardev->ops.write(chardev, &xmit_buf[off], 0, xmit_len);
92 // put back the left over if transmittion went south
93 rbuffer_puts(line_out->current, xmit_buf, xmit_len);
102 term_notify_data_avaliable(struct termport_capability* cap)
105 struct device* term_chrdev;
106 struct linebuffer* line_in;
107 lbuf_ref_t current_ref;
112 term_chrdev = term->chdev;
113 line_in = &term->line_in;
114 current_ref = ref_current(line_in);
116 // make room for current buf
118 buf = deref(current_ref)->buffer;
120 sz = term_chrdev->ops.read_async(term_chrdev, buf, 0, line_in->sz_hlf);
121 rbuffer_setcontent(deref(current_ref), sz);
123 if ((term->lflags & _ICANON)) {
124 lcntl_transform_inseq(term);
125 // write all processed to next, and flip back to current
128 pwake_all(&term->line_in_event);