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(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
37 chdev->ops.read(chdev, inbuffer, sz, max_lb_sz);
40 rbuffer_puts(line_in->next, inbuffer, sz);
47 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 if ((tdev->oflags & _OPOST)) {
97 lcntl_transform_inseq(tdev);
100 struct linebuffer* line_out = &tdev->line_out;
101 size_t xmit_len = line_out->current->len;
102 void* xmit_buf = line_out->next->buffer;
104 rbuffer_gets(line_out->current, xmit_buf, xmit_len);
108 while (xmit_len && ret >= 0) {
109 ret = tdev->chdev->ops.write(tdev->chdev, xmit_buf, off, xmit_len);
114 // put back the left over if transmittion went south
115 rbuffer_puts(line_out->current, xmit_buf, xmit_len);