Browse Source

It's possible to set parent_context and parent_exec to context structure

Serj Kalichev 5 months ago
parent
commit
0c3a867be0

+ 13 - 0
klish/kcontext.h

@@ -51,6 +51,11 @@ const kcontext_t *kcontext_parent_context(const kcontext_t *context);
 FAUX_HIDDEN bool_t kcontext_set_parent_context(kcontext_t *context,
 	const kcontext_t *parent_context);
 
+// Parent exec object
+const kexec_t *kcontext_parent_exec(const kcontext_t *context);
+FAUX_HIDDEN bool_t kcontext_set_parent_exec(kcontext_t *context,
+	const kexec_t *parent_exec);
+
 // Action iterator
 faux_list_node_t *kcontext_action_iter(const kcontext_t *context);
 FAUX_HIDDEN bool_t kcontext_set_action_iter(kcontext_t *context, faux_list_node_t *action_iter);
@@ -79,6 +84,14 @@ FAUX_HIDDEN bool_t kcontext_set_session(kcontext_t *context, ksession_t *session
 bool_t kcontext_done(const kcontext_t *context);
 FAUX_HIDDEN bool_t kcontext_set_done(kcontext_t *context, bool_t done);
 
+// Line
+const char *kcontext_line(const kcontext_t *exec);
+bool_t kcontext_set_line(kcontext_t *exec, const char *line);
+
+// Pipeline stage
+size_t kcontext_pipeline_stage(const kcontext_t *context);
+FAUX_HIDDEN bool_t kcontext_set_pipeline_stage(kcontext_t *context, size_t pipeline_stage);
+
 // Wrappers
 kparg_t *kcontext_candidate_parg(const kcontext_t *context);
 const kentry_t *kcontext_candidate_entry(const kcontext_t *context);

+ 1 - 0
klish/kcontext_base.h

@@ -9,6 +9,7 @@
 #include <faux/faux.h>
 
 typedef struct kcontext_s kcontext_t;
+typedef struct kexec_s kexec_t; // To use with context structure
 
 typedef enum {
 	KCONTEXT_TYPE_NONE,

+ 3 - 0
klish/kexec.h

@@ -47,6 +47,9 @@ bool_t kexec_done(const kexec_t *exec);
 bool_t kexec_retcode(const kexec_t *exec, int *status);
 // Saved path
 kpath_t *kexec_saved_path(const kexec_t *exec);
+// Line
+const char *kexec_line(const kexec_t *exec);
+bool_t kexec_set_line(kexec_t *exec, const char *line);
 
 // CONTEXTs
 bool_t kexec_add_contexts(kexec_t *exec, kcontext_t *context);

+ 21 - 0
klish/ksession/kcontext.c

@@ -15,6 +15,7 @@
 #include <klish/ksession.h>
 #include <klish/kaction.h>
 #include <klish/kscheme.h>
+#include <klish/kexec.h>
 
 
 struct kcontext_s {
@@ -26,6 +27,7 @@ struct kcontext_s {
 	kpargv_t *pargv;
 	const kpargv_t *parent_pargv; // Parent
 	const kcontext_t *parent_context; // Parent context (if available)
+	const kexec_t *parent_exec; // Parent exec (if available)
 	faux_list_node_t *action_iter; // Current action
 	ksym_t *sym;
 	int stdin;
@@ -33,6 +35,8 @@ struct kcontext_s {
 	int stderr;
 	pid_t pid;
 	bool_t done; // If all actions are done
+	char *line; // Text command context belong to
+	size_t pipeline_stage; // Index of current command within full pipeline
 };
 
 
@@ -69,6 +73,10 @@ FAUX_HIDDEN KSET(context, const kpargv_t *, parent_pargv);
 KGET(context, const kcontext_t *, parent_context);
 FAUX_HIDDEN KSET(context, const kcontext_t *, parent_context);
 
+// Parent exec
+KGET(context, const kexec_t *, parent_exec);
+FAUX_HIDDEN KSET(context, const kexec_t *, parent_exec);
+
 // Action iterator
 KGET(context, faux_list_node_t *, action_iter);
 FAUX_HIDDEN KSET(context, faux_list_node_t *, action_iter);
@@ -97,6 +105,14 @@ FAUX_HIDDEN KSET(context, ksession_t *, session);
 KGET_BOOL(context, done);
 FAUX_HIDDEN KSET_BOOL(context, done);
 
+// Line
+KGET_STR(context, line);
+FAUX_HIDDEN KSET_STR(context, line);
+
+// Pipeline stage
+KGET(context, size_t, pipeline_stage);
+FAUX_HIDDEN KSET(context, size_t, pipeline_stage);
+
 
 kcontext_t *kcontext_new(kcontext_type_e type)
 {
@@ -115,6 +131,7 @@ kcontext_t *kcontext_new(kcontext_type_e type)
 	context->pargv = NULL;
 	context->parent_pargv = NULL; // Don't free
 	context->parent_context = NULL; // Don't free
+	context->parent_exec = NULL; // Don't free
 	context->action_iter = NULL;
 	context->sym = NULL;
 	context->stdin = -1;
@@ -123,6 +140,8 @@ kcontext_t *kcontext_new(kcontext_type_e type)
 	context->pid = -1; // PID of currently executed ACTION
 	context->session = NULL; // Don't free
 	context->done = BOOL_FALSE;
+	context->line = NULL;
+	context->pipeline_stage = 0;
 
 	return context;
 }
@@ -142,6 +161,8 @@ void kcontext_free(kcontext_t *context)
 	if (context->stderr != -1)
 		close(context->stderr);
 
+	faux_str_free(context->line);
+
 	faux_free(context);
 }
 

+ 7 - 0
klish/ksession/kexec.c

@@ -44,6 +44,7 @@ struct kexec_s {
 	kpath_t *saved_path;
 	char *pts_fname; // Pseudoterminal slave file name
 	int pts; // Pseudoterminal slave handler
+	char *line; // Full command to execute (text)
 };
 
 // Dry-run
@@ -77,6 +78,10 @@ KSET(exec, faux_buf_t *, buferr);
 // Saved path
 KGET(exec, kpath_t *, saved_path);
 
+// Line
+KGET_STR(exec, line);
+KSET_STR(exec, line);
+
 // CONTEXT list
 KADD_NESTED(exec, kcontext_t *, contexts);
 KNESTED_LEN(exec, contexts);
@@ -108,6 +113,7 @@ kexec_t *kexec_new(ksession_t *session, kcontext_type_e type)
 	exec->session = session;
 	exec->dry_run = BOOL_FALSE;
 	exec->saved_path = NULL;
+	exec->line = NULL;
 
 	// List of execute contexts
 	exec->contexts = faux_list_new(FAUX_LIST_UNSORTED, FAUX_LIST_NONUNIQUE,
@@ -150,6 +156,7 @@ void kexec_free(kexec_t *exec)
 	faux_buf_free(exec->buferr);
 
 	faux_str_free(exec->pts_fname);
+	faux_str_free(exec->line);
 
 	kpath_free(exec->saved_path);
 

+ 11 - 4
klish/ksession/ksession_parse.c

@@ -45,7 +45,7 @@ static bool_t ksession_validate_arg(ksession_t *session, kpargv_t *pargv)
 	if (!ptype_entry)
 		return BOOL_FALSE;
 
-	if (!ksession_exec_locally(session, ptype_entry, pargv, NULL,
+	if (!ksession_exec_locally(session, ptype_entry, pargv, NULL, NULL,
 		&retcode, &out)) {
 		return BOOL_FALSE;
 	}
@@ -580,6 +580,7 @@ kexec_t *ksession_parse_for_exec(ksession_t *session, const char *raw_line,
 	kpargv_t *pargv = NULL;
 	kexec_t *exec = NULL;
 	bool_t is_piped = BOOL_FALSE;
+	size_t index = 0;
 
 	assert(session);
 	if (!session)
@@ -603,6 +604,7 @@ kexec_t *ksession_parse_for_exec(ksession_t *session, const char *raw_line,
 		faux_list_free(split);
 		return NULL;
 	}
+	kexec_set_line(exec, raw_line);
 
 	iter = faux_list_head(split);
 	while (iter) {
@@ -626,10 +628,13 @@ kexec_t *ksession_parse_for_exec(ksession_t *session, const char *raw_line,
 		kcontext_set_pargv(context, pargv);
 		// Context for ACTION execution contains session
 		kcontext_set_session(context, session);
+		kcontext_set_line(context, faux_argv_line(argv));
+		kcontext_set_pipeline_stage(context, index);
 		kexec_add_contexts(exec, context);
 
 		// Next component
 		iter = faux_list_next_node(iter);
+		index++;
 	}
 
 	faux_list_free(split);
@@ -639,7 +644,8 @@ kexec_t *ksession_parse_for_exec(ksession_t *session, const char *raw_line,
 
 
 kexec_t *ksession_parse_for_local_exec(ksession_t *session, const kentry_t *entry,
-	const kpargv_t *parent_pargv, const kcontext_t *parent_context)
+	const kpargv_t *parent_pargv, const kcontext_t *parent_context,
+	const kexec_t *parent_exec)
 {
 	faux_argv_node_t *argv_iter = NULL;
 	kpargv_t *pargv = NULL;
@@ -685,6 +691,7 @@ kexec_t *ksession_parse_for_local_exec(ksession_t *session, const kentry_t *entr
 	kcontext_set_pargv(context, pargv);
 	kcontext_set_parent_pargv(context, parent_pargv);
 	kcontext_set_parent_context(context, parent_context);
+	kcontext_set_parent_exec(context, parent_exec);
 	kcontext_set_session(context, session);
 	kexec_add_contexts(exec, context);
 
@@ -790,7 +797,7 @@ static bool_t action_stdout_ev(faux_eloop_t *eloop, faux_eloop_type_e type,
 
 bool_t ksession_exec_locally(ksession_t *session, const kentry_t *entry,
 	kpargv_t *parent_pargv, const kcontext_t *parent_context,
-	int *retcode, char **out)
+	const kexec_t *parent_exec, int *retcode, char **out)
 {
 	kexec_t *exec = NULL;
 	faux_eloop_t *eloop = NULL;
@@ -804,7 +811,7 @@ bool_t ksession_exec_locally(ksession_t *session, const kentry_t *entry,
 
 	// Parsing
 	exec = ksession_parse_for_local_exec(session, entry,
-		parent_pargv, parent_context);
+		parent_pargv, parent_context, parent_exec);
 	if (!exec)
 		return BOOL_FALSE;
 

+ 3 - 2
klish/ksession_parse.h

@@ -21,10 +21,11 @@ kpargv_t *ksession_parse_for_completion(ksession_t *session,
 kexec_t *ksession_parse_for_exec(ksession_t *session, const char *raw_line,
 	faux_error_t *error);
 kexec_t *ksession_parse_for_local_exec(ksession_t *session, const kentry_t *entry,
-	const kpargv_t *parent_pargv, const kcontext_t *parent_context);
+	const kpargv_t *parent_pargv, const kcontext_t *parent_context,
+	const kexec_t *parent_exec);
 bool_t ksession_exec_locally(ksession_t *session, const kentry_t *entry,
 	kpargv_t *parent_pargv, const kcontext_t *parent_context,
-	int *retcode, char **out);
+	const kexec_t *parent_exec, int *retcode, char **out);
 
 C_DECL_END
 

+ 17 - 3
klish/ktp/ktpd_session.c

@@ -55,6 +55,7 @@ static bool_t wait_for_actions_ev(faux_eloop_t *eloop, faux_eloop_type_e type,
 	void *associated_data, void *user_data);
 bool_t client_ev(faux_eloop_t *eloop, faux_eloop_type_e type,
 	void *associated_data, void *user_data);
+static bool_t ktpd_session_log(ktpd_session_t *ktpd, const kexec_t *exec);
 static bool_t ktpd_session_exec(ktpd_session_t *ktpd, const char *line,
 	int *retcode, faux_error_t *error,
 	bool_t dry_run, bool_t *view_was_changed);
@@ -167,7 +168,7 @@ static char *generate_prompt(ktpd_session_t *ktpd)
 			bool_t res = BOOL_FALSE;
 
 			res = ksession_exec_locally(ktpd->session,
-				prompt_entry, NULL, NULL, &rc, &prompt);
+				prompt_entry, NULL, NULL, NULL, &rc, &prompt);
 			if (!res || (rc < 0) || !prompt) {
 				if (prompt)
 					faux_str_free(prompt);
@@ -459,6 +460,7 @@ static bool_t ktpd_session_exec(ktpd_session_t *ktpd, const char *line,
 			*view_was_changed_p = !kpath_is_equal(
 				ksession_path(ktpd->session),
 				kexec_saved_path(exec));
+		ktpd_session_log(ktpd, exec);
 		kexec_free(exec);
 		return BOOL_TRUE;
 	}
@@ -521,6 +523,7 @@ static bool_t wait_for_actions_ev(faux_eloop_t *eloop, faux_eloop_type_e type,
 	faux_eloop_del_fd(eloop, kexec_stdout(ktpd->exec));
 	faux_eloop_del_fd(eloop, kexec_stderr(ktpd->exec));
 
+	ktpd_session_log(ktpd, ktpd->exec);
 	view_was_changed = !kpath_is_equal(
 		ksession_path(ktpd->session), kexec_saved_path(ktpd->exec));
 
@@ -560,6 +563,17 @@ static bool_t wait_for_actions_ev(faux_eloop_t *eloop, faux_eloop_type_e type,
 }
 
 
+static bool_t ktpd_session_log(ktpd_session_t *ktpd, const kexec_t *exec)
+{
+	fprintf(stderr, "LOG\n");
+
+	ktpd = ktpd;
+	exec = exec;
+
+	return BOOL_TRUE;
+}
+
+
 static int compl_compare(const void *first, const void *second)
 {
 	const char *f = (const char *)first;
@@ -660,7 +674,7 @@ static bool_t ktpd_session_process_completion(ktpd_session_t *ktpd, faux_msg_t *
 			parg = kparg_new(candidate, prefix);
 			kpargv_set_candidate_parg(pargv, parg);
 			res = ksession_exec_locally(ktpd->session, completion,
-				pargv, NULL, &rc, &out);
+				pargv, NULL, NULL, &rc, &out);
 			kparg_free(parg);
 			if (!res || (rc < 0) || !out) {
 				if (out)
@@ -797,7 +811,7 @@ static bool_t ktpd_session_process_help(ktpd_session_t *ktpd, faux_msg_t *msg)
 				parg = kparg_new(candidate, prefix);
 				kpargv_set_candidate_parg(pargv, parg);
 				ksession_exec_locally(ktpd->session,
-					help, pargv, NULL, &rc, &out);
+					help, pargv, NULL, NULL, &rc, &out);
 				kparg_free(parg);
 
 				if (out) {