Browse Source

Code for unfinished completions

Serj Kalichev 1 year ago
parent
commit
237c710bf3
4 changed files with 86 additions and 5 deletions
  1. 36 3
      bin/klish/interactive.c
  2. 41 1
      klish/ktp/ktp_session.c
  3. 7 1
      klish/ktp/ktpd_session.c
  4. 2 0
      klish/ktp_session.h

+ 36 - 3
bin/klish/interactive.c

@@ -23,11 +23,13 @@ typedef struct ctx_s {
 
 
 bool_t cmd_ack_cb(ktp_session_t *ktp, const faux_msg_t *msg, void *udata);
+bool_t completion_ack_cb(ktp_session_t *ktp, const faux_msg_t *msg, void *udata);
 static bool_t stdin_cb(faux_eloop_t *eloop, faux_eloop_type_e type,
 	void *associated_data, void *user_data);
 
 // Keys
 static bool_t tinyrl_key_enter(tinyrl_t *tinyrl, unsigned char key);
+static bool_t tinyrl_key_tab(tinyrl_t *tinyrl, unsigned char key);
 
 
 int klish_interactive_shell(ktp_session_t *ktp, struct options *opts)
@@ -51,7 +53,9 @@ int klish_interactive_shell(ktp_session_t *ktp, struct options *opts)
 	faux_str_free(hist_path);
 	tinyrl_set_prompt(tinyrl, "$ ");
 	tinyrl_set_udata(tinyrl, &ctx);
-	tinyrl_bind_key(tinyrl, KEY_CR, tinyrl_key_enter);
+	tinyrl_bind_key(tinyrl, '\n', tinyrl_key_enter);
+	tinyrl_bind_key(tinyrl, '\r', tinyrl_key_enter);
+	tinyrl_bind_key(tinyrl, '\t', tinyrl_key_tab);
 	tinyrl_redisplay(tinyrl);
 
 	ctx.ktp = ktp;
@@ -61,6 +65,7 @@ int klish_interactive_shell(ktp_session_t *ktp, struct options *opts)
 	// Don't stop interactive loop on each answer
 	ktp_session_set_stop_on_answer(ktp, BOOL_FALSE);
 	ktp_session_set_cb(ktp, KTP_SESSION_CB_CMD_ACK, cmd_ack_cb, &ctx);
+	ktp_session_set_cb(ktp, KTP_SESSION_CB_COMPLETION_ACK, completion_ack_cb, &ctx);
 	eloop = ktp_session_eloop(ktp);
 	faux_eloop_add_fd(eloop, STDIN_FILENO, POLLIN, stdin_cb, &ctx);
 	faux_eloop_loop(eloop);
@@ -99,9 +104,7 @@ bool_t cmd_ack_cb(ktp_session_t *ktp, const faux_msg_t *msg, void *udata)
 		tinyrl_redisplay(ctx->tinyrl);
 
 	// Happy compiler
-	ktp = ktp;
 	msg = msg;
-	udata = udata;
 
 	return BOOL_TRUE;
 }
@@ -142,3 +145,33 @@ static bool_t tinyrl_key_enter(tinyrl_t *tinyrl, unsigned char key)
 
 	return BOOL_TRUE;
 }
+
+
+static bool_t tinyrl_key_tab(tinyrl_t *tinyrl, unsigned char key)
+{
+	const char *line = NULL;
+	ctx_t *ctx = (ctx_t *)tinyrl_udata(tinyrl);
+
+	line = tinyrl_line(tinyrl);
+	ktp_session_completion(ctx->ktp, line, ctx->opts->dry_run);
+
+	tinyrl_set_busy(tinyrl, BOOL_TRUE);
+
+	return BOOL_TRUE;
+}
+
+
+bool_t completion_ack_cb(ktp_session_t *ktp, const faux_msg_t *msg, void *udata)
+{
+	ctx_t *ctx = (ctx_t *)udata;
+
+	tinyrl_set_busy(ctx->tinyrl, BOOL_FALSE);
+
+	printf("\nCOMPLETION\n");
+
+	// Happy compiler
+	ktp = ktp;
+	msg = msg;
+
+	return BOOL_TRUE;
+}

+ 41 - 1
klish/ktp/ktp_session.c

@@ -353,7 +353,7 @@ static bool_t ktp_session_process_cmd_ack(ktp_session_t *ktp, const faux_msg_t *
 	ktp->request_done = BOOL_TRUE;
 	ktp->state = KTP_SESSION_STATE_IDLE;
 	// Get exit flag from message
-	if (KTP_STATUS_IS_EXIT(faux_msg_get_status(msg)))
+	if (KTP_STATUS_IS_EXIT(status))
 		ktp->done = BOOL_TRUE;
 
 	// Execute external callback
@@ -366,6 +366,29 @@ static bool_t ktp_session_process_cmd_ack(ktp_session_t *ktp, const faux_msg_t *
 	return BOOL_TRUE;
 }
 
+
+static bool_t ktp_session_process_completion_ack(ktp_session_t *ktp, const faux_msg_t *msg)
+{
+	assert(ktp);
+	assert(msg);
+
+	ktp->request_done = BOOL_TRUE;
+	ktp->state = KTP_SESSION_STATE_IDLE;
+	// Get exit flag from message
+	if (KTP_STATUS_IS_EXIT(faux_msg_get_status(msg)))
+		ktp->done = BOOL_TRUE;
+
+	// Execute external callback
+	if (ktp->cb[KTP_SESSION_CB_COMPLETION_ACK].fn)
+		((ktp_session_event_cb_fn)
+			ktp->cb[KTP_SESSION_CB_COMPLETION_ACK].fn)(
+			ktp, msg,
+			ktp->cb[KTP_SESSION_CB_COMPLETION_ACK].udata);
+
+	return BOOL_TRUE;
+}
+
+
 /*
 static bool_t ktp_session_process_exit(ktp_session_t *ktp, const faux_msg_t *msg)
 {
@@ -405,6 +428,13 @@ static bool_t ktp_session_dispatch(ktp_session_t *ktp, faux_msg_t *msg)
 		}
 		rc = ktp_session_process_cmd_ack(ktp, msg);
 		break;
+	case KTP_COMPLETION_ACK:
+		if (ktp->state != KTP_SESSION_STATE_WAIT_FOR_COMPLETION) {
+			syslog(LOG_WARNING, "Unexpected KTP_COMPLETION_ACK was received\n");
+			break;
+		}
+		rc = ktp_session_process_completion_ack(ktp, msg);
+		break;
 	case KTP_STDOUT:
 		if (ktp->state != KTP_SESSION_STATE_WAIT_FOR_CMD) {
 			syslog(LOG_WARNING, "Unexpected KTP_STDOUT was received\n");
@@ -539,6 +569,16 @@ bool_t ktp_session_cmd(ktp_session_t *ktp, const char *line,
 }
 
 
+bool_t ktp_session_completion(ktp_session_t *ktp, const char *line, bool_t dry_run)
+{
+	if (!ktp_session_req(ktp, KTP_COMPLETION, line, NULL, dry_run))
+		return BOOL_FALSE;
+	ktp->state = KTP_SESSION_STATE_WAIT_FOR_COMPLETION;
+
+	return BOOL_TRUE;
+}
+
+
 bool_t ktp_session_retcode(ktp_session_t *ktp, int *retcode)
 {
 	if (!ktp)

+ 7 - 1
klish/ktp/ktpd_session.c

@@ -303,6 +303,7 @@ static bool_t ktpd_session_process_completion(ktpd_session_t *ktpd, faux_msg_t *
 	faux_msg_t *ack = NULL;
 	kpargv_t *pargv = NULL;
 	ktp_cmd_e cmd = KTP_COMPLETION_ACK;
+	uint32_t status = KTP_STATUS_NONE;
 
 	assert(ktpd);
 	assert(msg);
@@ -324,8 +325,13 @@ static bool_t ktpd_session_process_completion(ktpd_session_t *ktpd, faux_msg_t *
 
 	kpargv_free(pargv);
 
+	if (ksession_done(ktpd->session)) {
+		ktpd->exit = BOOL_TRUE;
+		status |= KTP_STATUS_EXIT; // Notify client about exiting
+	}
+
 	// Send ACK message
-	ack = ktp_msg_preform(cmd, KTP_STATUS_NONE);
+	ack = ktp_msg_preform(cmd, status);
 	faux_msg_send_async(ack, ktpd->async);
 	faux_msg_free(ack);
 

+ 2 - 0
klish/ktp_session.h

@@ -77,6 +77,8 @@ ktp_session_state_e ktp_session_state(const ktp_session_t *ktp);
 
 bool_t ktp_session_cmd(ktp_session_t *ktp, const char *line,
 	faux_error_t *error, bool_t dry_run);
+bool_t ktp_session_completion(ktp_session_t *ktp, const char *line,
+	bool_t dry_run);
 bool_t ktp_session_retcode(ktp_session_t *ktp, int *retcode);