#include "esh_main_loop.h" #include "esh_misc.h" void EShRunLoop() { struct termios orig_term_attr; struct termios new_term_attr; /* set the terminal to raw mode */ tcgetattr(fileno(stdin), &orig_term_attr); memcpy(&new_term_attr, &orig_term_attr, sizeof(struct termios)); new_term_attr.c_lflag &= ~(ECHO | ICANON | ISIG | IEXTEN); new_term_attr.c_cc[VTIME] = 0; new_term_attr.c_cc[VMIN] = 1; tcsetattr(fileno(stdin), TCSANOW, &new_term_attr); for (;;) { EShShowMsg(); char* command = malloc(esh_info_global->max_command_length); memset(command, 0, esh_info_global->max_command_length); int command_length = 0; int current_command_pos = 0; char input_char; while (input_char = fgetc(stdin)) { if (input_char == 10) { printf("\n"); break; // 'Enter' pressed; } if (input_char == EOF) { continue; } if (input_char == '\033') { // Arrow up/down/left/right sequence fgetc(stdin); switch(fgetc(stdin)) { case 'A': // Up break; case 'B': // Down break; case 'C': // Right if (current_command_pos < command_length) { printf("%c", command[current_command_pos]); ++current_command_pos; } break; case 'D': // Left if (current_command_pos > 0) { printf("\b"); --current_command_pos; } break; } continue; } if (input_char == 4) { // Ctrl + d printf("\n"); exit(0); } if (input_char == 127) { // Backspace if (current_command_pos > 0) { for (int i = current_command_pos - 1; i < command_length; ++i) { command[i] = command[i + 1]; } command[command_length - 1] = '\0'; printf("\b"); printf("%s", command + current_command_pos - 1); printf(" \b"); --current_command_pos; --command_length; for (int i = command_length - 1; i >= current_command_pos; --i) { printf("\b"); } } continue; } if (input_char == 3) { // Ctrl + c printf("\n"); exit(0); } if (EShIsShellLetter(input_char)) { for (int i = command_length; i >= current_command_pos; --i) { command[i + 1] = command[i]; } command[current_command_pos] = input_char; printf("%s", command + current_command_pos); ++current_command_pos; ++command_length; for (int i = command_length; i > current_command_pos; --i) { printf("\b"); } continue; } } if (command_length == 0) { printf("\n"); continue; } int pid = fork(); if (pid == 0) { execlp(command, command, NULL); printf("Esh: run command %s failed.\n", command); exit(1); // execlp failed } else { waitpid(pid, NULL, 0); printf("\n"); } } /* restore the original terminal attributes */ tcsetattr(fileno(stdin), TCSANOW, &orig_term_attr); } void EShShowMsg() { EShUpdateInviteMessage(); printf("%s", esh_info_global->invite_message); } void EShParseCommandIntoJobs(char* command) { } void EShExecuteJobs(int jobs_num, EShJob* jobs_list) { } void EShSetJobCommandType(EShJob* job) { } void EShRunJob(EShJob* job) { } int EmptyCommand(const char* command) { } int InnerCommand(const char* command) { } void EShProcessInnerJob(const char* command) { } void EShProcessExecJob(const char* command) { }