Browse Source

Implement restore=true for ENTRY

Serj Kalichev 3 months ago
parent
commit
586d8f6c64

+ 2 - 0
klish/kpath.h

@@ -36,6 +36,8 @@ bool_t kpath_pop(kpath_t *path);
 klevel_t *kpath_current(const kpath_t *path);
 kpath_levels_node_t *kpath_iterr(const kpath_t *path);
 klevel_t *kpath_eachr(kpath_levels_node_t **iterr);
+kpath_levels_node_t *kpath_iter(const kpath_t *path);
+klevel_t *kpath_each(kpath_levels_node_t **iter);
 
 C_DECL_END
 

+ 1 - 1
klish/ksession/kcontext.c

@@ -19,6 +19,7 @@
 struct kcontext_s {
 	kcontext_type_e type;
 	int retcode;
+	ksession_t *session;
 	kplugin_t *plugin;
 	kpargv_t *pargv;
 	const kpargv_t *parent_pargv; // Parent
@@ -28,7 +29,6 @@ struct kcontext_s {
 	int stdout;
 	int stderr;
 	pid_t pid;
-	ksession_t *session;
 	bool_t done; // If all actions are done
 };
 

+ 20 - 0
klish/ksession/kexec.c

@@ -547,6 +547,11 @@ bool_t kexec_continue_command_execution(kexec_t *exec, pid_t pid, int wstatus)
 
 bool_t kexec_exec(kexec_t *exec)
 {
+	kcontext_t *context = NULL;
+	const kpargv_t *pargv = NULL;
+	const kentry_t *entry = NULL;
+	bool_t restore = BOOL_FALSE;
+
 	assert(exec);
 	if (!exec)
 		return BOOL_FALSE;
@@ -556,6 +561,21 @@ bool_t kexec_exec(kexec_t *exec)
 	if (!kexec_prepare(exec))
 		return BOOL_FALSE;
 
+	// Pre-change VIEW if command has "restore" flag. Only first command in
+	// line (if many commands are piped) matters. Filters can't change the
+	// VIEW.
+	context = (kcontext_t *)faux_list_data(faux_list_head(exec->contexts));
+	pargv = kcontext_pargv(context);
+	entry = kpargv_command(pargv);
+	if (entry)
+		restore = kentry_restore(entry);
+	if (restore) {
+		size_t level = kpargv_level(pargv);
+		kpath_t *path = ksession_path(kcontext_session(context));
+		while(kpath_len(path) > (level + 1))
+			kpath_pop(path);
+	}
+
 	// Here no ACTIONs are executing, so pass -1 as pid of terminated
 	// ACTION's process.
 	kexec_continue_command_execution(exec, -1, 0);

+ 15 - 0
klish/ksession/kpath.c

@@ -116,3 +116,18 @@ klevel_t *kpath_eachr(kpath_levels_node_t **iterr)
 {
 	return (klevel_t *)faux_list_eachr((faux_list_node_t **)iterr);
 }
+
+
+kpath_levels_node_t *kpath_iter(const kpath_t *path)
+{
+	assert(path);
+	if (!path)
+		return NULL;
+	return (kpath_levels_node_t *)faux_list_head(path->levels);
+}
+
+
+klevel_t *kpath_each(kpath_levels_node_t **iter)
+{
+	return (klevel_t *)faux_list_each((faux_list_node_t **)iter);
+}

+ 1 - 1
klish/ksession/ksession_parse.c

@@ -295,7 +295,7 @@ kpargv_t *ksession_parse_line(ksession_t *session, const faux_argv_t *argv,
 	// iterator will be used.
 	path = ksession_path(session);
 	levels_iterr = kpath_iterr(path);
-	level_found = kpath_len(path);
+	level_found = kpath_len(path) - 1; // Levels begin with '0'
 	while ((level = kpath_eachr(&levels_iterr))) {
 		const kentry_t *current_entry = klevel_entry(level);
 		// Ignore entries with non-COMMON purpose. These entries are for

+ 19 - 0
plugins/klish/misc.c

@@ -12,6 +12,8 @@
 #include <faux/str.h>
 #include <faux/list.h>
 #include <klish/kcontext.h>
+#include <klish/ksession.h>
+#include <klish/kpath.h>
 
 
 int klish_nop(kcontext_t *context)
@@ -41,3 +43,20 @@ int klish_tsym(kcontext_t *context)
 
 	return 0;
 }
+
+// Symbol to show current path
+int klish_pwd(kcontext_t *context)
+{
+	kpath_t *path = NULL;
+	kpath_levels_node_t *iter = NULL;
+	klevel_t *level = NULL;
+
+	path = ksession_path(kcontext_session(context));
+	iter = kpath_iter(path);
+	while ((level = kpath_each(&iter))) {
+		printf("/%s", kentry_name(klevel_entry(level)));
+	}
+	printf("\n");
+
+	return 0;
+}

+ 2 - 0
plugins/klish/plugin_init.c

@@ -30,6 +30,8 @@ int kplugin_klish_init(kcontext_t *context)
 	kplugin_add_syms(plugin, ksym_new_ext("nop", klish_nop,
 		KSYM_USERDEFINED_PERMANENT, KSYM_SYNC));
 	kplugin_add_syms(plugin, ksym_new("tsym", klish_tsym));
+	kplugin_add_syms(plugin, ksym_new_ext("pwd", klish_pwd,
+		KSYM_PERMANENT, KSYM_SYNC));
 
 	// Navigation
 	// Navigation must be permanent (no dry-run) and sync. Because unsync

+ 1 - 0
plugins/klish/private.h

@@ -14,6 +14,7 @@ C_DECL_BEGIN
 // Misc
 int klish_nop(kcontext_t *context);
 int klish_tsym(kcontext_t *context);
+int klish_pwd(kcontext_t *context);
 
 // Navigation
 int klish_nav(kcontext_t *context);