From 41990c570f70c6d438a07ae30b5e33686a440837 Mon Sep 17 00:00:00 2001 From: "Enrico Fraccaroli (Galfurian)" Date: Tue, 25 Jan 2022 15:01:53 -0500 Subject: [PATCH] Improve ctrl+ management. --- libc/inc/bits/termios-struct.h | 4 +- mentos/inc/system/syscall.h | 14 ++++--- mentos/src/kernel.c | 12 ++++-- mentos/src/process/process.c | 69 ++++++++++++++++++---------------- programs/shell.c | 53 ++++++++++++++------------ 5 files changed, 86 insertions(+), 66 deletions(-) diff --git a/libc/inc/bits/termios-struct.h b/libc/inc/bits/termios-struct.h index 134550a..f28a33e 100644 --- a/libc/inc/bits/termios-struct.h +++ b/libc/inc/bits/termios-struct.h @@ -40,4 +40,6 @@ typedef struct termios { #define TOSTOP 0x00400000 ///< Allows SIGTTOU signals generated by background processes. #define ECHOCTL 0x00000040 ///< If this and ECHO are set, control characters with ‘^’ are echoed. #define ECHOKE 0x00000001 ///< If ICANON is set, KILL is echoed by erasing each character on the line. -#define IEXTEN 0x00000400 ///< Enables implementation-defined input processing. \ No newline at end of file +#define IEXTEN 0x00000400 ///< Enables implementation-defined input processing. + +#define CTRL(x) (x & 037) \ No newline at end of file diff --git a/mentos/inc/system/syscall.h b/mentos/inc/system/syscall.h index be2a6c9..4f9efbb 100644 --- a/mentos/inc/system/syscall.h +++ b/mentos/inc/system/syscall.h @@ -20,7 +20,7 @@ void syscall_handler(pt_regs *f); /// @brief Returns the current interrupt stack frame. /// @return Pointer to the stack frame. -pt_regs* get_current_interrupt_stack_frame(); +pt_regs *get_current_interrupt_stack_frame(); /// The exit() function causes normal process termination. /// @param exit_code The exit code. @@ -88,11 +88,13 @@ int sys_execve(pt_regs *f); /// @brief Changes the working directory. /// @param path The new working directory. -void sys_chdir(char const *path); +/// @return On success 0. On error -1, and errno indicates the error. +int sys_chdir(char const *path); /// @brief Changes the working directory. /// @param fd File descriptor of the new working directory. -void sys_fchdir(int fd); +/// @return On success 0. On error -1, and errno indicates the error. +int sys_fchdir(int fd); /// @brief Returns the process ID (PID) of the calling process. /// @return The process ID. @@ -103,7 +105,7 @@ pid_t sys_getpid(); /// If pid != 0 return the SID corresponding to the process having identifier == pid ///@param pid process identifier from wich we want the SID ///@return On success return SID of the session -/// Otherwise return -1 with errno set on: EPERM or ESRCH +/// Otherwise return -1 with errno set on: EPERM or ESRCH pid_t sys_getsid(pid_t pid); ///@brief creates a new session if the calling process is not a @@ -113,7 +115,7 @@ pid_t sys_getsid(pid_t pid); /// of a new process group in the session (i.e., its process group ID /// is made the same as its process ID). ///@return On success return SID of the session just created -/// Otherwise return -1 with errno : EPERM +/// Otherwise return -1 with errno : EPERM pid_t sys_setsid(); ///@brief returns the Process Group ID (PGID) of the process specified by pid. @@ -134,7 +136,7 @@ int sys_setpgid(pid_t pid, pid_t pgid); pid_t sys_getgid(); ///@brief sets the effective group ID of the calling process. -///@param pid process identifier to +///@param pid process identifier to ///@return On success, zero is returned. /// Otherwise returns -1 with errno set to :EINVAL or EPERM. int sys_setgid(pid_t pid); diff --git a/mentos/src/kernel.c b/mentos/src/kernel.c index bf87513..f04eeb3 100644 --- a/mentos/src/kernel.c +++ b/mentos/src/kernel.c @@ -113,6 +113,12 @@ int kmain(boot_info_t *boot_informations) initial_esp = boot_info.stack_base; // Dump the multiboot structure. dump_multiboot(boot_info.multiboot_header); + + //========================================================================== + // First, disable the keyboard, otherwise the PS/2 initialization does not + // work properly. + keyboard_disable(); + //========================================================================== pr_notice("Initialize the video...\n"); vga_initialize(); @@ -298,9 +304,8 @@ int kmain(boot_info_t *boot_informations) return 1; } print_ok(); - + //========================================================================== -#if 1 pr_notice("Setting up PS/2 driver...\n"); printf("Setting up PS/2 driver..."); if (ps2_initialize()) { @@ -309,8 +314,7 @@ int kmain(boot_info_t *boot_informations) return 1; } print_ok(); -#endif - + //========================================================================== pr_notice("Setting up keyboard driver...\n"); printf("Setting up keyboard driver..."); diff --git a/mentos/src/process/process.c b/mentos/src/process/process.c index 874b478..a7284d4 100644 --- a/mentos/src/process/process.c +++ b/mentos/src/process/process.c @@ -228,7 +228,7 @@ static inline task_struct *__alloc_task(task_struct *source, task_struct *parent // Initalize real_timer for intervals proc->real_timer = NULL; - + // Set the default terminal options. proc->termios = (termios_t){ .c_cflag = 0, @@ -338,47 +338,52 @@ task_struct *process_create_init(const char *path) char *sys_getcwd(char *buf, size_t size) { - task_struct *current_process = scheduler_get_current_process(); - if ((current_process != NULL) && (buf != NULL)) { - strncpy(buf, current_process->cwd, size); + task_struct *current = scheduler_get_current_process(); + if ((current != NULL) && (buf != NULL)) { + strncpy(buf, current->cwd, size); return buf; } return (char *)-EACCES; } -void sys_chdir(char const *path) +int sys_chdir(char const *path) { - task_struct *current_process = scheduler_get_current_process(); - if ((current_process != NULL) && (path != NULL)) { - char absolute_path[PATH_MAX]; - realpath(path, absolute_path); - // Check that the directory exists. - vfs_file_t *dir = vfs_open(absolute_path, O_RDONLY | O_DIRECTORY, S_IXUSR); - if (dir != NULL) { - pr_debug("Success `%s` -> `%s` -> `%s`\n", path, absolute_path, dir->name); - strcpy(current_process->cwd, absolute_path); - vfs_close(dir); - } else { - pr_debug("Failed `%s` -> `%s` -> `NULL`\n", path, absolute_path); - } + task_struct *current = scheduler_get_current_process(); + assert(current && "There is no running process."); + if (!path) + return -EFAULT; + char absolute_path[PATH_MAX]; + realpath(path, absolute_path); + // Check that the directory exists. + vfs_file_t *dir = vfs_open(absolute_path, O_RDONLY | O_DIRECTORY, S_IXUSR); + if (dir) { + strcpy(current->cwd, absolute_path); + vfs_close(dir); + return 0; } + // Return the errno value set by either VFS or the filesystem underneath. + return -errno; } -void sys_fchdir(int fd) +int sys_fchdir(int fd) { - // Get the current task. - task_struct *task = scheduler_get_current_process(); - // Check the current FD. - if (fd >= 0 && fd < task->max_fd) { - // Get the file descriptor. - vfs_file_descriptor_t *vfd = &task->fd_list[fd]; - // Check the file. - if (vfd->file_struct != NULL) { - char absolute_path[PATH_MAX]; - realpath(vfd->file_struct->name, absolute_path); - strcpy(task->cwd, absolute_path); - } - } + task_struct *current = scheduler_get_current_process(); + assert(current && "There is no running process."); + // Check if it is a valid file descriptor. + if ((fd < 0) || (fd >= current->max_fd)) + return -EBADF; + // Get the file descriptor. + vfs_file_descriptor_t *vfd = ¤t->fd_list[fd]; + // Check if the file descriptor file is set. + if (vfd->file_struct == NULL) + return -ENOENT; + // Check that the path points to a directory. + if (!bitmask_check(vfd->file_struct->flags, DT_DIR)) + return -ENOTDIR; + char absolute_path[PATH_MAX]; + realpath(vfd->file_struct->name, absolute_path); + strcpy(current->cwd, absolute_path); + return 0; } pid_t sys_fork(pt_regs *f) diff --git a/programs/shell.c b/programs/shell.c index 487faf4..1157e4f 100644 --- a/programs/shell.c +++ b/programs/shell.c @@ -20,6 +20,7 @@ #include "termios.h" #include "limits.h" #include "sys/utsname.h" +#include "ctype.h" /// Maximum length of commands. #define CMD_LEN 32 @@ -535,29 +536,6 @@ static void __cmd_get() __cmd_ers(0x7F); } } - } else if (c == '^') { - c = getchar(); // Get the char. - if (c == 'C') { - // Re-set the index to the beginning. - cmd_cursor_index = 0; - // Go to the new line. - printf("\n\n"); - // Sets the command. - __cmd_set("\0"); - // Break the while loop. - break; - } else if (c == 'U') { - // Clear the current command. - __cmd_clr(); - // Re-set the index to the beginning. - cmd_cursor_index = 0; - // Sets the command. - __cmd_set("\0"); - } else if (c == 'D') { - // Go to the new line. - printf("\n"); - exit(0); - } } } else if (c == '\b') { __cmd_ers('\b'); @@ -626,10 +604,34 @@ static void __cmd_get() strcpy(cmd + cmd_cursor_index, cmd + cmd_cursor_index + 1); putchar(127); } + } else if (iscntrl(c)) { + if (c == CTRL('C')) { + // Re-set the index to the beginning. + cmd_cursor_index = 0; + // Go to the new line. + printf("\n\n"); + // Sets the command. + __cmd_set("\0"); + // Break the while loop. + break; + } else if (c == CTRL('U')) { + // Clear the current command. + __cmd_clr(); + // Re-set the index to the beginning. + cmd_cursor_index = 0; + // Sets the command. + __cmd_set("\0"); + } else if (c == CTRL('D')) { + // Go to the new line. + printf("\n"); + exit(0); + } } else if ((c > 0) && (c != '\n')) { if (__cmd_app(c)) { putchar(c); } + } else { + pr_debug("Unrecognized character %02x (%c)\n", c, c); } } while (cmd_cursor_index < CMD_LEN); @@ -678,6 +680,11 @@ int main(int argc, char *argv[]) { setsid(); + struct termios _termios; + tcgetattr(STDIN_FILENO, &_termios); + _termios.c_lflag &= ~ISIG; + tcsetattr(STDIN_FILENO, 0, &_termios); + char *USER = getenv("USER"); if (USER == NULL) { printf("shell: There is no user set.\n");