Browse Source

Fix memory leaks

Serj Kalichev 2 years ago
parent
commit
ea7770be82
4 changed files with 35 additions and 19 deletions
  1. 2 0
      klish/ksession/kcontext.c
  2. 4 0
      klish/ksession/kexec.c
  3. 28 19
      klish/ksession/ksession.c
  4. 1 0
      klish/ktp/ktpd_session.c

+ 2 - 0
klish/ksession/kcontext.c

@@ -107,5 +107,7 @@ void kcontext_free(kcontext_t *context)
 	if (!context)
 		return;
 
+	kpargv_free(context->pargv);
+
 	faux_free(context);
 }

+ 4 - 0
klish/ksession/kexec.c

@@ -274,6 +274,7 @@ static bool_t exec_action_sync(kcontext_t *context, const kaction_t *action,
 
 	fn = ksym_function(kaction_sym(action));
 
+	// Prepare streams before fork
 	fflush(stdout);
 	fflush(stderr);
 
@@ -293,15 +294,18 @@ static bool_t exec_action_sync(kcontext_t *context, const kaction_t *action,
 		if (pid)
 			*pid = child_pid;
 
+		// Temporarily replace orig output stream by pipe
 		saved_stdout = dup(STDOUT_FILENO);
 		dup2(pipefd[1], STDOUT_FILENO);
 		close(pipefd[0]);
 		close(pipefd[1]);
 
+		// Execute sym function right here
 		exitcode = fn(context);
 		if (retcode)
 			*retcode = exitcode;
 
+		// Restore orig output stream
 		fflush(stdout);
 		fflush(stderr);
 		dup2(saved_stdout, STDOUT_FILENO);

+ 28 - 19
klish/ksession/ksession.c

@@ -180,7 +180,6 @@ bool_t ksession_exec_locally(ksession_t *session, const char *line,
 {
 	kexec_t *exec = NULL;
 	faux_eloop_t *eloop = NULL;
-	faux_buf_t *buf = NULL;
 
 	assert(session);
 	if (!session)
@@ -194,16 +193,22 @@ bool_t ksession_exec_locally(ksession_t *session, const char *line,
 	// Session status can be changed while parsing because it can execute
 	// nested ksession_exec_locally() to check for PTYPEs, CONDitions etc.
 	// So check for 'done' flag to propagate it.
-	if (ksession_done(session))
+	if (ksession_done(session)) {
+		kexec_free(exec);
 		return BOOL_FALSE; // Because action is not completed
+	}
 
 	// Execute kexec and then wait for completion using local Eloop
-	if (!kexec_exec(exec))
+	if (!kexec_exec(exec)) {
+		kexec_free(exec);
 		return BOOL_FALSE; // Something went wrong
-	// If kexec contains only sync ACTIONs then we don't need event loop
-	// and can return here.
-	if (kexec_retcode(exec, retcode))
+	}
+	// If kexec contains only non-exec (for example dry-run) ACTIONs then
+	// we don't need event loop and can return here.
+	if (kexec_retcode(exec, retcode)) {
+		kexec_free(exec);
 		return BOOL_TRUE;
+	}
 
 	// Local service loop
 	eloop = faux_eloop_new(NULL);
@@ -218,21 +223,25 @@ bool_t ksession_exec_locally(ksession_t *session, const char *line,
 
 	kexec_retcode(exec, retcode);
 
+	// Debug only
 	{
-	printf("STDOUT:\n");
-	fflush(stdout);
-	ssize_t r = 0;
-	buf = kexec_bufout(exec);
-	do {
-		void *d = NULL;
-		ssize_t really_readed = 0;
-		r = faux_buf_dread_lock_easy(buf, &d);
-		if (r > 0) {
-			really_readed = write(STDOUT_FILENO, d, r);
-		}
-		faux_buf_dread_unlock_easy(buf, really_readed);
-	} while (r > 0);
+		faux_buf_t *buf = NULL;
+		printf("STDOUT:\n");
+		fflush(stdout);
+		ssize_t r = 0;
+		buf = kexec_bufout(exec);
+		do {
+			void *d = NULL;
+			ssize_t really_readed = 0;
+			r = faux_buf_dread_lock_easy(buf, &d);
+			if (r > 0) {
+				really_readed = write(STDOUT_FILENO, d, r);
+			}
+			faux_buf_dread_unlock_easy(buf, really_readed);
+		} while (r > 0);
 	}
 
+	kexec_free(exec);
+
 	return BOOL_TRUE;
 }

+ 1 - 0
klish/ktp/ktpd_session.c

@@ -184,6 +184,7 @@ static bool_t ktpd_session_process_cmd(ktpd_session_t *session, faux_msg_t *msg)
 	int retcode = 0;
 	bool_t r = BOOL_FALSE;
 	r = ksession_exec_locally(session->ksession, line, &retcode, error);
+	faux_str_free(line);
 	if (!r)
 		printf("ksession_exec_locally() return value is false\n");
 	printf("kexec retcode is %d\n", retcode);