|
@@ -4,6 +4,8 @@
|
|
|
#include "esh_init.h"
|
|
|
#include "esh_deinit.h"
|
|
|
|
|
|
+#include "string_misc.h"
|
|
|
+
|
|
|
void EShRunLoop() {
|
|
|
struct termios orig_term_attr;
|
|
|
struct termios new_term_attr;
|
|
@@ -147,7 +149,6 @@ void EShRunLoop() {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
if (input_char == 3) {
|
|
|
|
|
|
printf("\n");
|
|
@@ -218,6 +219,16 @@ EShJob* EShParseCommandIntoJobs(char* command, int* jobs_num) {
|
|
|
jobs[*jobs_num].job_start_condition = PREVIOUS_EXIT_FAILED;
|
|
|
}
|
|
|
|
|
|
+ if (delimiter == BIT_AND) {
|
|
|
+ printf(ANSI_COLOR_RED "\nESh note: running processes in background is still not available, selected job will be running in foreground :(\n" ANSI_COLOR_RESET);
|
|
|
+ fflush(stdout);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (delimiter == BIT_OR) {
|
|
|
+ printf(ANSI_COLOR_RED "\nESh note: running processes through pipes is still not available, you will need to enter data manually :(\n" ANSI_COLOR_RESET);
|
|
|
+ fflush(stdout);
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
|
|
|
++(*jobs_num);
|
|
@@ -263,6 +274,10 @@ void EShSplitJobCommand(EShJob* job, char delim) {
|
|
|
job->command_tokens[job->command_tokens_num - 1][current_token_length] = job->command[i];
|
|
|
++current_token_length;
|
|
|
}
|
|
|
+
|
|
|
+ for (int i = 0; i < job->command_tokens_num; ++i) {
|
|
|
+ EShSubstituteShellValuesArgument(&job->command_tokens[i]);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void EShExecuteJobs(int jobs_num, EShJob* jobs_list) {
|
|
@@ -275,8 +290,44 @@ void EShSetJobCommandType(EShJob* job) {
|
|
|
|
|
|
}
|
|
|
|
|
|
-void EShRunJob(EShJob* job) {
|
|
|
+int EShRunJob(EShJob* job) {
|
|
|
+ if (EShIsInnerJob(job)) {
|
|
|
+ EShProcessInnerJob(job);
|
|
|
+ } else {
|
|
|
+ EShProcessExecJob(job);
|
|
|
+ }
|
|
|
|
|
|
+}
|
|
|
+
|
|
|
+int EShIsInnerJob(EShJob* job) {
|
|
|
+ return strcmp(job->command_tokens[0], "cd") == 0 ||
|
|
|
+ strcmp(job->command_tokens[0], "exit") == 0;
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+int EShProcessInnerJob(EShJob* job) {
|
|
|
+ if (strcmp(job->command_tokens[0], "cd") == 0) {
|
|
|
+
|
|
|
+ if (job->command_tokens_num < 2) {
|
|
|
+ printf(ANSI_COLOR_RED "Esh: cannot change directory, no directory specified.\n" ANSI_COLOR_RESET, job->command);
|
|
|
+ fflush(stdout);
|
|
|
+ }
|
|
|
+
|
|
|
+ chdir(job->command_tokens[1]);
|
|
|
+ getcwd(esh_info_global->current_working_dir, PATH_MAX);
|
|
|
+ EShOptimiseCurrentWorkingDirectory();
|
|
|
+ EShUpdateInviteMessage();
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (strcmp(job->command_tokens[0], "exit") == 0) {
|
|
|
+ EShExit(0);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+int EShProcessExecJob(EShJob* job) {
|
|
|
int pid = fork();
|
|
|
if (pid == 0) {
|
|
|
for (int i = job->command_tokens_num; i < esh_info_global->max_command_tokens; ++i) {
|
|
@@ -285,7 +336,8 @@ void EShRunJob(EShJob* job) {
|
|
|
}
|
|
|
|
|
|
execvp(job->command_tokens[0], job->command_tokens);
|
|
|
- printf("Esh: run command %s failed.\n", job->command);
|
|
|
+ printf(ANSI_COLOR_RED "Esh: run command %s failed.\n" ANSI_COLOR_RESET, job->command);
|
|
|
+ fflush(stdout);
|
|
|
exit(1);
|
|
|
} else {
|
|
|
waitpid(pid, NULL, 0);
|
|
@@ -293,20 +345,49 @@ void EShRunJob(EShJob* job) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-int EmptyCommand(const char* command) {
|
|
|
|
|
|
-}
|
|
|
+void EShSubstituteShellValuesArgument(char** arg) {
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
-int InnerCommand(const char* command) {
|
|
|
+ char* new_str = *arg;
|
|
|
+ new_str = repl_str(new_str, "~", esh_info_global->user_data->pw_dir);
|
|
|
|
|
|
-}
|
|
|
+
|
|
|
+
|
|
|
+ char* envvar_begin = new_str - 1;
|
|
|
+ while ((envvar_begin = strchr(envvar_begin + 1, '%')) != NULL) {
|
|
|
+ char* envvar_end = strchr(envvar_begin + 1, '%');
|
|
|
+ if (envvar_end == NULL)
|
|
|
+ break;
|
|
|
|
|
|
-void EShProcessInnerJob(const char* command) {
|
|
|
+ char envvar_name[1024 * 1024];
|
|
|
+ memset(envvar_name, 0, 1024 * 1024);
|
|
|
+ memcpy(envvar_name, envvar_begin + 1, (envvar_end - envvar_begin - 1));
|
|
|
|
|
|
-}
|
|
|
+ char* envvar_value = getenv(envvar_name);
|
|
|
|
|
|
-void EShProcessExecJob(const char* command) {
|
|
|
-
|
|
|
+ if (envvar_value == NULL) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ char envvar_name_overed[1024 * 1024];
|
|
|
+ memset(envvar_name_overed, 0, 1024 * 1024);
|
|
|
+ strcat(envvar_name_overed, "%");
|
|
|
+ strcat(envvar_name_overed, envvar_name);
|
|
|
+ strcat(envvar_name_overed, "%");
|
|
|
+
|
|
|
+ new_str = repl_str(new_str, envvar_name_overed, envvar_value);
|
|
|
+ }
|
|
|
+
|
|
|
+ free(*arg);
|
|
|
+ *arg = new_str;
|
|
|
}
|
|
|
|
|
|
void EShPrintJobsDebugInfo(const char* command, EShJob* jobs, int jobs_num) {
|