From f7319b36f4f48cdf065b9a1472c9a848ca6f95bc Mon Sep 17 00:00:00 2001 From: _ov4 Date: Sun, 18 Oct 2026 14:57:06 +0000 Subject: adapt self pipe --- include/line/line_editor.h | 2 +- include/pipe.h | 5 +++++ include/util/non_block_input.h | 2 +- src/line/cursor.cc | 1 + src/line/input.cc | 12 +++++++++-- src/pipe.cc | 32 +++++++++++++++++++++++++++ src/self_pipe.cc | 21 ------------------ src/signal/sigwinch_handler.cc | 2 +- src/util/non_block_input.cc | 49 ++++++++++++++++++++++++++++++++++++++++++ src/util/non_block_io.cc | 49 ------------------------------------------ 10 files changed, 100 insertions(+), 75 deletions(-) create mode 100644 src/pipe.cc delete mode 100644 src/self_pipe.cc create mode 100644 src/util/non_block_input.cc delete mode 100644 src/util/non_block_io.cc diff --git a/include/line/line_editor.h b/include/line/line_editor.h index a97b09c..8fa3841 100644 --- a/include/line/line_editor.h +++ b/include/line/line_editor.h @@ -15,6 +15,7 @@ inline bool raw_enabled = false; void disable_raw(); void enable_raw(); void editor_exit(int code); +inline bool windows_size_changed = false; class T_line_editor { @@ -49,7 +50,6 @@ public: // getter - bool windows_size_changed = false; int get_terminal_pos_cursor(); int get_buffer_index_display_begin(); diff --git a/include/pipe.h b/include/pipe.h index e7d7b67..157063d 100644 --- a/include/pipe.h +++ b/include/pipe.h @@ -6,4 +6,9 @@ namespace ov4 inline int self_pipe_fd[2] = {-1, -1}; +constexpr unsigned char SELF_PIPE_BYTE = 1; + +void self_pipe_init(); +int self_pipe_write(); + } \ No newline at end of file diff --git a/include/util/non_block_input.h b/include/util/non_block_input.h index f5937a7..83e8809 100644 --- a/include/util/non_block_input.h +++ b/include/util/non_block_input.h @@ -1,6 +1,6 @@ #pragma once -namespace pv4 +namespace ov4 { int non_block_read_char(char *c, int *src = nullptr); diff --git a/src/line/cursor.cc b/src/line/cursor.cc index 81454ae..1baa33c 100644 --- a/src/line/cursor.cc +++ b/src/line/cursor.cc @@ -228,6 +228,7 @@ void T_line_editor::check_window_update() { update_window_size(); clear_below(); + print_override(line_buffer); windows_size_changed = false; } } diff --git a/src/line/input.cc b/src/line/input.cc index b7dbc23..1e7ca38 100644 --- a/src/line/input.cc +++ b/src/line/input.cc @@ -5,6 +5,8 @@ #include #include "history.h" +#include "util/non_block_input.h" +#include "pipe.h" using namespace std; @@ -25,9 +27,15 @@ string T_line_editor::readline() T_position pos = get_cursor_position(); prompt_pos = pos.col; - char c; - while (read(STDIN_FILENO, &c, 1) == 1) + char c; int src; + while (non_block_read_char(&c, &src) == 1) { + // if signal'd + if (src == self_pipe_fd[0]) + { + check_window_update(); + break; + } if (iscntrl(c)) { //print("control: {}\r\n", static_cast(c)); diff --git a/src/pipe.cc b/src/pipe.cc new file mode 100644 index 0000000..5baaeae --- /dev/null +++ b/src/pipe.cc @@ -0,0 +1,32 @@ +#include "pipe.h" + +#include +#include +#include + +#include "error.h" + +namespace ov4 +{ + +void self_pipe_init() +{ + int ret = pipe2(self_pipe_fd, O_NONBLOCK); + if (ret != 0) + { + throw T_error(error_code::FAIL_TO_OPEN_PIPE, "Fail to open self pipe"); + } +} + +/* + * write a byte to self pipe + * NB: you can ONLY determine that signal handler was called + * but CANNOT determine the number of callings, or which signal was called + * because when the pipe is full, nothing will be written + */ +int self_pipe_write() +{ + return write(self_pipe_fd[1], &SELF_PIPE_BYTE, 1); +} + +} \ No newline at end of file diff --git a/src/self_pipe.cc b/src/self_pipe.cc deleted file mode 100644 index 42e61d8..0000000 --- a/src/self_pipe.cc +++ /dev/null @@ -1,21 +0,0 @@ -#include "pipe.h" - -#include -#include -#include - -#include "error.h" - -namespace ov4 -{ - -void self_pipe_init() -{ - int ret = pipe2(self_pipe_fd, O_NONBLOCK); - if (ret != 0) - { - throw T_error(error_code::FAIL_TO_OPEN_PIPE, "Fail to open self pipe"); - } -} - -} \ No newline at end of file diff --git a/src/signal/sigwinch_handler.cc b/src/signal/sigwinch_handler.cc index 4b692ed..20d4550 100644 --- a/src/signal/sigwinch_handler.cc +++ b/src/signal/sigwinch_handler.cc @@ -1,6 +1,6 @@ #include "signal_handler.h" -#include "line/getter.h" +#include "line/line_editor.h" namespace ov4 { diff --git a/src/util/non_block_input.cc b/src/util/non_block_input.cc new file mode 100644 index 0000000..a17daf2 --- /dev/null +++ b/src/util/non_block_input.cc @@ -0,0 +1,49 @@ +#include "util/non_block_input.h" + +#include +#include + +#include "pipe.h" + +using namespace std; + +namespace ov4 +{ + + +/* + * read from both stdin, and self pipe + * returns immediately as soon as stdin or pipe is "readable" + * returns read()'s ret value + * and set src to the the read source (stdin or pipe) + */ +int non_block_read_char(char *c, int *src) +{ + // get fd check range + int max_fd; + if (STDIN_FILENO > self_pipe_fd[0]) max_fd = STDIN_FILENO; + else max_fd = self_pipe_fd[0]; + + // monitor STDIN, and self pipe + fd_set rset; + FD_ZERO(&rset); + FD_SET(STDIN_FILENO, &rset); + FD_SET(self_pipe_fd[0], &rset); + + select(max_fd+1, &rset, nullptr, nullptr, nullptr); + + int ret = -1; + if (FD_ISSET(self_pipe_fd[0], &rset)) + { + ret = read(self_pipe_fd[0], c, 1); + if (src != nullptr) *src = self_pipe_fd[0]; + } + else if (FD_ISSET(STDIN_FILENO, &rset)) + { + ret = read(STDIN_FILENO, c, 1); + if (src != nullptr) *src = STDIN_FILENO; + } + return ret; +} + +} \ No newline at end of file diff --git a/src/util/non_block_io.cc b/src/util/non_block_io.cc deleted file mode 100644 index 31edbc9..0000000 --- a/src/util/non_block_io.cc +++ /dev/null @@ -1,49 +0,0 @@ -#include "util/non_block_input.h" - -#include -#include - -#include "pipe.h" - -using namespace std; - -namespace ov4 -{ - - -/* - * read from both stdin, and self pipe - * returns immediately as soon as stdin or pipe is "readable" - * returns read()'s ret value - * and set src to the the read source (stdin or pipe) - */ -int non_block_read_char(char *c, int *src) -{ - // get fd check range - int max_fd; - if (STDIN_FILENO > self_pipe_fd[0]) max_fd = STDIN_FILENO; - else max_fd = self_pipe_fd[0]; - - // monitor STDIN, and self pipe - fd_set rset; - FD_ZERO(&rset); - FD_SET(STDIN_FILENO, &rset); - FD_SET(self_pipe_fd[0], &rset); - - select(max_fd+1, &rset, nullptr, nullptr, nullptr); - - int ret = -1; - if (FD_ISSET(self_pipe_fd[0], &rset)) - { - ret = read(self_pipe_fd[0], c, 1); - if (src != nullptr) *src = self_pipe_fd[0]; - } - else if (FD_ISSET(STDIN_FILENO, &rset)) - { - ret = read(STDIN_FILENO, c, 1); - if (src != nullptr) *src = self_pipe_fd[0]; - } - return ret; -} - -} \ No newline at end of file -- cgit v1.3.1-4-g156e