Browse Source

Ctrl_c for non interactive commands. Not works yet

Serj Kalichev 6 months ago
parent
commit
131f70ce5c
3 changed files with 91 additions and 11 deletions
  1. 43 5
      bin/klish/interactive.c
  2. 4 2
      tinyrl/tinyrl.h
  3. 44 4
      tinyrl/tinyrl/tinyrl.c

+ 43 - 5
bin/klish/interactive.c

@@ -44,6 +44,8 @@ static bool_t stdin_cb(faux_eloop_t *eloop, faux_eloop_type_e type,
 	void *associated_data, void *user_data);
 static bool_t sigwinch_cb(faux_eloop_t *eloop, faux_eloop_type_e type,
 	void *associated_data, void *user_data);
+static bool_t ctrl_c_cb(faux_eloop_t *eloop, faux_eloop_type_e type,
+	void *associated_data, void *user_data);
 
 static void reset_hotkey_table(ctx_t *ctx);
 static bool_t interactive_stdout_cb(ktp_session_t *ktp, const char *line, size_t len,
@@ -119,6 +121,12 @@ int klish_interactive_shell(ktp_session_t *ktp, struct options *opts)
 
 	eloop = ktp_session_eloop(ktp);
 
+	// Reassign signal handlers. Handlers are used to send SIGINT
+	// to non-interactive commands
+	faux_eloop_add_signal(eloop, SIGINT, ctrl_c_cb, &ctx);
+	faux_eloop_add_signal(eloop, SIGTERM, ctrl_c_cb, &ctx);
+	faux_eloop_add_signal(eloop, SIGQUIT, ctrl_c_cb, &ctx);
+
 	// Notify server about terminal window size change
 	faux_eloop_add_signal(eloop, SIGWINCH, sigwinch_cb, &ctx);
 
@@ -256,6 +264,9 @@ bool_t cmd_ack_cb(ktp_session_t *ktp, const faux_msg_t *msg, void *udata)
 	int rc = -1;
 	faux_error_t *error = NULL;
 
+	// Disable SIGINT caught for non-interactive commands
+	tinyrl_disable_isig(ctx->tinyrl);
+
 	process_prompt_param(ctx->tinyrl, msg);
 	process_hotkey_param(ctx, msg);
 
@@ -296,11 +307,15 @@ bool_t cmd_incompleted_ack_cb(ktp_session_t *ktp, const faux_msg_t *msg, void *u
 {
 	ctx_t *ctx = (ctx_t *)udata;
 
-	// Interactive command. So restore stdin handler.
-	if ((ktp_session_state(ktp) == KTP_SESSION_STATE_WAIT_FOR_CMD) &&
-		KTP_STATUS_IS_INTERACTIVE(ktp_session_cmd_features(ktp))) {
-		faux_eloop_add_fd(ktp_session_eloop(ktp), STDIN_FILENO, POLLIN,
-			stdin_cb, ctx);
+	if (ktp_session_state(ktp) == KTP_SESSION_STATE_WAIT_FOR_CMD) {
+		// Interactive command. So restore stdin handler.
+		if (KTP_STATUS_IS_INTERACTIVE(ktp_session_cmd_features(ktp))) {
+			// Disable SIGINT signal
+			tinyrl_disable_isig(ctx->tinyrl);
+			// Interactive command. So restore stdin handler.
+			faux_eloop_add_fd(ktp_session_eloop(ktp), STDIN_FILENO, POLLIN,
+				stdin_cb, ctx);
+		}
 	}
 
 	// Happy compiler
@@ -406,6 +421,26 @@ static bool_t sigwinch_cb(faux_eloop_t *eloop, faux_eloop_type_e type,
 }
 
 
+static bool_t ctrl_c_cb(faux_eloop_t *eloop, faux_eloop_type_e type,
+	void *associated_data, void *udata)
+{
+	ctx_t *ctx = (ctx_t *)udata;
+	char ctrl_c = KEY_ETX;
+
+	if (!ctx)
+		return BOOL_FALSE;
+
+	ktp_session_stdin(ctx->ktp, &ctrl_c, sizeof(ctrl_c));
+
+	// Happy compiler
+	eloop = eloop;
+	type = type;
+	associated_data = associated_data;
+
+	return BOOL_TRUE;
+}
+
+
 static bool_t tinyrl_key_enter(tinyrl_t *tinyrl, unsigned char key)
 {
 	const char *line = NULL;
@@ -426,6 +461,9 @@ static bool_t tinyrl_key_enter(tinyrl_t *tinyrl, unsigned char key)
 
 	tinyrl_reset_line(tinyrl);
 	tinyrl_set_busy(tinyrl, BOOL_TRUE);
+	// Suppose non-interactive command
+	// Caught SIGINT for non-interactive commands
+	tinyrl_enable_isig(ctx->tinyrl);
 
 	key = key; // Happy compiler
 

+ 4 - 2
tinyrl/tinyrl.h

@@ -89,8 +89,10 @@ void tinyrl_line_to_hist(tinyrl_t *tinyrl);
 void tinyrl_reset_hist_pos(tinyrl_t *tinyrl);
 void *tinyrl_udata(const tinyrl_t *tinyrl);
 void tinyrl_set_udata(tinyrl_t *tinyrl, void *udata);
-void tty_raw_mode(tinyrl_t *tinyrl);
-void tty_restore_mode(tinyrl_t *tinyrl);
+void tinyrl_raw_mode(tinyrl_t *tinyrl);
+void tinyrl_restore_mode(tinyrl_t *tinyrl);
+void tinyrl_enable_isig(tinyrl_t *tinyrl);
+void tinyrl_disable_isig(tinyrl_t *tinyrl);
 int tinyrl_read(tinyrl_t *tinyrl);
 void tinyrl_redisplay(tinyrl_t *tinyrl);
 void tinyrl_save_last(tinyrl_t *tinyrl);

+ 44 - 4
tinyrl/tinyrl/tinyrl.c

@@ -77,7 +77,7 @@ tinyrl_t *tinyrl_new(FILE *istream, FILE *ostream,
 	tinyrl->hist = hist_new(hist_fname, hist_stifle);
 	tinyrl_hist_restore(tinyrl);
 
-	tty_raw_mode(tinyrl);
+	tinyrl_raw_mode(tinyrl);
 
 	return tinyrl;
 }
@@ -89,7 +89,7 @@ void tinyrl_free(tinyrl_t *tinyrl)
 	if (!tinyrl)
 		return;
 
-	tty_restore_mode(tinyrl);
+	tinyrl_restore_mode(tinyrl);
 
 	tinyrl_hist_save(tinyrl);
 	hist_free(tinyrl->hist);
@@ -103,7 +103,7 @@ void tinyrl_free(tinyrl_t *tinyrl)
 }
 
 
-void tty_raw_mode(tinyrl_t *tinyrl)
+void tinyrl_raw_mode(tinyrl_t *tinyrl)
 {
 	struct termios new_termios = {};
 	FILE *istream = NULL;
@@ -137,7 +137,7 @@ void tty_raw_mode(tinyrl_t *tinyrl)
 }
 
 
-void tty_restore_mode(tinyrl_t *tinyrl)
+void tinyrl_restore_mode(tinyrl_t *tinyrl)
 {
 	FILE *istream = NULL;
 	int fd = -1;
@@ -151,6 +151,46 @@ void tty_restore_mode(tinyrl_t *tinyrl)
 }
 
 
+void tinyrl_enable_isig(tinyrl_t *tinyrl)
+{
+	struct termios new_termios = {};
+	FILE *istream = NULL;
+	int fd = -1;
+
+	if (!tinyrl)
+		return;
+	istream = vt100_istream(tinyrl->term);
+	if (!istream)
+		return;
+	fd = fileno(istream);
+	if (tcgetattr(fd, &new_termios) < 0)
+		return;
+//	new_termios.c_lflag |= (ISIG | NOFLSH);
+//	new_termios.c_lflag |= (ISIG);
+	tcsetattr(fd, TCSADRAIN, &new_termios);
+}
+
+
+void tinyrl_disable_isig(tinyrl_t *tinyrl)
+{
+	struct termios new_termios = {};
+	FILE *istream = NULL;
+	int fd = -1;
+
+	if (!tinyrl)
+		return;
+	istream = vt100_istream(tinyrl->term);
+	if (!istream)
+		return;
+	fd = fileno(istream);
+	if (tcgetattr(fd, &new_termios) < 0)
+		return;
+//	new_termios.c_lflag &= ~(ISIG | NOFLSH);
+//	new_termios.c_lflag &= ~(ISIG);
+	tcsetattr(fd, TCSADRAIN, &new_termios);
+}
+
+
 bool_t tinyrl_bind_key(tinyrl_t *tinyrl, int key, tinyrl_key_func_t *fn)
 {
 	assert(tinyrl);