|
@@ -225,11 +225,15 @@ EShJob* EShParseCommandIntoJobs(char* command, int* jobs_num) {
|
|
|
}
|
|
|
|
|
|
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);
|
|
|
- }
|
|
|
+ int pipes[2];
|
|
|
+ if (pipe(pipes) != 0) {
|
|
|
+ printf(ANSI_COLOR_RED "\nESh error: cannot spawn pipe: %s\n" ANSI_COLOR_RESET, strerror(errno));
|
|
|
+ fflush(stdout);
|
|
|
+ }
|
|
|
|
|
|
- // TODO: delimiter == BIT_OR and BIT_AND
|
|
|
+ jobs[*jobs_num - 1].stdout_fd = pipes[1];
|
|
|
+ jobs[*jobs_num].stdin_fd = pipes[0];
|
|
|
+ }
|
|
|
|
|
|
++(*jobs_num);
|
|
|
current_job_cmd_length = 0;
|
|
@@ -281,8 +285,18 @@ void EShSplitJobCommand(EShJob* job, char delim) {
|
|
|
}
|
|
|
|
|
|
void EShExecuteJobs(int jobs_num, EShJob* jobs_list) {
|
|
|
+ int prev_job_exit_code = 0;
|
|
|
+
|
|
|
for (int i = 0; i < jobs_num; ++i) {
|
|
|
- EShRunJob(&jobs_list[i]);
|
|
|
+ if (strlen(jobs_list[i].command) == 0)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ if (jobs_list[i].job_start_condition == NO_CONDITION ||
|
|
|
+ (jobs_list[i].job_start_condition == PREVIOUS_EXIT_SUCCESS && prev_job_exit_code == 0) ||
|
|
|
+ (jobs_list[i].job_start_condition == PREVIOUS_EXIT_FAILED && prev_job_exit_code != 0))
|
|
|
+ {
|
|
|
+ EShRunJob(&jobs_list[i]);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -292,9 +306,9 @@ void EShSetJobCommandType(EShJob* job) {
|
|
|
|
|
|
int EShRunJob(EShJob* job) {
|
|
|
if (EShIsInnerJob(job)) {
|
|
|
- EShProcessInnerJob(job);
|
|
|
+ return EShProcessInnerJob(job);
|
|
|
} else {
|
|
|
- EShProcessExecJob(job);
|
|
|
+ return EShProcessExecJob(job);
|
|
|
}
|
|
|
// TODO: PIPES INIT & BG PROCESS SUPPORT
|
|
|
}
|
|
@@ -308,13 +322,12 @@ int EShIsInnerJob(EShJob* job) {
|
|
|
|
|
|
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);
|
|
|
+ if (chdir(job->command_tokens[1]) == -1) {
|
|
|
+ printf(ANSI_COLOR_RED "Esh: cannot change directory: %s\n" ANSI_COLOR_RESET, strerror(errno));
|
|
|
fflush(stdout);
|
|
|
+ return -1;
|
|
|
}
|
|
|
|
|
|
- chdir(job->command_tokens[1]);
|
|
|
getcwd(esh_info_global->current_working_dir, PATH_MAX);
|
|
|
EShOptimiseCurrentWorkingDirectory();
|
|
|
EShUpdateInviteMessage();
|
|
@@ -330,6 +343,24 @@ int EShProcessInnerJob(EShJob* job) {
|
|
|
int EShProcessExecJob(EShJob* job) {
|
|
|
int pid = fork();
|
|
|
if (pid == 0) {
|
|
|
+ if (job->stdin_fd != -1) {
|
|
|
+ dup2(job->stdin_fd, STDIN_FILENO);
|
|
|
+ close(job->stdin_fd);
|
|
|
+ job->stdin_fd = -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (job->stdout_fd != -1) {
|
|
|
+ dup2(job->stdout_fd, STDOUT_FILENO);
|
|
|
+ close(job->stdout_fd);
|
|
|
+ job->stdout_fd = -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (job->stderr_fd != -1) {
|
|
|
+ dup2(job->stderr_fd, STDERR_FILENO);
|
|
|
+ close(job->stderr_fd);
|
|
|
+ job->stderr_fd = -1;
|
|
|
+ }
|
|
|
+
|
|
|
for (int i = job->command_tokens_num; i < esh_info_global->max_command_tokens; ++i) {
|
|
|
free(job->command_tokens[i]);
|
|
|
job->command_tokens[i] = NULL;
|
|
@@ -340,27 +371,41 @@ int EShProcessExecJob(EShJob* job) {
|
|
|
fflush(stdout);
|
|
|
exit(1); // execlp failed
|
|
|
} else {
|
|
|
- waitpid(pid, NULL, 0);
|
|
|
- printf("\n");
|
|
|
+ if (job->stdin_fd != -1) {
|
|
|
+ close(job->stdin_fd);
|
|
|
+ job->stdin_fd = -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (job->stdout_fd != -1) {
|
|
|
+ close(job->stdout_fd);
|
|
|
+ job->stdout_fd = -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (job->stderr_fd != -1) {
|
|
|
+ close(job->stderr_fd);
|
|
|
+ job->stderr_fd = -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ job->job_pid = pid;
|
|
|
+ int status;
|
|
|
+ waitpid(pid, &status, 0);
|
|
|
+
|
|
|
+ if (WIFEXITED(status)) {
|
|
|
+ return WEXITSTATUS(status);
|
|
|
+ } else {
|
|
|
+ return -1; // No exit status received;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
void EShSubstituteShellValuesArgument(char** arg) {
|
|
|
- // Processing tilda
|
|
|
- // char* tilda_pos;
|
|
|
- // while ((tilda_pos = strchr(arg, '~')) != NULL) {
|
|
|
- // for (int i = strlen(arg); i > (tilda_pos - arg); --i) {
|
|
|
- // arg[i + strlen(esh_info_global->user_data->pw_dir)] = arg[i];
|
|
|
- // }
|
|
|
- // memcpy(tilda_pos, esh_info_global->user_data->pw_dir, strlen(esh_info_global->user_data->pw_dir));
|
|
|
- // }
|
|
|
-
|
|
|
char* new_str = *arg;
|
|
|
+
|
|
|
+ // Processing tilda
|
|
|
new_str = repl_str(new_str, "~", esh_info_global->user_data->pw_dir);
|
|
|
|
|
|
// Processing system variables
|
|
|
-
|
|
|
char* envvar_begin = new_str - 1;
|
|
|
while ((envvar_begin = strchr(envvar_begin + 1, '%')) != NULL) {
|
|
|
char* envvar_end = strchr(envvar_begin + 1, '%');
|