X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/1375eb51603466b723ab7dd1ca4194ee5d662f75..9209afa5f69cffa48a04c4a9066357d5cba75926:/lunaix-os/hal/term/lcntls/lcntl.c diff --git a/lunaix-os/hal/term/lcntls/lcntl.c b/lunaix-os/hal/term/lcntls/lcntl.c index aab02c0..db146e1 100644 --- a/lunaix-os/hal/term/lcntls/lcntl.c +++ b/lunaix-os/hal/term/lcntls/lcntl.c @@ -17,7 +17,7 @@ static inline void raise_sig(struct term* at_term, struct linebuffer* lbuf, int sig) { - term_sendsig(at_term, SIGINT); + term_sendsig(at_term, sig); lbuf->sflags |= LSTATE_SIGRAISE; } @@ -32,7 +32,6 @@ lcntl_transform_seq(struct term* tdev, struct linebuffer* lbuf, bool out) _lf = tdev->lflags; int allow_more = 1, latest_eol = cooked->ptr; char c; - bool should_flush = false; int (*lcntl_slave_put)(struct term*, struct linebuffer*, char) = tdev->lcntl->process_and_put; @@ -45,6 +44,13 @@ lcntl_transform_seq(struct term* tdev, struct linebuffer* lbuf, bool out) #define QUIT tdev->cc[_VQUIT] #define SUSP tdev->cc[_VSUSP] +#define putc_safe(rb, chr) \ + ({ \ + if (!rbuffer_put_nof(rb, chr)) { \ + break; \ + } \ + }) + if (!out) { // Keep all cc's (except VMIN & VTIME) up to L2 cache. for (size_t i = 0; i < _VMIN; i++) { @@ -52,25 +58,25 @@ lcntl_transform_seq(struct term* tdev, struct linebuffer* lbuf, bool out) } } - while (rbuffer_get(raw, &c) && allow_more) { + while (allow_more && rbuffer_get(raw, &c)) { if (c == '\r' && ((_if & _ICRNL) || (_of & _OCRNL))) { c = '\n'; } else if (c == '\n') { - if ((_if & _INLCR) || (_of & (_ONLRET | _ONLCR))) { + if ((_if & _INLCR) || (_of & (_ONLRET))) { c = '\r'; } } if (c == '\0') { + if ((_if & _IGNBRK)) { + continue; + } + if ((_if & _BRKINT)) { raise_sig(tdev, lbuf, SIGINT); break; } - - if ((_if & _IGNBRK)) { - continue; - } } if ('a' <= c && c <= 'z') { @@ -81,23 +87,21 @@ lcntl_transform_seq(struct term* tdev, struct linebuffer* lbuf, bool out) } } + if (out) { + goto do_out; + } + if (c == '\n') { latest_eol = cooked->ptr + 1; - if (!out && (_lf & _ECHONL)) { + if ((_lf & _ECHONL)) { rbuffer_put(output, c); } - should_flush = true; - } - - if (out) { - goto put_char; } // For input procesing if (c == '\n' || c == EOL) { lbuf->sflags |= LSTATE_EOL; - goto keep; } else if (c == EOF) { lbuf->sflags |= LSTATE_EOF; rbuffer_clear(raw); @@ -110,36 +114,47 @@ lcntl_transform_seq(struct term* tdev, struct linebuffer* lbuf, bool out) } else if (c == SUSP) { raise_sig(tdev, lbuf, SIGSTOP); } else if (c == ERASE) { - rbuffer_erase(cooked); + if (!rbuffer_erase(cooked)) + continue; } else if (c == KILL) { // TODO shrink the rbuffer } else { goto keep; } + if ((_lf & _ECHOE) && c == ERASE) { + rbuffer_put(output, '\x8'); + rbuffer_put(output, ' '); + rbuffer_put(output, '\x8'); + } + if ((_lf & _ECHOK) && c == KILL) { + rbuffer_put(output, c); + rbuffer_put(output, '\n'); + } + continue; keep: if ((_lf & _ECHO)) { rbuffer_put(output, c); } - if ((_lf & _ECHOE) && c == ERASE) { - rbuffer_erase(output); - } - if ((_lf & _ECHOK) && c == KILL) { - rbuffer_put(output, c); - rbuffer_put(output, '\n'); + + goto put_char; + + do_out: + if (c == '\n' && (_of & _ONLCR)) { + putc_safe(cooked, '\r'); } put_char: if (!out && (_lf & _IEXTEN) && lcntl_slave_put) { allow_more = lcntl_slave_put(tdev, lbuf, c); } else { - allow_more = rbuffer_put(cooked, c); + allow_more = rbuffer_put_nof(cooked, c); } } - if (should_flush && !(_lf & _NOFLSH)) { + if (!out && !rbuffer_empty(output) && !(_lf & _NOFLSH)) { term_flush(tdev); } @@ -157,5 +172,5 @@ lcntl_transform_inseq(struct term* tdev) int lcntl_transform_outseq(struct term* tdev) { - return lcntl_transform_seq(tdev, &tdev->line_in, true); + return lcntl_transform_seq(tdev, &tdev->line_out, true); } \ No newline at end of file