* Make the ksym table built-in with kernel image, thus remove the need
[lunaix-os.git] / lunaix-os / hal / term / lcntls / lcntl.c
index fdaf244275811feb83a4e5b876cefa199b72602f..db146e1d84de8f915469dd184a658e47d2276ccf 100644 (file)
@@ -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;
 }
 
@@ -44,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++) {
@@ -51,7 +58,7 @@ 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';
@@ -80,17 +87,17 @@ 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);
             }
         }
 
-        if (out) {
-            goto do_out;
-        }
-
         // For input procesing
 
         if (c == '\n' || c == EOL) {
@@ -107,7 +114,8 @@ 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 {
@@ -135,18 +143,18 @@ lcntl_transform_seq(struct term* tdev, struct linebuffer* lbuf, bool out)
 
     do_out:
         if (c == '\n' && (_of & _ONLCR)) {
-            rbuffer_put(cooked, '\r');
+            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 (!rbuffer_empty(output) && !(_lf & _NOFLSH)) {
+    if (!out && !rbuffer_empty(output) && !(_lf & _NOFLSH)) {
         term_flush(tdev);
     }