|
@@ -2,27 +2,131 @@
|
|
|
#include "esh_misc.h"
|
|
|
|
|
|
void EShRunLoop() {
|
|
|
+ struct termios orig_term_attr;
|
|
|
+ struct termios new_term_attr;
|
|
|
+
|
|
|
+
|
|
|
+ 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 = NULL;
|
|
|
+ char* command = malloc(esh_info_global->max_command_length);
|
|
|
+ memset(command, 0, esh_info_global->max_command_length);
|
|
|
int command_length = 0;
|
|
|
- ssize_t buf_size = 0;
|
|
|
-
|
|
|
- while ((command_length = getline(&command, &buf_size, stdin)) == 0) {
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if (command_length == -1)
|
|
|
- break;
|
|
|
+ int current_command_pos = 0;
|
|
|
+
|
|
|
+ char input_char;
|
|
|
+
|
|
|
+ while (input_char = fgetc(stdin)) {
|
|
|
+ if (input_char == 10) {
|
|
|
+ printf("\n");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (input_char == EOF) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (input_char == '\033') {
|
|
|
+ fgetc(stdin);
|
|
|
+ switch(fgetc(stdin)) {
|
|
|
+ case 'A':
|
|
|
+ break;
|
|
|
+ case 'B':
|
|
|
+ break;
|
|
|
+ case 'C':
|
|
|
+ if (current_command_pos < command_length) {
|
|
|
+ printf("%c", command[current_command_pos]);
|
|
|
+ ++current_command_pos;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 'D':
|
|
|
+ if (current_command_pos > 0) {
|
|
|
+ printf("\b");
|
|
|
+ --current_command_pos;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (input_char == 4) {
|
|
|
+
|
|
|
+ printf("\n");
|
|
|
+ exit(0);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (input_char == 127) {
|
|
|
+
|
|
|
+ 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) {
|
|
|
+
|
|
|
+ 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);
|
|
|
+ } else {
|
|
|
+ waitpid(pid, NULL, 0);
|
|
|
+ printf("\n");
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+ tcsetattr(fileno(stdin), TCSANOW, &orig_term_attr);
|
|
|
}
|
|
|
|
|
|
void EShShowMsg() {
|
|
|
EShUpdateInviteMessage();
|
|
|
- EShUpdateInviteMessage();
|
|
|
- EShUpdateInviteMessage();
|
|
|
- EShUpdateInviteMessage();
|
|
|
-
|
|
|
printf("%s", esh_info_global->invite_message);
|
|
|
}
|
|
|
|