diff --git a/lab5/user/lab5/apps/init.c b/lab5/user/lab5/apps/init.c index 46fdec0..01a75c5 100644 --- a/lab5/user/lab5/apps/init.c +++ b/lab5/user/lab5/apps/init.c @@ -29,7 +29,8 @@ int fs_server_cap; #define FTYPE_FILE 0b01 #define FTYPE_DIR 0b10 -static char *builtin_complement_word[] = {"cd", "ls", "ll", "cat", "echo", "clear"}; +static char *builtin_complement_word[] = {"cd", "ls", "ll", "cat", "echo", "clear", "pwd", + "exit", "quit"}; static int n_builtin_complement_word = sizeof(builtin_complement_word) / sizeof(char *); static char file_complement_buf[MAX_FILE_COMPLEMENT_WORD * (MAX_FILENAME_LEN + 1)]; @@ -38,6 +39,9 @@ void path_to_absolute(char *path); void path_append(char *path, char *sub); int fs_scan(char *path); +// 当前目录 +char working_directory[BUFLEN] = {'/'}; + /** * 生成文件补全词列表 * @param ret_words 返回列表 @@ -131,8 +135,10 @@ static char *match_builtin_command_param(char *complement, int complement_time, while (complement[start_pos] == ' ') start_pos++; // 匹配子目录文件 - n_words = make_file_complement_word(&words, complement + start_pos, type_mask); - matched = match_complement_words(words, n_words, complement + start_pos, complement_time, match_count); + if (*(complement + start_pos) != '\0') { + n_words = make_file_complement_word(&words, complement + start_pos, type_mask); + matched = match_complement_words(words, n_words, complement + start_pos, complement_time, match_count); + } // 匹配当前目录文件 if (!matched) { n_words = make_file_complement_word(&words, NULL, type_mask); @@ -157,8 +163,10 @@ static int do_complement(char *buf, char *complement, int complement_time) int n_words; // 匹配子目录内文件,如 tar 匹配 tar/file1 - n_words = make_file_complement_word(&words, complement, FTYPE_FILE); - matched = match_complement_words(words, n_words, complement, complement_time, &match_count); + if (*complement != '\0') { + n_words = make_file_complement_word(&words, complement, FTYPE_FILE); + matched = match_complement_words(words, n_words, complement, complement_time, &match_count); + } // 匹配当前目录文件,如 f 匹配 file1 if (!matched) { @@ -260,15 +268,30 @@ char *readline(const char *prompt) int do_cd(char *cmdline) { + char pathbuf[BUFLEN]; cmdline += 2; while (*cmdline == ' ') cmdline++; if (*cmdline == '\0') return 0; + // 解析路径 if (*cmdline != '/') { - } - printf("Build-in command cd %s: Not implemented!\n", cmdline); - return 0; + // 相对路径 + strcpy(pathbuf, working_directory); + path_append(pathbuf, cmdline); + } else { + // 绝对路径 + strcpy(pathbuf, cmdline); + } + // 检查路径是否存在 + int ret = fs_scan(pathbuf); + if (ret < 0) { + printf("'%s' is not a dir!\n", cmdline); + return -1; + } + // 切换 + strcpy(working_directory, pathbuf); + return 0; } int do_top() @@ -277,18 +300,24 @@ int do_top() return 0; } +int do_pwd() +{ + printf("%s\n", working_directory); + return 0; +} + /** * 转为绝对路径 */ void path_to_absolute(char *path) { char pathbuf[BUFLEN]; - strcpy(pathbuf + 1, path); - pathbuf[0] = '/'; + strcpy(pathbuf, working_directory); + path_append(pathbuf, path); strcpy(path, pathbuf); } /** - * 路径连接 + * 路径连接,sub 必须为相对路径且不支持 .. */ void path_append(char *path, char *sub) { size_t path_len = strlen(path); @@ -298,13 +327,19 @@ void path_append(char *path, char *sub) { path += path_len; } else { path[path_len] = '/'; - path += path_len + 1; + path += ++path_len; } } // sub 之前没有 '/' while (*sub == '/') sub++; // 连接路径 strcpy(path, sub); + path += strlen(sub); + path_len += strlen(sub); + // 路径末尾不能出现 '/',个人感觉不是很合理,但是 tfs_open_path 行为如此 + while (*--path == '/' && --path_len > 0) { + *path = '\0'; + } } /** @@ -551,6 +586,10 @@ int builtin_cmd(char *cmdline) ret = do_top(); return !ret ? 1 : -1; } + if (!strcmp(cmd, "pwd")) { + ret = do_pwd(); + return !ret ? 1 : -1; + } return 0; }