3 #include <lunaix/clock.h>
4 #include <lunaix/sched.h>
6 #include <usr/lunaix/term.h>
8 #define ONBREAK (LSTATE_EOF | LSTATE_SIGRAISE)
9 #define ONSTOP (LSTATE_SIGRAISE | LSTATE_EOL | LSTATE_EOF)
12 do_read_raw(struct term* tdev)
14 struct device* chdev = tdev->chdev;
16 struct linebuffer* line_in = &tdev->line_in;
17 size_t max_lb_sz = line_in->sz_hlf;
21 char* inbuffer = line_in->current->buffer;
22 size_t min = tdev->cc[_VMIN] - 1;
23 size_t sz = chdev->ops.read_async(chdev, inbuffer, 0, max_lb_sz);
24 time_t t = clock_systime(), dt = 0;
25 time_t expr = (tdev->cc[_VTIME] * 100) - 1;
27 while (sz <= min && dt <= expr) {
28 // XXX should we held the device lock while we are waiting?
30 dt = clock_systime() - t;
35 // TODO pass a flags to read to indicate it is non blocking ops
36 sz += chdev->ops.read_async(chdev, &inbuffer[sz], 0, max_lb_sz);
39 rbuffer_puts(line_in->next, inbuffer, sz);
46 do_read_raw_canno(struct term* tdev)
48 struct device* chdev = tdev->chdev;
49 struct linebuffer* line_in = &tdev->line_in;
50 struct rbuffer* current_buf = line_in->current;
51 int sz = chdev->ops.read(chdev, current_buf->buffer, 0, line_in->sz_hlf);
53 current_buf->ptr = sz;
54 current_buf->len = sz;
60 term_read_noncano(struct term* tdev)
62 struct device* chdev = tdev->chdev;
63 return do_read_raw(tdev);
67 term_read_cano(struct term* tdev)
69 struct device* chdev = tdev->chdev;
70 struct linebuffer* line_in = &tdev->line_in;
73 while (!(line_in->sflags & ONSTOP)) {
74 // move all hold-out content to 'next' buffer
77 size += do_read_raw_canno(tdev);
78 lcntl_transform_inseq(tdev);
85 term_read(struct term* tdev)
87 if ((tdev->lflags & _ICANON)) {
88 return term_read_cano(tdev);
90 return term_read_noncano(tdev);
94 term_flush(struct term* tdev)
96 struct linebuffer* line_out = &tdev->line_out;
97 char* xmit_buf = tdev->scratch_pad;
98 lbuf_ref_t current_ref = ref_current(line_out);
102 while (!rbuffer_empty(deref(current_ref))) {
103 if ((tdev->oflags & _OPOST)) {
104 lcntl_transform_outseq(tdev);
107 size_t xmit_len = line_out->current->len;
109 rbuffer_gets(line_out->current, xmit_buf, xmit_len);
113 while (xmit_len && ret >= 0) {
114 ret = tdev->chdev->ops.write(tdev->chdev, &xmit_buf[off], 0, xmit_len);
120 // put back the left over if transmittion went south
121 rbuffer_puts(line_out->current, xmit_buf, xmit_len);