网站开发需要代码吗,商河县建设局网站,wordpress赞插件,个人网站怎么写目录 添加 read 系统调用#xff0c;获取键盘输入 :sys_read
putchar和clear
上班#xff1a;实现一个简单的shell
测试上电 我们下面来实现一个简单的shell
添加 read 系统调用#xff0c;获取键盘输入 :sys_read
/* Read count bytes from the file pointed to by fi…目录 添加 read 系统调用获取键盘输入 :sys_read
putchar和clear
上班实现一个简单的shell
测试上电 我们下面来实现一个简单的shell
添加 read 系统调用获取键盘输入 :sys_read
/* Read count bytes from the file pointed to by file descriptor fd into buf,* return the number of bytes read on success, return -1 if end of file is* reached*/
int32_t sys_read(int32_t fd, void *buf, uint32_t count)
{KERNEL_ASSERT(buf);int32_t ret -1;uint32_t global_fd 0;if (fd 0 || fd stdout_no || fd stderr_no){ccos_printk(sys_read: fd error\n);}else if (fd stdin_no){char *buffer buf;uint32_t bytes_read 0;while (bytes_read count){*buffer ioq_getchar(keyboard_ringbuffer);bytes_read;buffer;}ret (bytes_read 0 ? -1 : (int32_t)bytes_read);}else{global_fd fd_local2global(fd);ret file_read(file_table[global_fd], buf, count);}return ret;
}
我们终于跟老朋友见面了。我们修订一下:sys_read现在实现了读取文件的功能。它首先检查传入的 buf 指针是否有效。如果文件描述符 fd 无效例如小于0或者是标准输出、标准错误则会打印错误信息。如果文件描述符是标准输入stdin_no函数会从键盘输入的缓冲区 keyboard_ringbuffer 中读取字符将其存入 buf 中直到读取指定的字节数或达到文件末尾。函数会返回成功读取的字节数如果没有读取到任何数据返回 -1。如果文件描述符不是标准输入函数会根据 fd 获取对应的文件并调用 file_read 函数来执行实际的读取操作并返回成功读取的字节数。如果文件读取失败返回 -1。
int32_t read(int32_t fd, void *buf, uint32_t count)
{return _syscall3(SYS_READ, fd, buf, count);
}
putchar和clear
这个把我们之前做的工作编程系统调用即可
/* Outputs a character */
void putchar(char char_asci) {_syscall1(SYS_PUTCHAR, char_asci);
}
/* Clears the screen */
void clear(void) {_syscall0(SYS_CLEAR);
}
void sys_putchar(char char_asci)
{console__ccos_putchar(char_asci);
}
/* Initialize the system call table */
void syscall_init(void) {verbose_ccputs(syscall_init start\n); // Logging the start of syscall initialization/* Set the system call table entries for various system call numbers */syscall_table[SYS_GETPID] sys_getpid; // Get process IDsyscall_table[SYS_WRITE] sys_write; // Write to consolesyscall_table[SYS_MALLOC] sys_malloc; // Memory allocationsyscall_table[SYS_FREE] sys_free; // Free allocated memorysyscall_table[SYS_FORK] sys_fork; // Fork a new processsyscall_table[SYS_READ] sys_read;syscall_table[SYS_PUTCHAR] sys_putchar;syscall_table[SYS_CLEAR] clean_screen;verbose_ccputs(syscall_init done\n); // Logging the completion of syscall// initialization
}
上班实现一个简单的shell
#include include/user/ccshell/ccshell.h
#include include/defines.h
#include include/filesystem/file.h
#include include/library/string.h
#include include/library/types.h
#include include/syscall/syscall.h
#include include/user/stdio/stdio.h
#include include/filesystem/filesystem_settings.h
#include include/user/library/user_assertion.h
#define CMD_LEN MAX_PATH_LEN
#define MAX_ARG_NR (16)
/* Stores the input command */
static char cmd_line[CMD_LEN] {0};
/* Used to record the current directory; it is updated every time the cd command* is executed */
char cwd_cache[MAX_PATH_LEN] {0};
/* Outputs the shell prompt */
void print_prompt(void)
{printf([ HOST_NAME localhost %s]$ , cwd_cache);
}
/* Reads up to count bytes from the keyboard buffer into buf */
static void readline(char *buf, int32_t count)
{user_assert(buf count 0);char *pos buf;
while (read(stdin_no, pos, 1) ! -1 (pos - buf) count){ // Read until enter key is foundswitch (*pos){/* If enter or newline is found, treat it as the end of the command*/case \n:case \r:*pos 0; // Add null terminator to cmd_lineputchar(\n);return;
case \b:if (cmd_line[0] ! \b){ // Prevent deleting non-inputted data--pos; // Move back to the previous character in the bufferputchar(\b);}break;
/* For other characters, output normally */default:putchar(*pos);pos;}}printf(readline: cant find enter_key in the cmd_line, max num of char is 128\n);
}
先说说readline:这段代码实现了一个从键盘缓冲区读取用户输入的功能。函数readline的作用是从输入流中读取字符直到遇到回车键\n 或 \r为止或者读取达到指定的字节数限制。读取的内容会存储到buf中。具体步骤如下 函数首先检查传入的缓冲区指针buf是否有效并确认count大于0。 while循环会持续读取一个字符通过read(stdin_no, pos, 1)直到读取到回车键或达到指定的字符数量count。读取的字符会存储在buf中。 当遇到回车符\n 或 \r时表示用户输入完成此时将当前位置字符设置为\0并输出换行符表示命令输入结束。 如果遇到退格符\b程序会检查输入内容是否为空。如果不为空指针会退回一个字符删除命令行中的最后一个字符并输出退格符。此功能允许用户删除输入的字符。 其他字符直接输出并追加到pos指向的位置继续读取下一个字符。 如果没有在指定字符数内读取到回车键则会输出错误提示表明命令行输入超出了最大字符限制。
这个函数的设计使得用户可以在命令行中输入命令且支持基本的退格功能直到按下回车键为止。
ccshell是我们的核心
void ccshell(void)
{cwd_cache[0] /;while (1){print_prompt();k_memset(cmd_line, 0, CMD_LEN);readline(cmd_line, CMD_LEN);if (cmd_line[0] 0){continue;}}user_panic(Man!: you should not be here!!!);
}
这段代码实现了一个简单的命令行shell功能。函数ccshell定义了一个无限循环其中每次循环都会显示提示符等待用户输入命令。命令输入通过readline函数完成读取用户输入并存储到cmd_line中。每次读取命令之前cmd_line会被清空确保新命令不会受到旧命令的影响。如果用户没有输入命令程序会跳过本次循环。当用户输入命令时如果命令不为空程序会继续执行。虽然代码没有明确的退出机制但如果程序异常执行到user_panic(Man!: you should not be here!!!)说明发生了错误。
测试上电
#include include/device/console_tty.h
#include include/kernel/init.h
#include include/library/kernel_assert.h
#include include/thread/thread.h
#include include/user/stdio/stdio.h
#include include/memory/memory.h
#include include/library/ccos_print.h
#include include/filesystem/filesystem.h
#include include/library/string.h
#include include/filesystem/dir.h
#include include/syscall/syscall.h
#include include/user/ccshell/ccshell.h
void init(void);
int main(void)
{init_all();while(1);
}
// init process here
void init(void)
{uint32_t ret_pid fork();if (ret_pid){while(1);}else{ccshell();}while (1);
}
注意多敲几下键盘因为输出非常多。
下一篇
从0开始的操作系统手搓教程44——实现更好的shell-CSDN博客文章浏览阅读766次点赞14次收藏9次。在 Linux 系统中快捷键如“Ctrlu”和“Ctrll”是由操作系统提供的标准功能但它们的实现方式并不是直接由键盘驱动程序keyboard.c来处理的。如果在键盘驱动程序中加入过多的逻辑处理会导致系统的中断处理变得非常复杂效率降低进而影响整个系统的响应速度。的数据类型从16位改为32位因为一旦改动数据类型后续代码可能会受到影响造成所谓的“雪崩效应”即需要改动很多地方的代码和解释。时输入缓冲区中的字符会被清除屏幕会被清空然后打印命令提示符再显示用户已输入的命令。https://blog.csdn.net/charlie114514191/article/details/146144528